Juha-Matti Santala
Community Builder. Dreamer. Adventurer.

Search, Webmentions and microformats

I have recently been updating this website with new features! Let’s talk about them.

Search

Inspired by a Youtube video by Coding in Public, I decided to add a search function to my site. It’s actually something I’ve wanted to have for a long time but given this is a purely static, generated site, I hadn’t found a good option. I didn’t want to build something that would rely on 3rd party APIs or anything like that because I want to keep my dependencies as small as possible.

From that video however, I learned about a tool called Pagefind that makes it possible to generate the search after the build and then made available in the website.

There are essentially two steps:

First, you need to generate your search “database”. To do that, after building the site with Eleventy, run npx pagefind --site=_site (replacing _site with wherever your site gets built to).

Second, you need to add their script to the website itself. I made a new file search.njk and added:

<link href="/pagefind/pagefind-ui.css" rel="stylesheet">
<script src="/pagefind/pagefind-ui.js"></script>
<div id="search"></div>
<script>
    window.addEventListener('DOMContentLoaded', (event) => {
        new PagefindUI({ element: "#search", showSubResults: true });
    });
</script>

The contents of /pagefind gets populated automatically by the script in the first step. When the page is loaded, it will create the search UI and populate the results.

The third, optional step, that I took, was to exclude some pages and elements from the search. For example, I removed the blog listing page, the sidebar on my blog that shows most recent and so on because those are items that the search will find anyway through the main blog post or the blog roll page. To do that, I added a data-pagefind-ignore attribute to the elements I wanted to ignore.

Finally, as a fourth optional step, I defined the provided CSS variables so that they respect my light/dark mode styling:

--pagefind-ui-primary: var(--color-text-primary);
--pagefind-ui-text: var(--color-text-primary);
--pagefind-ui-background: var(--color-background-primary);
--pagefind-ui-border: var(--brand);
--pagefind-ui-tag: var(--color-text-primary);

I really like how the search turned out. Integrating Pagefind was really easy and their documentation is very nice. I often struggle to integrate tools into my projects so I was so happy when things just worked out of the box with a single command and I was able to fine-tune the end result with custom CSS and excluding elements from the search.

Webmentions

I finally integrated Webmentions to the site, at least partially. Using a third-party service Webmention.io, I’m able to receive Webmentions sent by other people and other services. To broadcast this for tools, I added a

<link
  rel="webmention"
  href="https://webmention.io/hamatti.org/webmention"
/>

into the <head> of my site. When someone sends a mention to that endpoint, I can see it from my Webmention.io dashboard and feel the dopamine hit.

Related to this, I also added Remy’s great webmentions CLI tool to my workflow. I didn’t automate it (at least yet) but once I merge in my new blog post, I have two npm scripts I can run to let others know through their webmention setup that I’ve mentioned them.

"webmentions:debug": "npx @remy/webmention https://hamatti.org/feed/feed.xml --limit 1 --debug",
"webmentions:send": "npx @remy/webmention https://hamatti.org/feed/feed.xml --limit 1 --send",

The first one, webmentions:debug checks my RSS feed’s latest post, looks through all the links to see if they support receiving webmentions and does a dry run, letting me know what it found. The second, webmentions:send runs the same but actually sends the webmentions.

Currently I’m doing this manually and have the debug script there so I can keep a bit of an eye on it to make sure it works (and to learn how it works). Probably eventually I’ll add it to my post-build process. Big thanks to Sophie at localghost for teaching me how!

I’m already seeing the webmentions flow in and it makes me very happy. Not only to see other people share my content but also to be part of this cool web crowd.

So far, I haven’t set up any automation to show these webmentions on my site but I’m working on it. I just first need to get a bunch of them so I can learn a bit more how they work and what kind of data I have to play with before I decide how I integrate them.

Microformats

Slightly related to the webmention stuff, I also started adding microformats stuff to my website, starting with my blog posts. Microformats are a way to annotate websites and content pieces in a standardized way.

For example, if someone parses the microformatted information from my earlier blog post on Debugging Python, they would see (among other data):

{
	"type": [
	    "h-entry"
	],
	"properties": {
	    "name": [
	        "Debugging Python"
	    ],
	    "author": [
	        "Juha-Matti Santala"
	    ],
	    "published": [
	        "Jan 13th, 2024"
	    ],
	    "content": [
	        {
	            "html": " -- omitted -- "
				  }
      ],
		  ... (other data omitted)
  }
}

I’m still very new to microformats and their usage but to my understanding, when I now send a webmention from one of my blog posts to someone else’s blog, they’ll get this extra metadata alongside the mention. I think that’s pretty fun.

I’m only just beginning to explore the microformats but at least now I have a starting point deployed and can start making incremental improvements as I learn more.

Oh, I also added blog stats!

Another thing that I added that I talked about in Mastodon but haven’t mentioned on the blog yet: blog stats. Inspired by the Robb Knight’s stats page, Cory Dransfeldt’s stats page and using Robb’s Eleventy Post Graph plugin, I now have a /blog/stats page that keeps track of my most popular blog posts for the month as well as annual data on how many blog posts I’ve published and on which days, similar to the contribution graph in GitHub.

If you take a look, you’ll discover that I’m very much a Wednesday blogger. I try to maintain a steady pace of publishing every Wednesday. This year with extra time and creative energy on my hands, I’ve added regular Saturday posts and occasional Monday posts to the mix as well.