DEV Community

Cover image for Adding lazy loading of items using htmx
Cristian Molina
Cristian Molina

Posted on

Adding lazy loading of items using htmx

This is a continuation of some testing of these front-end libraries.
I used the lazy load example here to add lazy loading of the articles on this index page.

This is how it looks like:

a spinning animation before showing articles

Previous to this change, I created an Articles Active Record model, ran migrations, and changed the insert action to create new records.

I added a GET htmx definition in the index view code to fetch the items' partial and added a route and a controller action for this new response.

You can see that there is an extra logic in the Articles::IndexView to discern between displaying the lazy load code or the fragment with the list of articles. This is based on an initialization parameter. I'd probably refactor this later, maybe extracting the list block into a new component.

Here is the important code changes:

Route definition

  resources :articles do
    get "items", on: :collection
Enter fullscreen mode Exit fullscreen mode

Controller changes

  def index

  def items
    articles = Article.all.order(id: :desc)
    sleep 1 # this is to simulate a slow response and should be removed in a real scenario
    render, layout: false
Enter fullscreen mode Exit fullscreen mode

Changes in the index view class

class Articles::IndexView < ApplicationView
  def template
    if @articles.nil?

  def load_indicator_placeholder
    div("hx-get": items_articles_path, "hx-trigger": "load", class: "flex justify-center") {
      img(alt: "Loading items...",
        class: "htmx-indicator", width: "150", src: "/bars.svg")

  def load_articles_section
    section(id: "article-list", class: "grid md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4") {
      articles.each { |el| render el }
Enter fullscreen mode Exit fullscreen mode

Also available in the GitHub repo

Happy hacking!

Top comments (0)