About this website

This web site is static, i.e. pages and their contents coming from the same domain are sent as is by the server, without any on-the-fly creation[1].

If you're not interested in the technique, you can also learn more about Nicolas Hoizey.

The whole site is generated by Eleventy from documents written in Markdown syntax. It was last generated on 25 September 2023 with Eleventy v2.0.1.

The site was previously generated by Jekyll, another famous Static Site Generator, but its development staled, and after multiple years I still wasn't confortable with Ruby development, so I moved to something easier (for me), yet at least as powerful.

Even before, I was using SPIP[2] which has its own specific syntax (not so different from Markdown), so in order to migrate the hundreds of contents written since 2001, I developed a SPIP → Markdown plugin which transforms as much as possible this specific syntax into Markdown syntax, including the YAML Front Matter.

An increasing number of plugins exist in the Eleventy ecosystem to enrich the base solution.

The images benefit from my eleventy-plugin-images-responsiver plugin to use the SaaS Cloudinary service in order to generate the different versions necessary for Responsive Web Design, while optimizing performance.

Web site performance has been one of my hobbies for many years, being above all frustrated as a simple visitor by sites that are slower and heavier than the others.

Producing a static website helps to optimize this performance, as generating pages on the fly is no longer necessary. But I have focused on providing a very pleasant experience for visitors, with a high-performance site.

For this purpose, several recipes have been combined:

The external resources, potential sources of trouble, are mainly :

  • the video players, including Youtube, Vimeo or Dailymotion
  • the widgets of certain services, including Ulule, Speakerdeck or Slideshare

Switching to static made me lose the comments I had natively in SPIP, so I decided a little later to switch to Disqus so as not to lose the contribution of the discussions, although I don't really like the comments to be hosted elsewhere.

I had also started to implement Webmention fairly quickly to explore a new standard inter-blog dialog technique.

I ended up abandoning Disqus in favor of Webmention, thanks to the great Bridgy and webmention.io services.

Setting up an internal search engine on a static site is no simpler than for comments. It is necessary to make dynamics, find elements meeting the search criteria and list them.

With a dynamic site, it is possible to index directly the contents present in the content repository, usually a database. Some CMS even directly integrate this functionality, more or less turnkey.

Algolia is a search engine in SaaS mode, fully controlled by an extremely rich REST API. It is the choice I made back in 2015 to have a search engine on this site, and I later moved from a classic search to integrate Algolia InstantSearch seamlessly as a progressive enhancement of my static archives pages.

It's a progressive enhancement because:

  • all content is already available in the static HTML provided by the server, and this static version already contains "filters" for content type and year/month of publication (it takes most of my build time… 😅)
  • Algolia InstantSearch is then loaded as an module, so only recent browsers can load it and the code can use ES6. Old browsers will not get it, but they are often on devices with lower capacities, so browsing the static version is enough, as for people with JS disabled (or unavailable) for any reason.

I tried to make the switch as seamless as possible for the user, with a stable page layout to prevent Cumulative Layout Shift.

Also, I manage the URL dynamically (thanks Algolia for the API) to map static navigation to the content type and/or year/month facets (and optimize for SEO):

  • for example: here are the notes from November 2020: https://nicolas-hoizey.com/notes/2020/11/. This page exists on the server, and it is enhanced as a search to allow for free text search and other facets (tags, language).
  • another example: if you go to the full archives page, selecting one (only one) of the content type facets will update both the URL and the selected item in the main navigation.

All of this was not so easy, but with great documentation, threads in the Algolia community forums and issues on GitHub, I managed to do it, and I'm really happy with the result.

There are still some things I would like to improve, so any advice is welcome:

  • Algolia's first results list before the user type any keyword is exactly the same as the static page (if the URL contains only a content type and/or a year/month), so I would like to NOT run the search on first hit. I know it is however necessary to get the facets values and numbers, so I would at least not replace the results list, and I didn't find a way yet.
  • When I'm on any InstantSearch page and I click an item in the navigation corresponding to one of the content types, I would like to select the related facet and deselect any other previously selected, instead of reloading the full page HTML and re-initialize InstantSearch, but I didn't find yet how to do it.

I hope it will inspire other people to provide a great UX for navigating archives on content sites!

Publishing new content has become more complicated, since you have to produce the Markdown and possible illustrations, then launch the compilation by Eleventy, before deploying.

All this could be made easier with Netlify, but I didn't move this site there yet.

But having a clean content source, in a more standard format, and versioned in GitHub, is a considerable gain.

  1. So it's hard to blame any server application for being slow… ↩︎

  2. SPIP is an excellent free and open source French CMS, particularly relevant for editorial content, running with PHP and a database. ↩︎