Search by Algolia
What is online retail merchandising? An introduction
e-commerce

What is online retail merchandising? An introduction

Done any shopping on an ecommerce website lately? If so, you know a smooth online shopper experience is not optional ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

5 considerations for Black Friday 2023 readiness
e-commerce

5 considerations for Black Friday 2023 readiness

It’s hard to imagine having to think about Black Friday less than 4 months out from the previous one ...

Piyush Patel

Chief Strategic Business Development Officer

How to increase your sales and ROI with optimized ecommerce merchandising
e-commerce

How to increase your sales and ROI with optimized ecommerce merchandising

What happens if an online shopper arrives on your ecommerce site and: Your navigation provides no obvious or helpful direction ...

Catherine Dee

Search and Discovery writer

Mobile search UX best practices, part 3: Optimizing display of search results
ux

Mobile search UX best practices, part 3: Optimizing display of search results

In part 1 of this blog-post series, we looked at app interface design obstacles in the mobile search experience ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Mobile search UX best practices, part 2: Streamlining search functionality
ux

Mobile search UX best practices, part 2: Streamlining search functionality

In part 1 of this series on mobile UX design, we talked about how designing a successful search user experience ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Mobile search UX best practices, part 1: Understanding the challenges
ux

Mobile search UX best practices, part 1: Understanding the challenges

Welcome to our three-part series on creating winning search UX design for your mobile app! This post identifies developer ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Teaching English with Zapier and Algolia
engineering

Teaching English with Zapier and Algolia

National No Code Day falls on March 11th in the United States to encourage more people to build things online ...

Alita Leite da Silva

How AI search enables ecommerce companies to boost revenue and cut costs
ai

How AI search enables ecommerce companies to boost revenue and cut costs

Consulting powerhouse McKinsey is bullish on AI. Their forecasting estimates that AI could add around 16 percent to global GDP ...

Michelle Adams

Chief Revenue Officer at Algolia

What is digital product merchandising?
e-commerce

What is digital product merchandising?

How do you sell a product when your customers can’t assess it in person: pick it up, feel what ...

Catherine Dee

Search and Discovery writer

Scaling marketplace search with AI
ai

Scaling marketplace search with AI

It is clear that for online businesses and especially for Marketplaces, content discovery can be especially challenging due to the ...

Bharat Guruprakash

Chief Product Officer

The changing face of digital merchandising
e-commerce

The changing face of digital merchandising

This 2-part feature dives into the transformational journey made by digital merchandising to drive positive ecommerce experiences. Part 1 ...

Reshma Iyer

Director of Product Marketing, Ecommerce

What’s a convolutional neural network and how is it used for image recognition in search?
ai

What’s a convolutional neural network and how is it used for image recognition in search?

A social media user is shown snapshots of people he may know based on face-recognition technology and asked if ...

Catherine Dee

Search and Discovery writer

What’s organizational knowledge and how can you make it accessible to the right people?
product

What’s organizational knowledge and how can you make it accessible to the right people?

How’s your company’s organizational knowledge holding up? In other words, if an employee were to leave, would they ...

Catherine Dee

Search and Discovery writer

Adding trending recommendations to your existing e-commerce store
engineering

Adding trending recommendations to your existing e-commerce store

Recommendations can make or break an online shopping experience. In a world full of endless choices and infinite scrolling, recommendations ...

Ashley Huynh

Ecommerce trends for 2023: Personalization
e-commerce

Ecommerce trends for 2023: Personalization

Algolia sponsored the 2023 Ecommerce Site Search Trends report which was produced and written by Coleman Parkes Research. The report ...

Piyush Patel

Chief Strategic Business Development Officer

10 ways to know it’s fake AI search
ai

10 ways to know it’s fake AI search

You think your search engine really is powered by AI? Well maybe it is… or maybe not.  Here’s a ...

Michelle Adams

Chief Revenue Officer at Algolia

Cosine similarity: what is it and how does it enable effective (and profitable) recommendations?
ai

Cosine similarity: what is it and how does it enable effective (and profitable) recommendations?

You looked at this scarf twice; need matching mittens? How about an expensive down vest? You watched this goofy flick ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

What is cognitive search, and what could it mean for your business?
ai

What is cognitive search, and what could it mean for your business?

“I can’t find it.”  Sadly, this conclusion is often still part of the modern enterprise search experience. But ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Looking for something?

Add Autocomplete search to your Strapi CMS
facebookfacebooklinkedinlinkedintwittertwittermailmail

Strapi is an open-source, headless CMS that builds API abstractions to retrieve your content regardless of where it’s stored. It’s a great tool for building content-driven applications like blogs and other media sites.

In this post, you’re going to add interactive search to a Strapi blog with a Next.js front end using Algolia’s Autocomplete.js library and the community-built Search plugin for Strapi.

Prerequisites

Strapi and Algolia Autcomplete.js are both build using Javascript, so you’ll want node v.12 installed.
.
You’ll build on the basic blog application from this guide using Strapi and Next.js. You should familiarize yourself with the steps in that post before building your search experience on top of it.

You’ll also need an Algolia account for search. You can use your existing Algolia account or sign up for a free account.

Building the back end

Start by creating a directory to hold your project’s front and back ends:

mkdir blog-strapi-algolia && cd blog-strapi-algolia

Strapi has a set of pre-baked templates you can use to get a CMS up and running quickly. These all include Strapi itself with pre-defined content types and sample data. If you don’t have a Strapi blog already, you can use the blog template to quickly set one up.

npx create-strapi-app backend  --quickstart --template @strapi/template-blog@1.0.0 blog

After the script finishes installing, add an admin user at https://localhost:1337 so you can log in to the Strapi dashboard. This script sets up most of back end for us, including a few demo blog posts. You can read more about everything that was setup in the quick start.

Next you need to index your demo content. Fortunately, the Strapi community has you covered with a Search plugin and Algolia indexing provider built by community member Mattias van den Belt. You can read more about Mattie’s plugin in the documentation, but getting up and running only requires a couple of pieces of configuration.

Go ahead and stop your Strapi server so you can install the plugin using npm (or yarn).

cd backend && npm install @mattie-bundle/strapi-plugin-search @mattie-bundle/strapi-provider-search-algolia --save

You’ll need to add an Algolia API key and App ID to your Strapi environment. You can manage your keys by navigating the Algolia Dashboard under Settings > Team and Access > API Keys, or go directly to https://algolia.com/account/api-keys. Since Strapi is modifying your Algolia index, you’ll need to provide either the admin API key (for demos) or create a key with appropriate access for your production project.

# .env
// ...
ALGOLIA_PROVIDER_APPLICATION_ID=XXXXXXXXXX
ALGOLIA_PROVIDER_ADMIN_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

With your credentials in place, the last step is to configure the plugin. Create or modify the ./config/plugins.js file in your backend directory. You want to tell the plugin to index the article and category content types for your blog.

'use strict';

module.exports = ({ env }) => ({
  // ...
  search: {
    enabled: true,
    config: {
      provider: 'algolia',
      providerOptions: {
        apiKey: env('ALGOLIA_PROVIDER_ADMIN_API_KEY'),
        applicationId: env('ALGOLIA_PROVIDER_APPLICATION_ID'),
      },
      contentTypes: [
        { name: 'api::article.article' },
        { name: 'api::category.category' },
      ],
    },
  },
});

Restart your Strapi server to pick up these environment variables and the new plugin (npm run develop). The Search plugin triggers when new content is Published, so you’ll need to either Unpublish and Publish the demo articles, or create a new one. Load the Strapi admin panel (https://localhost:1337/admin) and navigate to Content Manager > COLLECTION TYPES > Article and either click on an existing article and Unpublish it, or click on Create new Entry. Click Publish on your article to index this entry into your Algolia application. You can do the same for the category content type if you’d like to index those as well.

Building the front end

Now that you’ve built your back end and populated your index, it’s time to build the front end for you users.

Strapi has a great blog post walking you through building a Next.js powered front end. You’ll build on top of those steps here. You can either walk through their quick start yourself, or you can just clone this repo if you want to jump directly to adding search.

git clone --single-branch --branch no-search-version git@github.com:chuckmeyer/blog-strapi-frontend.git frontend

Don’t forget to run

cd frontend && npm install

if you cloned the front end from the repo.

This is enough to get the basic blog site up and running. You can test it out by starting up the server in the frontend directory.

npm run dev

The only thing missing is search. You’ll be using the Algolia Autocomplete.js library to add an autocomplete search experience to your blog’s navigation bar. When a user types into the field, the autocomplete “completes” their thought by providing full terms or results. The Autocomplete library is source agnostic, so you’ll also need the Algolia InstantSearch library to connect to your index on the back end.

npm install @algolia/autocomplete-js algoliasearch @algolia/autocomplete-theme-classic --save

To use the autocomplete library in a React project, you first need to create an Autocomplete component to wrap the library. You can find the boilerplate for this in the autocomplete documentation.

./frontend/components/autocomplete.js

import { autocomplete } from '@algolia/autocomplete-js';
import React, { createElement, Fragment, useEffect, useRef } from 'react';
import { render } from 'react-dom';

export function Autocomplete(props) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current) {
      return undefined;
    }

    const search = autocomplete({
      container: containerRef.current,
      renderer: { createElement, Fragment },
      render({ children }, root) {
        render(children, root);
      },
      ...props,
    });

    return () => {
      search.destroy();
    };    
  }, [props]);

  return <div ref={containerRef} />;
}

Just like in the back end, you’ll need your Algolia credentials to connect to the API. Since the front end only needs to read from the index, you can use your search key for the application. Create a ./frontend/.env.local file to store your credentials.

NEXT_PUBLIC_ALGOLIA_APP_ID=XXXXXXXXXX
NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Now you can initialize your connection to Algolia and add your new Autocomplete component by updating the code in ./frontend/components/nav.js.

import React from "react";
import Link from "next/link";

import { getAlgoliaResults } from '@algolia/autocomplete-js';
import algoliasearch from 'algoliasearch';
import { Autocomplete } from './autocomplete';
import SearchItem from './searchItem';
import "@algolia/autocomplete-theme-classic";

const searchClient = algoliasearch(
  process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
  process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY,
);

const Nav = ({ categories }) => {
  return (
    <div>
      <nav className="uk-navbar-container" data-uk-navbar>
        <div className="uk-navbar-left">
          <ul className="uk-navbar-nav">
            <li>
              <Link href="/">
                <a>Strapi Blog</a>
              </Link>
            </li>
          </ul>
        </div>
        <div className="uk-navbar-center">
          <Autocomplete
            openOnFocus={false}
            detachedMediaQuery=''
            placeholder="Search for articles"
            getSources={({ query }) => [
              {
                sourceId: "articles",
                getItemUrl( {item} ) { return `/article/${item.slug}`},
                getItems() {
                  return getAlgoliaResults({
                    searchClient,
                    queries: [
                      {
                        indexName: "development_api::article.article",
                        query,
                      }
                    ]
                  })
                },
                templates: {
                  item({ item, components}) {
                    return <SearchItem hit={item} components={components} />;
                  }
                }
              },
            ]}
          />
        </div>
        <div className="uk-navbar-right">
          <ul className="uk-navbar-nav">
            {categories.map((category) => {
              return (
                <li key={category.id}>
                  <Link href={`/category/${category.attributes.slug}`}>
                    <a className="uk-link-reset">{category.attributes.name}</a>
                  </Link>
                </li>
              );
            })}
          </ul>
        </div>
      </nav>
    </div>
  );
};

export default Nav;

As you can see, you’re passing a few parameters to the Autocomplete component:

  • openOnFocus={false} – tells your search not to populate results until a user starts typing
  • detachedMediaQuery=''– opens search in a detached modal, providing more room for your results
  • placeholder="Search for articles" – the text that appears in the searchbox before a search
  • getSources={({ query }) => – where you define your data sources for your autocomplete experience

Remember that Autocomplete is source agnostic. You define sources based on APIs, libraries, or static content within your application. Here, you’re binding a source called articles to your Algolia index using the getAlgoliaResults function from the autocomplete-js library.

              {
                sourceId: "articles",
                getItemUrl( {item} ) { return `/article/${item.slug}`},
                getItems() {
                  return getAlgoliaResults({
                    searchClient,
                    queries: [
                      {
                        indexName: "development_api::article.article",
                        query,
                      }
                    ]
                  })
                },
                templates: {
                  item({ item, components}) {
                    return <SearchItem hit={item} components={components} />;
                  }
                }
              },

The development_api::article.article is the index generated by the Strapi Search plugin above for your article content type. When you move to production, the plugin will create a separate production_api::article.article index in the same application.

The getItemUrl() section sets up keyboard navigation, while getItems() handles retrieving articles from your index using the query term(s) from the searchbox.

Notice the code above references a SearchItem component. This is the template you’ll use to tell Autocomplete how to render your search results. Add a new component called ./frontend/components/searchItem.js with the following code.

import React from "react";

function SearchItem({ hit, components }) {
  return (
    <a className="aa-ItemLink" href={`/article/${hit.slug}`}>
      <div className="aa-ItemContent">
        <div className="ItemCategory">{hit.category.name}</div>
        <div className="aa-ItemContentBody">
          <div className="aa-ItemContentTitle">
            <components.Highlight hit={hit} attribute="title" />
          </div>
          <div className="aa-ItemContentDescription">
            <components.Highlight hit={hit} attribute="description" />
          </div>
        
        </div>
      </div>
    </a>
  );
};

export default SearchItem;

With this code, you’re displaying the category associated with the article, the title, and the description. Use the components.Highlight component to emphasize the part of the attribute that matched the user’s query.

And with that, you’re done! Start your front end server with npm run dev. You should now see the autocomplete searchbox at the top of the page. Clicking on it opens the modal search interface where you can start typing your search term.

You can see a hosted version of this front end on codesandbox, although it may take some time for the back end container to start. The before and after versions of the front end code are both available on Github as well.

If you build something cool using this blog, share it with us on Twitter.

About the author
Chuck Meyer

Sr. Developer Relations Engineer

githubtwitter

Recommended Articles

Powered byAlgolia Algolia Recommend

Replicating the Algolia documentation search with Autocomplete
ux

Sarah Dayan
François Chalifour

Sarah Dayan &

François Chalifour

Creating an omnibar with Autocomplete
engineering

Bryan Robinson

Senior Developer Relations Specialist

Part 4: Supercharging search for ecommerce solutions with Algolia and MongoDB — Frontend implementation and conclusion
engineering

Soma Osvay

Full Stack Engineer, Starschema