Search by Algolia

Sorry, there is no results for this query

How to implement autocomplete with JavaScript on your website

You’ve likely seen autocomplete searches before, where users get suggested searches as they type. Not only does it save keystrokes and time for your users, it can also uncover potential results they might not have found otherwise.

For example, if someone types “apple” into your product catalog search, they’ll get various suggestions as they type. To provide matches, you’ll need to pull these potential results from somewhere — a database, an API, or a list of known terms.

Before going down the rabbit hole into building your own autocomplete, let’s take a look at a robust, production-level solution: 

We’ve written about this autocomplete solution, which can transform the simple drop down into a rich and multi-faceted interactive user experience. When today’s users start typing a query, they expect to see more than just suggested queries — they want access to a variety of datasources and results, multiple filters, categories, and images with helpful and highlighted text. 

This autocomplete library is open sourced and fully customizable for any industry and UI/UX design.

In this article, we take a step back and show you how to build a simple autocomplete with Javascript, to help you understand the principles of our more production-level version. We’ll also show that to tune your autocomplete search correctly, you’ll need to work with additional front-end and back-end code that does the heavy lifting for you.

Basic implementation using static data

To start, let’s create a proof of concept autocomplete example. Our goal is to allow the user to start typing into a search box and see matching terms below the search form — autocompleting the user’s input as it’s typed into a search bar.

Any JavaScript autocomplete search is going to need the following:

  • HTML for the search form
  • CSS to display the results
  • A data source of results
  • JavaScript, of course

Since we’re starting with a basic implementation, we’ll return exact match results from a set of predetermined search terms. We’ll use an online store as our example, where the user is searching for a specific item. If what they have typed in the search box can be completed to match an item, the website suggests that item.

Let’s see how that search box looks in some simple HTML:

<form autocomplete="off"><input type="text" name="q" id="q" onKeyUp="showResults(this.value)" />
<div id="result"></div>

Disabling autocomplete (autocomplete = off) might seem a little strange, but this needs to be done to disable the browser’s automatic suggestions, which will get in the way of our own. 

A couple of other things to note are the onKeyUp attribute, which calls our JavaScript function, and uses an empty div for results.

Next, here’s the JavaScript to receive the search value, match it against the known terms, and display suggestions:

var search_terms = ['apple', 'apple watch', 'apple macbook', 'apple macbook pro', 'iphone', 'iphone 12'];

function autocompleteMatch(input) {
  if (input == '') {
    return [];
  var reg = new RegExp(input)
  return search_terms.filter(function(term) {
	  if (term.match(reg)) {
  	  return term;

function showResults(val) {
  res = document.getElementById("result");
  res.innerHTML = '';
  let list = '';
  let terms = autocompleteMatch(val);
  for (i=0; i<terms.length; i++) {
    list += '<li>' + terms[i] + '</li>';
  res.innerHTML = '<ul>' + list + '</ul>';

The terms are stored as a simple JavaScript array at the top. The browser will call the showResults function after every single keypress. Then it passes the current search to an autocompleteMatch function to get the list of matched terms. Finally, the results are added to the div as an unordered list.

When you run this code, you’ll notice that matched terms appear as bullet points below the search box. That’s not exactly a great experience. We’d rather see something like this:

A little CSS can complete the style, which you can customize to match your site:

#result {
  border: 1px dotted #ccc;
  padding: 3px;
#result ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
#result ul li {
  padding: 5px 0;
#result ul li:hover {
  background: #eee;

While we now have a basic autocomplete with JavaScript implementation, it’s still far from something you’d use in production. For one, the data comes from a single static array, hard-coded within our JavaScript. Let’s take a step toward a more realistic example by incorporating a back-end search request.

Back-end-driven: autocomplete with an internal API

The basic autocomplete with JavaScript example shows most of the interaction patterns users will expect. There are always design and interaction improvements to consider, but the concept remains: when the user types a few keystrokes into a search bar, they will see relevant potential searches or results below. The difference — and the subject of the remainder of this post — is where we retrieve those results.

In most sufficiently complex examples, you won’t have a finite list of potential queries. The static implementation in the first section is a proof of concept that won’t cut it in production. You’ll need to send your search to a back end to return potential matches, which means an internal API to handle the query.

We might update the showResults function in the previous section to look something like this:

function showResults(val) {
  res = document.getElementById("result");
  res.innerHTML = '';
  if (val == '') {
  let list = '';
  fetch('/suggest?q=' + val).then(
   function (response) {
     return response.json();
   }).then(function (data) {
     for (i=0; i<data.length; i++) {
       list += '<li>' + data[i] + '</li>';
     res.innerHTML = '<ul>' + list + '</ul>';
     return true;
   }).catch(function (err) {
     console.warn('Something went wrong.', err);
     return false;

Rather than compare the current search to potential queries with the autocompleteMatch function, we call the local API endpoint at /suggest. This will return a JSON array of potential matches instead.

To test this out, you could set up your own local API with Node or any other back-end language. For example, the following Express route will provide suggestions to anything passed to the q querystring:

var express = require('express');
var router = express.Router();

const data = ["apple","apple watch","iphone","iphone x","apple macbook","apple macbook air","apple macbook air pro 13"];

router.get('/suggest', function(req, res, next) {
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify(data.filter(value => value.includes(req.query.q))));

module.exports = router;

Note, we might see a performance impact if we deployed this to a server. Each lookup comes after a single keypress, which may not make sense when users are typing multiple keystrokes. You’ll want to incorporate a delay in your front end before you connect to the back end through the Internet, such as with network throttling.

Adding a query suggestions database

This code has the same finite dataset of terms we used previously. We’re still prototyping. You’ll need to connect your back-end API to a database. The query delay will become even more important when each call includes a round trip HTTP call, which itself calls a database.

The benefit is clear, though: by accessing a database, you can suggest a robust set of query suggestions that match the user’s characters as they type. A query suggestions database contains prior queries saved by the search engine as it processes every query. These queries are usually ranked by popularity. Google provides an example of this:

There’s a lot to consider for your database. Is it especially built for search terms? Or do you need to connect to an existing source, such as a product or content database? And how will you tune it to these frequent, short queries?

These are big questions that will likely point to a need to pull results from multiple sources, a concept called federated search.

Federated search: query multiple dynamic data sources

Most search engines you’ve used are likely pulling from more than one database. Unlike the basic autocomplete example, they don’t have the benefit of a small, static set of potential searches. If you’re concerned about the performance impact on a single database, it’s even more difficult with federated search.

Not only do you have multiple sources, but each is dynamic. The products database may update nightly, while the inventory management system aims to be real-time. Your reviews are likely stored elsewhere and published several times per day. You may want comments to be available more quickly to generate discussion.

Each of these databases has fields you probably want searchable — and others you don’t. Product names, descriptions, and metadata clearly need to be included. But internal identifiers or product codes might not be necessary. Similarly, user-generated content can provide rich search terms, but you’ll want to make sure personal information like email or IP addresses are kept from the search suggestions.

Once you’ve determined which data sources to use in your federated search, you need to ensure it can be reached from the front end with a single call, as shown in the back-end-driven autocomplete section. In other words, you likely don’t want the front end calling multiple data sources directly after every few keystrokes — this would be both inefficient and potentially expose too much of your internal data model. Instead, you’ll likely use one of two architectures:

The left image shows how your front end calls a back-end API that itself makes multiple requests to your databases. It would need to merge and filter these responses into a single set of search suggestions or results for the front end to display.

Alternatively, the right shows a dedicated search database for a single place to query. You would need to update this database based on the other sources periodically. The difference from the other architecture is that the merging and filtering of results happen ahead of time. In many cases, search does not need to be as real-time as direct lookups. For example, a user might expect a comment to appear instantly on the page, but wouldn’t notice if it took an hour or more to appear in a search.

There are many different approaches to how you merge and filter federated search results. To provide the best user experience for searchers, you may want to consider some additional ways to tune your results.

Beyond autocomplete: what robust search requires

Implementing great autocomplete is more than knowing the right combination of JavaScript, HTML, and CSS. You need to access the right data sources and provide the results from a back end so your front end is able to easily display it to the user. Further, you’ll find the potential improvements continue to stack up the more you consider what’s possible.

For example, there are a couple things to notice in the search suggestions above:

  1. Though “iphone” is misspelled, the results flexibly assume what the user meant
  2. For some terms, the user can drill down by category for a more specific search

Both of these features take some additional engineering to achieve. Your database may support fuzzy searching for spelling mistakes, though you’ll need to make sure the implementation of fuzzy search doesn’t decrease performance. With this in mind, we implemented a typo tolerance feature that does not slow down the query.

The category search is more advanced and requires additional structure within your search database. We’ve written a guide about faceted search with JSON attributes, which discusses how to organize your data for this type of filtered search. 

If you want to build robust search, Algolia can support you. Search suggestions and facets are built-in to our API-driven platform.

About the author
Adam DuVander

Principal Consultant at EveryDeveloper


Recommended Articles

Powered byAlgolia Algolia Recommend

Building a composable front-end search with autocomplete and instant search results

John Stewart

VP Corporate Marketing

Replicating the Algolia documentation search with Autocomplete

Sarah Dayan
François Chalifour

Sarah Dayan &

François Chalifour

Mobile Search UX – Part Two: Deconstructing Mobile Search

Raphael Terrier

Education Engineer