My site is pretty small, so I don’t really need search functionality, but the Netlify Algolia plugin looked easy enough to use and a bit of fun.
Diving into the docs, I got a bit overwhelmed. Algolia’s breadth of capabilities is huge. They definitely seem like the go-to for fully customisable search on a Jamstack site. But all I wanted was a quick half an hour set up. I started reading a few articles and eventually figured out that Algolia offers two main products, instantsearch and autocomplete. Instantsearch is wildly extensible and has an array of UI components to create full search experiences. Autocomplete, on the other hand, adds a little search box like I’ve seen on so many sites.
I installed the Netlify plugin and kicked off a new build to get the crawler running automatically which indexed the content on my site. As I’m using Nuxt, all of the pages are pre-rendered so the crawler can parse the content. If you have an SPA, you’ll need to tweak a config setting in your netlify.toml
file to get the crawler to render the Javascript on the page.
1[[plugins]]2package = "@algolia/netlify-plugin-crawler"3 [plugins.inputs]4 branches = ['main', 'develop', 'feat/add-algolia']5 disabled = true6 pathPrefix = "/blog"7 customDomain = "example.com"8 renderJavaScript = true
I then tried to install the @algolia/algoliasearch-netlify-frontend
plugin, but the install is broken on Windows because they’re using a UNIX specific command in their postinstall script. I started off by including it from JSDelivr instead as per their docs, but ran into some issues with not being able to use the head property on the Nuxt error layout.
I wrote a little load script wrapper in the mounted hook, but this felt a little slow, having to load resources from a 3rd party, all the extra DNS overhead that that brings, and what if jsDelivr went down (unlikely).
1mounted () { 2 this.loadScript('https://cdn.jsdelivr.net/npm/@algolia/algoliasearch-netlify-frontend@1/dist/algoliasearchNetlify.js', () => { 3 algoliasearchNetlify({ 4 // Options 5 }) 6 }) 7 }, 8 methods: { 9 loadScript (url, callback) {10 const script = document.createElement('script')11 script.src = url12 script.onload = callback13 document.head.appendChild(script)14 }15 }
What I really wanted was to be able to import an es module and bundle it with my code, like a normal Javascript package. I ended up enabling Typescript in my project, my first foray, copying Algolia’s source files, and importing like so (much simpler).
1import algoliasearchNetlify from './AlgoliasearchNetlify'
You can view the commit that adds the @algolia/algoliasearch-netlify-frontend
package to my project. There’s a bit of technical debt here in that I manually need to update files if Algolia update their package, but it also means I can customise it no-end if need be. I also now control the requirements of Algolias core packages like @algolia/autocomplete-js
and @algolia/client-search
, so can keep things more up-to-date. I feel like it’s a good compromise.
The Netlify walkthrough gives you the following code snippet, but I found it really difficult to work out what all the env variables were and which page in the Algolia dashboard to go to to get the right variable. I worked out that the dashboard shows you different API keys depending on which application you had last visited. How I longed for Stripe’s docs here which automatically fill in the code samples with your keys.
1algoliasearchNetlify({2 appId: '<YOUR_ALGOLIA_APP_ID>',3 apiKey: '<YOUR_ALGOLIA_API_KEY>',4 siteId: '<YOUR_NETLIFY_SITE_ID>',5 branch: '<YOUR_TARGET_GIT_BRANCH>',6 selector: 'div#search',7})
Now I had a working search! I wanted to style it a little though, which Algolia let you do through their config options. Just place this code in the algoliasearchNetlify
config options.
1theme: {2 mark: '#fff', // Color of the matching content3 background: '#23263b', // Background Color of the input and the panel4 selected: '#111432', // Background Color of the selected item5 text: '#d6d6e7', // Color of the title of the items6 colorSourceIcon: '#d6d6e7' // Color of the icon on the left of results7}
After plugging the values in, I realised I’d need to dynamically update them due to the dark theme toggle on my site. I experimented a little with watching a darktheme
prop and trying to destroy and recreate the search container, but eventually dove into their source code and picked out the bits of CSS I needed to change. Here’s a snippet of what I added:
1#search .aa-Autocomplete, .aa-Panel, .aa-DetachedContainer { 2 --height: 3rem; 3 --height-icon: 1.5rem; 4 --color-input-icon: var(--grey); 5 --color-mark: var(--green); 6 --color-background: white; 7 --color-selected: #ECECEC; 8 --color-text: var(--grey); 9 --color-source-icon: var(--grey)10}
The way the autocomplete works is that when you start typing, a popup displays with the top results. You can configure how many to show, but I left it at the default which is 5. Annoyingly, whenever you click off the window, the popup disappears, so you can’t inspect it with dev tools. I did some Googling and found that you could pass a debug option to algoliasearchNetlify
which keeps the popup open. That let me make the final styling touches I needed.
1algoliasearchNetlify({2 appId: '<YOUR_ALGOLIA_APP_ID>',3 apiKey: '<YOUR_ALGOLIA_API_KEY>',4 siteId: '<YOUR_NETLIFY_SITE_ID>',5 branch: '<YOUR_TARGET_GIT_BRANCH>',6 selector: 'div#search',7 debug: true 8})
Overall, it was a bit of a pain to add Algolia with the Netlify plugin, the whole integration feels rushed on their part. It’s not quite plug and play for an SPA or SSG. I can imagine it works well if you just have HTML files though and don’t mind a few extra 3rd party resources. If I were to need a comprehensive search functionality in the future, I’d definitely go with Algolia, but for smaller projects, I’ll be looking for something less complex. Take a look at the new search feature.