Gatsby How to setup search on Gatsby

written in JavaScript

We're going to add search to an example Gatsby application.

  1. Create a new Gatsby application.
  2. Copy the theme files that we need to override.
  3. Create a search page.
  4. Implement CloudSh for searching.

View the Example Gatsby App on GitHub.

Really this should be built as a plugin, but I don't know Gatsby well enough to do that just yet!

Create the app

Run the Gatsby generator to create a new application.

npx gatsby new gatsby-example
cd gatsby-example

Next we need to copy the default html.js file to add the search script.

In another shell, run npm run develop to create the .cache directory to copy the file from.

cp .cache/default-html.js src/html.js

Add the CloudSh search.js script

Here we add the script to the html.js just before the closing </body> tag. This allows the script to be available when we need it on our search page.

  // src/html.js
...
<script src="https://app.cloudsh.com/js/search.js" />
</body>
...

Create the search page

You'll need a CloudSh JWT token, you can create a free account and setup an index for your site. After you create a token for your index replace CLOUDSH_TOKEN with that value.

Token Show

Next create a search.js in src/pages/ with something like the following code.

// src/pages/search.js

import React from "react";
import { Link } from "gatsby";

import Layout from "../components/layout";
import SEO from "../components/seo";

export default class Searchpage extends React.Component {
componentDidMount() {
const conf = {
token: "CLOUDSH_TOKEN",
formId: "#cloudsh",
resultsId: "#results"
};

const load_cloudsh = () => {
window.cloudsh.inject(conf.formId, conf);
};

if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => load_cloudsh());
} else {
load_cloudsh();
}
}

render() {
return (
<Layout>
<SEO title="Search" />
<h1>Search</h1>
<Link to="/">Go back to the homepage</Link>

<div>
<form id="cloudsh" className="search form-inline">
<div className="form-group">
<input
className="form-control"
id="q"
placeholder="search"
type="text"
/>

<button className="btn btn-primary">Search</button>{" "}
</div>
</form>
</div>

<div id="results" />
</Layout>
);
}
}

In the componentDidMount function, we check if the document is ready, and when it is we call the window.cloudsh.inject function. That function needs the Id of the form element and the configuration options for search.

In the render function, we need a form w/ the input and a place for the results to go. Make sure the ids used here match the config in componentDidMount.

Lastly, add a link to the search page from the index.js file.

// src/pages/index.js
...

const IndexPage = () => (
<Layout>
...
<Link to="/search/">Search</Link>
</Layout>
);

Try it out!

Gatsby Screenshot

You can run npm run develop and test out your search.

Read more about the options for customization in the docs.