Implementing promoted search results with React InstantSearch

Learn how to display promoted results with React InstantSearch Hooks and Meilisearch.

Laurent Cazanove

Laurent Cazanove

Developer Experience Engineer·@StriftCodes·LinkedIn

··7 min read
Implementing promoted search results with React InstantSearch

Share the article

Today we’ll learn how to promote results by pinning given documents at the top of search results. This can be used in ecommerce to give more visibility to featured products or in-app search to prioritize user-specific content. We’ll use Node.js and React to implement promoted documents.

Need promoted documents inside the Meilisearch engine? Give your feedback!

This tutorial will use a sample movie dataset. Our objective will be to have “Finding Nemo” at the top of the results when typing “funny”, “children”, or “fish”.

Folder structure

In this guide, we’ll separate the frontend code from the backend code used to configure Meilisearch.

We’ll organize our project using the following folder structure:

json

First, create a directory for our application (eg. my-app) or use an existing one. In our application directory, let’s create a data folder for the backend code.

Download the movies dataset and save it as movies.json in the new data folder.

The promoted index holds only the documents you want pinned, plus a keywords field listing the queries that should surface them. Create data/promoted-movies.json with a single promoted movie:

json

Alright. Let’s code!

Meilisearch setup

First, we need a Meilisearch instance. The quickest route is Meilisearch Cloud, which gives you a managed project with no setup. You can also run the open-source engine locally by following the self-hosting guide. We’ll write a setup script to configure our Meilisearch instance and seed the data.

This setup script uses the JavaScript SDK, but you can use any of Meilisearch SDKs.

In this tutorial, we're using the current Node LTS. Let's install the JavaScript SDK:

bash

Then, let's create a setup.js file:

javascript

This script creates our two indexes. Let’s recap what it does:

  • It sets the same displayed attributes for both movies and promoted-movies.
  • It sets the searchable attributes; only keywords is searchable in the promoted-movies index.
  • It adds documents to our Meilisearch indexes.

To optimize indexing speed, always add documents after configuring settings.

We can now run the script with Node.js:

bash

Our Meilisearch instance is now configured and seeded. It’s time to implement promoted results using React!

Displaying promoted results

First, we’ll navigate back to the root directory of our application (eg. my-app). We’ll use Vite to create the React app in this folder.

bash

If the CLI asks to remove existing files from the current directory, answer 'No'.

Then, let’s install the additional dependencies for integrating InstantSearch with Meilisearch:

bash

Let’s edit our App component to display search results. We want the promoted results to show up before the rest. Let’s replace the App.jsx boilerplate code with our own:

javascript

We can now run the development server using npm run dev. In the browser, our app should display something like this:

HTML output of the code above

Displaying promoted results before other results

Congrats. We’ve successfully displayed our promoted results before the rest of the results.

Got stuck? Don’t hesitate to ask for help in our Discord community.

Frequently asked questions (FAQs)

How do promoted search results work in Meilisearch?

Meilisearch has no dedicated "promote this document" setting, so you model promotion as data. You keep a second, much smaller index holding only the documents you want pinned, with a keywords field listing the queries that should surface them. Both indexes are queried in the same request, and the frontend renders the promoted hits above the regular ones.

Why does the promoted index only make keywords searchable?

Because you want full control over when a promoted document appears. If title and overview were searchable in the promoted index, "Finding Nemo" would surface for any query matching its description, not only the queries you chose. Restricting the searchable attributes to keywords means the document is promoted for exactly the terms you list and nothing else.

Does promoting documents this way affect the relevancy of normal results?

No. The two indexes are ranked independently, so the promoted index cannot reorder or suppress anything in your main index. The main results come back exactly as they would without promotion, and the promoted hits are simply rendered before them.

Can you implement promoted results on the backend instead?

Yes. Instead of querying two indexes from the frontend, you can pin documents server-side with any of the Meilisearch SDKs and merge them into a single response. That takes more backend code but returns one result set, which is easier to paginate.

Going further

This tutorial explored one approach for implementing promoted results. An alternative technique would be implementing document pinning in the backend, using one of Meilisearch SDKs. This approach has the benefit of allowing to merge results in a single response (as if they were coming from a single index).

Both techniques can achieve similar results. We also plan to integrate promoted documents in the Meilisearch engine. Share your use case in our product discussions to help us prioritize it.

For more things Meilisearch, you can subscribe to our newsletter. You can learn more about our product by checking out the roadmap and participating in our product discussions.

For anything else, join our developers' community on Discord.

I’ll see you there.

Laurent Cazanove

Laurent Cazanove

Developer Experience Engineer

Laurent Cazanove is a freelance software engineer specializing in developer experience.

Related articles