The other day, I was casually browsing the web and stumbled upon the need for an API for my new little project. Instead of starting from scratch, I thought it would be great if I could find an existing API to build upon. That's when I came across this repository consisting of public APIs.
As I was browsing through the list of public APIs, I couldn't help but think how cool it would be to create a tiny website using some of these APIs. It just seemed like such a fun project that could be quickly put together and shown to others.
Well, hype aside, I find this exciting because of the challenge it presents. It’s no secret that HTMX can work with both hypermedia and JSON responses. Although, HTMX is primarily designed for hypermedia. However, I want to prove that it's completely possible (and not even that difficult) to use HTMX with JSON API as well.
JSON is the most popular data format for APIs
Also, this seems to be a common real-life scenario that many encounter.
Just imagine someone saying, "Hey, I want to migrate to HTMX but I already have a bunch of JSON APIs. Do I have to change my entire server-side implementation? What a bummer!".
So, today, I’m going to write about how I came to create a very simple website powered by HTMX, Nunjucks, and Spaceflight News API (SNAPI). But really you can replicate this with any JSON API of your choice.
I love static websites. They are fast, cheap, and super easy to host. The best part? They hardly require any maintenance!
- A code editor with a live server for testing (e.g., Visual Studio Code with the Live Server extension) or any code playground like JSFiddle
By the end of this, you will have built a Spaceflight News blog page using HTMX with the following features:
- Displaying blog posts with titles, authors, publication dates, and summaries
- Pagination with a "Load More" button
- Search functionality
Step 1: Basic HTML Structure
Let's get started with building our web page. The first step is to set up the basic HTML structure. It's super easy!
Just copy the provided HTML code into a new HTML file. You can name it something like
index.html. Oh, and don't forget to include the necessary script in the
Now, before we move on, I want to share some libraries that we'll be using:
- HTMX for AJAX interactions
- Nunjucks for client-side templates
- Optional: water.css classless CSS for basic styling
Here, we’ll be using the
/v4/blogs endpoint. According to the SNAPI docs, we've got an example response that we can work with:
If we take a look at the JSON response, it looks like we can make good use of the
published_at fields to create our blog page.
The first 10 characters of an ISO 8601 date string format are in the format YYYY-MM-DD. So we’ll use the first 10 characters of
published_at as our published date later.
previous keys will come in handy for pagination.
Step 2: Client Side Templates
Next, we'll delve into actually calling the API and displaying the available blog posts on SNAPI.
Now, let me break it down a bit:
- We use the
hx-ext="client-side-templates"attribute to activate the client-side templates extension for HTMX. This little beauty allows us to employ a templating engine (e.g. Nunjucks) to transform the JSON response from the API into HTML before it shows up on the page.
nunjucks-templateattribute specifies the name of the Nunjucks template (
blogs-template) we'll be using to convert the JSON response from the API into HTML. This template comprises the following elements:
- A count of the total number of results
- A list of the results, each featuring a title, news site, published date, and summary
- When the
hx-getevent is triggered on
https://api.spaceflightnewsapi.net/v4/blogs/endpoint is called and the response is parsed as JSON. The Nunjucks template is then used to render the JSON response into HTML. The rendered HTML is then swapped into the DOM, replacing the
divelement with the ID
Now, let's take a peek at all this in action on our browser... Huh, it should have worked smoothly, right? Why is the blog section of our page completely blank?! Where are the blog posts?!?!
Debugging: CORS Workaround
Let’s check this out with some good old browser inspection. Checking out the Console tab, we see an error message stating:
We need to work around this issue because the Spaceflight News API doesn't allow cross-origin requests by default.
Here's the script to add to the
<head> section to implement the CORS workaround when making requests to external APIs with HTMX. It essentially just removes any custom headers:
We can now see a list of blog posts being rendered on our HTML page! Yay!
However, we are only seeing the results from the first page. Our next step is to work on the pagination part: add a "Load More" button at the bottom of the page.
Step 3: Pagination
The "Load More" button is implemented as a
When the “Load More” button is clicked, here’s what happens:
hx-getevent is triggered. The
nextvariable is used to specify the URL of the next page of blogs. The HTML that gets swapped into the DOM is the same as the one for the
blogs-templateelement but with some fancy new blogs added to the end.
hx-swapattribute basically tells us how we should swap the new HTML into the DOM. In our case, we’re using the
outerHTMLswap mode. This means that the new HTML will replace the entire existing HTML for the
- Lastly, the
hx-triggerattribute tells us which event will trigger the
hx-getevent. Here, we're using the good ol'
clickevent. So, whenever you click on that "Load More" button,
hx-getevent gets triggered and our pagination game begins!
That’s it! We’ve now got a “Load More” pagination implemented for our blog.
We're not done yet! We need to find the blog post about the Chandrayaan-3 lunar exploration mission. So, let's keep clicking that "Load More" button...and more...and more...
Step 4: Search Input
Just kidding! Who would want to keep clicking more to look for specific stuff? Thankfully, the
/v4/blog of SNAPI supports search queries out of the box. So, we can easily search for the article about the Chandrayaan-3 lunar exploration mission.
Let's work on modifying the original
div to a search
input. So, you can easily type in your search keywords and find the articles you're interested in:
<input> element acts as a search bar that uses the
hx-get event to load a list of blogs from the API when you type in a search query.
hx-get event is triggered by the
search events (reference). The search results are then rendered in the
#result element using the
blogs-template Nunjucks template.
Finally, I can search for “Chandrayaan” related blog posts. No more endless clicking ‘Load More’!
We have successfully created a Spaceflight News blog page with live search functionality, dynamic content loading, and client-side templates using HTMX and JSON API.
For a better search experience, you could try to update the search input to sync with the search query of the URL so that you can do something like this.
Thanks for reading!
Making this wouldn’t be possible without these awesome resources: