My experiment with HTMX and Astro

petrtcoi

Petr Tcoi

Posted on June 20, 2024

My experiment with HTMX and Astro

I share my first experience with the htmx library. I created a simple site (https://tubog-showcase.ru) consisting of a home page with an initial set of apartment cards and 5 buttons that display apartments filtered by number of rooms.

Stack: Astro + HTMX + Tailwind

Implementation is very simple:

// src/pages/index.astro

<form
  id='filter-form'
  hx-trigger='change'
  hx-post='/api/cases'
  hx-target='#serch-results'
  hx-swap='innerHTML'
  hx-indicator='#loading'
>
    ...
    <label>
      <input
    type='radio'
    name='rooms'
    value='1'
        class='hidden peer'
      />
      <div class='hover:border-slate-500 peer-checked:opacity-100 peer-checked:shadow-xl peer-checked:border-slate-400'>
    1 комната
      </div>
   </label>

    ...
</form>

<div id='loading'>
  Loading...
</div>

<div id='serch-results'></div>
Enter fullscreen mode Exit fullscreen mode

Соответственно, при выборе нового варианта фильтра, по адресу /api/cases выполняется POST-запрос с данными о выбранном варианте.

Индикатором рабты запроса является <div id='loading'>. Результат (готовый HTML) выводится внутри <div id='serch-results'></div>.
На стороне api код выглядит примерно так:

// src/pages/api/cases.ts

export const POST: APIRoute = async ({ request }) => {

   const formData = await request.formData()
   const rooms = formData.get('rooms')

   // Получаем список комнат на основе rooms

   return new Response(
     `
      <div>
         ${filteredFlats.map(flat => ` {some flat html here} `)}
      </div> 
     `,
     {
        status: 200,
    headers: {
       'Content-Type': 'text/html+htmx',
    },
      }
   )
Enter fullscreen mode Exit fullscreen mode

And that's it.

First Impressions

This approach to create web applications is rather not for me. Implementing with the same React seems simpler and with more potential for improvement. What I didn't like:

  • The blurring of application logic. The backend doesn't just return data, but also deals with frontend tasks;
  • The need to harmonize the layout on the client side and the server side (in our case it's the default display of maps and search results output).

Yes, I made it a bit more difficult for myself by not using page partials, but their use within the same Astro in conjunction with HTMX seemed a bit too far-fetched to me.

Still, I have a number of tasks where HTMX is a perfect fit: I have several old static sites and sites implemented on CMS like WordPress. For these, the will to add interactivity (especially using page partials) is a great prospect. For sites written in Next or Astro, I haven't seen a use for it yet.

P.S. An unexpected problem

In this project I've connected View Transitions and it seems to break the HTMX library. As soon as you make a transition between pages, the site ends up static. Fortunately, I came across this article which describes the solution: you need to add the following script to the page with HTXM code.

// src/pages/index.astro

<script>
  document.addEventListener('astro:page-load', () => {
    const contentElement = document.getElementById('filter-form')
    if (contentElement) { 
      htmx.process(document.body)
    }
  })
</script>
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
petrtcoi
Petr Tcoi

Posted on June 20, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related