Dynamic webpages with a high amount of site content are usually complex for users to navigate looking for specific data. These sites use On-site search (also called internal search), which uses a search bar to return the results of a search query made by the user. This simple implementation provides relevant content to users' needs, saving time and effort spent searching for data.
In this tutorial, readers will learn what on-site search is, when to use it, how they can build a web application implementing search functionality with a CMS, and its benefits.
As the name implies, on-site search is a search feature that takes place on a website. It uses a search bar, where the user enters a search query. Based on the query in the search bar, the site data is filtered to provide information relevant to the search.
Search engines such as Google have a vast amount of information. To provide relevant results for what the user wants, they use search bars to collect a search query and display popular and related results to the user's entry. This feature is also nice to have quality for web applications, to provide ease of use to the site’s visitors.
Meilisearch is an open-source search engine that can be easily integrated into web applications to handle search functionalities. The Meilisearch Strapi Plugin is a search plugin that can be linked to the Strapi CMS to filter through the store information and provide relevant/related results to the search query entered in the search box.
It is easy to set up: Meilisearch effortlessly fits into your application. With a few steps, this search feature can be integrated into your application.
It is flexible: Meilisearch readily updates to reflect changes to the data source, for instance, when new data is added or pre-existing information is modified.
It is fast and typo-tolerant: Meilisearch offers quick search results and has a feature to account for typing errors made by users. Even if users made a mistake in the search query, they would still get relevant results.
Data security: The data linked to Meilisearch is secure and can only be accessed with the correct API credentials.
Strapi is an open-source, headless Content Management System developed using the Node.js Javascript framework. Strapi provides users with features to store, manipulate, and manage content across their application workflows. It's simple and easy to use. Strapi provides users with an administrative panel where they can monitor and manipulate their content.
To quickly follow up with this tutorial, you will need to get the starter code for the movie web application. The front-end can be found on the GitHub repo. You can also get the Strapi starter template with some movie collections from the following repo.
If you run the front-end starter code in your terminal with the npm run dev
command, you will get a result similar to the image below:
The starter code has four components: Movies.js
, Nav.js
, List.js
, and Card.js
. The Movies.js
component renders the Nav
and List
components. The Nav
components contain the search bar that we will link to the meilisearch
plugin later in this tutorial. The List
component will return the data from the Strapi
collections in the form of cards. These cards will contain the image, movie name, and genre.
To connect the application to the Strapi CMS collection, we will need to fetch the data from Strapi, map through it and return the cards with the appropriate details. But before that, note that we will only have to return results corresponding to the search bar query and only return the entire collection when the search input is empty. We will need to install meilisearch
and integrate the search functionality to achieve this.
To make use of Meilisearch locally, we will download and run an instance of it. This can be downloaded from Meilisearch. Next, we install the Strapi-meilisearch
plugin in the cloned Strapi starter repo with the following command CLI command:
npm install strapi-plugin-meilisearch
After this, we run npm run develop
to rebuild our Strapi application with the new meilisearch
plugin. Open the localhost URL in your browser and log in. You will be directed to the Strapi dashboard:
Click on the meilisearch
option from the left navigation pane, and in the “Settings” tab enter the URL for the meilisearch instance.
Finally, add the movie collection to meilisearch in the “Collections” window:
With this, if we launch our meilisearch instance, we'll get the Strapi collections.
To return the Strapi collection to our application, we will need to install meilisearch js
with the following command in CLI:
npm install meilisearch
Next, we will add an import for this dependency in Movies.js
:
1 import { React, useEffect, useState } from "react";
2 import MeiliSearch from "meilisearch";
3
4 const Movies = () => {
5 const [collection, setCollection] = useState([]);
6 useEffect(() => {
7 const fetchData = async () => {
8 const client = new MeiliSearch({
9 host: 'http://127.0.0.1:7700',
10 })
11 const index = await client.getIndex('moviesapp');
12 const movies = await index.search('*');
13 setCollection(movies.hits);
14 };
15 fetchData();
16 }, []);
17 //....
The above code returns all movies from our Strapi CMS received through the meilisearch
instance. To render our Cards
, we pass the collection
as a prop to the List
component, map through it, and return the data:
1<List collection={collection}/>
Then in List.js
:
1 // we pass the collection prop to the Cards component to render it
2 const List = ({collection}) => {
3 return (
4 <div className="w-full flex justify-center">
5 <div className=" w-5/6 px-6 pt-24 grid grid-cols-3 gap-2">
6 <Cards collection={collection} />
7 </div>
8 </div>
9 );
10 };
Finally, we can map through the collection
in Cards.js
:
1 const Cards = ({collection}) => {
2 return (
3 <>
4 {collection && collection.map((movie) => (
5 console.log(movie.image.url),
6 <div className=" text-white" key={movie.id}>
7 <Image
8 className=" rounded-md"
9 src={`http://localhost:1337${movie.image.url}`}
10 height="300px"
11 width="200px"
12 alt="image here"
13 />
14 <h2 className=" font-semibold">{movie.moviename}</h2>
15 <h3 className=" opacity-50">{movie.genre}</h3>
16 </div>
17 ))}
18 </>
19 );
20 };
With this done, when we run our code, we get a result similar to the image below:
We will only need to return results related to the search query in the input field for the search functionality. We will simply pass the search input data from the Nav
component to the Movies
component and add it to the fetchData
function.
In Movies.js
, we will create a function that will return the search field value:
1 const [input, setInput] = useState("");
2 // use effect block
3 const pull_data =(dat)=>{
4 setInput(dat)
5 }
Then we pass pull_data
function to the Nav
component:
1<Nav func={pull_data}/>
In Nav.js
, we will pass the value from the input field to this prop:
1 const Nav = ({func}) => {
2 const [input, setInput] = useState("");
3 func(input)
4 const handleInputChange = (e) => {
5 setInput(e.target.value);
6 };
7 //....
With this, the final step is to add the input
to the fetchData
function in Movies.js
:
1 const index = await client.getIndex('moviesapp');
2 const movies = await index.search(input);
3 setCollection(movies.hits);
4 };
5 fetchData();
6 }, [input]);
Now, we can enter a search query, and we only get results related to search keywords.
We have come to the end of this tutorial. In this tutorial, we learned about on-site search and its benefits. We also integrated search functionality into a movie application using Meilisearch. With the Meilisearch functionality, we can search through the movie collection either with the movie name or genre. It also readily reflects changes in the Strapi collection, such as deleting or adding a new entry.
I am a front-end react developer and technical writer. I build scalable web applications with different implementations.