Skip to main content
Animated placeholders mimic the effect of typing queries in a passive search box. They’re a good way of drawing your users’ attention to the search box and suggesting possible queries. Such a pattern can help increase the usage of your search box and improve conversion rate and discovery.

Before you begin

This tutorial requires InstantSearch.js.

High-level overview

To create an animated placeholder, you want to run some code that animates text character by character with pauses between, and injects it into the search box as placeholder text. The length of a pause should be random so it looks like actual typing. The recommended delay range of 50-90 milliseconds looks the most natural.

Single placeholder

1

Add a search box

Add an InstantSearch searchBox widget and set its placeholder to an empty string.
JavaScript
search.addWidget(
  instantsearch.widgets.searchBox({
    container: "#search-box",
    placeholder: "",
    showLoadingIndicator: true,
  }),
);
2

Declare constants

Declare the following constants:
  • The search box element
  • The delay after the animation has run
  • The animation delay between letters (a minimum and maximum value)
  • Your placeholder text.
JavaScript
const searchBar = document.querySelector(".ais-SearchBox-input");

const DELAY_AFTER_ANIMATION = 1000;
const MIN_ANIMATION_DELAY = 50;
const MAX_ANIMATION_DELAY = 90;
const PLACEHOLDER = "This is an animated placeholder";
3

Randomize animation time

Add a function that returns a random integer between a minimum and maximum value. This gets the animation time for each letter.
JavaScript
const getRandomDelayBetween = (min, max) =>
  Math.floor(Math.random() * (max - min + 1) + min);
4

Set the placeholder attribute value

Add a function that sets the value of the placeholder attribute in the search box.
JavaScript
const setPlaceholder = (inputNode, placeholder) => {
  inputNode.setAttribute("placeholder", placeholder);
};
5

Animate the characters

  1. Add a function that recursively animates all the characters from an array.
    JavaScript
    const animateLetters = (currentLetters, remainingLetters, inputNode) => {
      if (!remainingLetters.length) {
        return;
      }
    
      currentLetters.push(remainingLetters.shift());
    
      setTimeout(
        () => {
          setPlaceholder(inputNode, currentLetters.join(""));
          animateLetters(currentLetters, remainingLetters, inputNode);
        },
        getRandomDelayBetween(MIN_ANIMATION_DELAY, MAX_ANIMATION_DELAY),
      );
    };
    
  2. Add a function that makes the initial call to animateLetters.
    JavaScript
    const animatePlaceholder = (inputNode, placeholder) => {
      animateLetters([], placeholder.split(""), inputNode);
    };
    
6

Animate the placeholder

Add an event listener that animates the placeholder when the page loads.
JavaScript
window.addEventListener("load", () => {
  animatePlaceholder(searchBar, PLACEHOLDER);
});

Multiple placeholders

To animate multiple placeholders, you need to make a few changes to the code you wrote for a single placeholder implementation.
1

Change placeholder constant

Change your PLACEHOLDER constant to an array of strings called PLACEHOLDERS, containing all the placeholder sentences you want to display.
JavaScript
const searchBar = document.querySelector(".ais-SearchBox-input");
const DELAY_AFTER_ANIMATION = 1000;
const PLACEHOLDER = "This is an animated placeholder"; 
const PLACEHOLDERS = [  
  "This is an animated placeholder", 
  "Search for a green hoodie", 
  "Search for our latest item", 
  "Find your favorite movie", 
]; 

const MIN_ANIMATION_DELAY = 50;
const MAX_ANIMATION_DELAY = 90;
2

Select random placeholder

  1. Add an onAnimationEnd callback function that selects a random (but different) placeholder string from your PLACEHOLDERS array and calls the animatePlaceholder function with the new string. This function triggers every time the animation ends.
    JavaScript
    const onAnimationEnd = (placeholder, inputNode) => {
      setTimeout(() => {
        let newPlaceholder = "";
    
        do {
          newPlaceholder =
            PLACEHOLDERS[Math.floor(Math.random() * PLACEHOLDERS.length)];
        } while (placeholder === newPlaceholder);
    
        animatePlaceholder(inputNode, newPlaceholder, onAnimationEnd);
      }, DELAY_AFTER_ANIMATION);
    };
    
  2. Change the return value of your animateLetter function so that it calls the onAnimationEnd function whenever a placeholder animation ends.
    JavaScript
    const animateLetters = (
      currentLetters,
      remainingLetters,
      inputNode,
      onAnimationEnd,
    ) => {
      if (!remainingLetters.length) {
        return; 
        return ( 
          typeof onAnimationEnd === "function" &&
          onAnimationEnd(currentLetters.join(""), inputNode) 
        ); 
      }
    
      currentLetters.push(remainingLetters.shift());
    
      setTimeout(
        () => {
          setPlaceholder(inputNode, currentLetters.join(""));
          animateLetters(
            currentLetters,
            remainingLetters,
            inputNode,
            onAnimationEnd,
          );
        },
        getRandomDelayBetween(MIN_ANIMATION_DELAY, MAX_ANIMATION_DELAY),
      );
    };
    
3

Update event listener

Update your load event listener so that it passes the onAnimationEnd callback and the first item of your PLACEHOLDERS array to animatePlaceholders.
JavaScript
window.addEventListener('load', () => {
  // If we want multiple, different placeholders, we pass our callback.
  animatePlaceholder(
    searchBar,
    PLACEHOLDER, 
    PLACEHOLDERS[0], 
    onAnimationEnd
  );
});