How to use the Gatsby elasticlunr plugin with MDX

I'm The Flying Dev - flight attendant and self-taught developer. The founder and host of the Landing in Tech podcast.
Search for a command to run...

I'm The Flying Dev - flight attendant and self-taught developer. The founder and host of the Landing in Tech podcast.
No comments yet. Be the first to comment.
If you use an email long enough, you know how much spam that email will get - some even pass through the filter and reach your inbox. When this happens, you can do three things: Add filtering to delete emails from a specific domain/email address aut...

Actions I've taken to improve security and accounts hardening

When I built the website for Landing in Tech I wanted to have a bar on top of the page with the latest episode. The idea was to allow users to listen to the episode while browsing the page. I added the iframe on my layout.js file and expected it to ...

Version control systems are tools to keep track of changes to source code or other collections of files and folders. They help to track the changes of documents, they make it easy collaborating with someone else. Version Control track changes in a se...

As developers, we use the terminal all the time, it makes sense to learn some shortcuts that can help you do things in the command line. Learning these will also help you boost your productivity because you don't have to retype your commands again j...

Since I've recently moved from using markdownRemark to MDX on all my Gatsby Sites, the instructions to some plugins might not be that straightforward to follow. Recently, I've created a Digital Garden and wanted to add a search bar to it.
On one of my first Gatsby projects, I had used the Elasticlurn Plugin for Gatsby to add a search bar to a website. I decided to try and use this plugin since I don't have to use an external service like Algolia.
Installing the plugin is pretty straightforward. You need to run the command:
npm install @gatsby-contrib/gatsby-plugin-elasticlunr-search
Then on your gatsby-config.js file, you can add the configuration for the plugin. If you read the README.md, you can see that one of the configuration options is the resolvers, here you need to replace MarkdownRemark for Mdx.
{
resolve: `@gatsby-contrib/gatsby-plugin-elasticlunr-search`,
options: {
fields: [`title`, `category`, `tags`, `excerpt` ],
resolvers: {
Mdx: {
title: node => node.frontmatter.title,
category: node => node.frontmatter.category,
tags: node => node.frontmatter.tags,
excerpt: node => node.frontmatter.excerpt,
slug: node => node.fields.slug
}
},
filter: (node, getNode) => node.frontmatter.category
}
}
My frontmatter contains all those fields (but the slug). These are the fields that I want users to be able to search. You can choose as many or as little as you want.
With the plugin installed and configured, we have to create the search bar component. I re-used the component that I had created on the other project.
Note: This component needs refactoring. Most of this code was taken from the plugin instructions.
import React, { Component } from "react"
import { Index } from "elasticlunr"
import { Link } from "gatsby"
export default class Search extends Component {
constructor(props) {
super(props)
this.state = {
query: ``,
results: []
}
}
render() {
return (
<div className="my-5 relative">
<div className="flex justify-center items-center">
<i className="gg-search mr-2" />
<input type="text" value={this.state.query} onChange={this.search} placeholder="Search..." />
</div>
{this.state.results.length !== 0 ?
<div className="mt-2 flex flex-col absolute z-10 search-results">
{this.state.results.map(page => (
<Link className="link m-1" to={`${page.slug}`} key={page.title}>
<span className="underline">{page.title}</span> : <span className="green">{page.tags.join(', ')}</span>
</Link>
))}
</div>
: ''}
</div>
)
}
getOrCreateIndex = () =>
this.index ? this.index : Index.load(this.props.searchIndex)
search = evt => {
const query = evt.target.value
this.index = this.getOrCreateIndex()
this.setState({
query,
results: this.index
.search(query, { expand: true})
.map(({ ref }) => this.index.documentStore.getDoc(ref))
})
}
}
I want users to get partial matches straight away. So when you type something, you will get all matches first. Then the query will return fewer results. If you don't want this to happen and return the search results instead, you can remove the { expand: true } parameter from the search method.
You can probably see that on this site I am using TailwindCss. The only bit of CSS that I added outside Tailwind was the search-results which adds some styling(colour, spacing) to that div. The reason why I decided to use an absolute position, is because I want the search results to drop down and stay above the content.
Now that the search bar component is completed, you can use it anywhere on your site by importing it. But you also need to provide a searchIndex to the component. Luckily, the plugin adds a query for you to use.
query {
siteSearchIndex {
index
}
}
Then you can import the search bar component and use it like this:
<SearchBar searchIndex={props.data.siteSearchIndex.index} />
That's all there is to add a search bar with elasticlunr plugin and MDX. If you have any issues feel free to reach me on Twitter @FabioRosado, I will be happy to give you a hand!