Shobdo Logo

Implementing Autocomplete

When a user is typing in a search bar, hitting the full /search endpoint on every keystroke is inefficient. The /search endpoint returns heavy dictionary objects (with phonetics, definitions, and synonyms) which takes more bandwidth and processing time.

For a snappy, "type-ahead" experience, you should use the Autocomplete API.

The Autocomplete API

The /api/v1/api/autocomplete endpoint is highly optimized for speed. Instead of returning full dictionary entries, it returns a lightweight array of suggested words based on a prefix.

Making a Request

Listen to the onChange event of your search input, and fetch suggestions as the user types:

// Example prefix from user input
const prefix = "dic";
 
const fetchSuggestions = async (prefix) => {
  // If the input is empty, clear suggestions
  if (!prefix.trim()) return [];
 
  const response = await fetch(`https://api.shobdo.me/api/v1/api/autocomplete?q=${encodeURIComponent(prefix)}`, {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Accept": "application/json"
    }
  });
 
  const suggestions = await response.json();
  return suggestions;
};
 
// Result for "dic":
// [ "dictionary", "dictate", "dictator", "diction", "dice" ]

Best Practices

To build a production-grade autocomplete search bar, you should implement the following techniques:

1. Debouncing

Do not fire an API request on every single keystroke. Instead, wait for the user to pause typing (usually 150ms - 300ms) before making the request. This reduces API calls and prevents race conditions where an older, slower request overrides a newer one.

2. Caching

If a user types "dict", deletes the "t", and types it again, you shouldn't need to hit the API again. Keep a local memory cache of prefix -> results.

The Autocomplete API only provides the words. Once a user clicks on one of the suggestions (e.g. "dictionary"), you should then redirect them to a results page or fire a request to the /api/v1/api/entry/en/word/dictionary endpoint to fetch the actual definitions!

Example React Implementation

Here is a simplified example of how you might wire this up in a React component:

import { useState, useEffect } from "react";
import { useDebounce } from "use-debounce"; // npm install use-debounce
 
export function SearchBar() {
  const [query, setQuery] = useState("");
  const [suggestions, setSuggestions] = useState([]);
  
  // Debounce the query by 300ms
  const [debouncedQuery] = useDebounce(query, 300);
 
  useEffect(() => {
    if (!debouncedQuery) {
      setSuggestions([]);
      return;
    }
 
    const loadSuggestions = async () => {
      const res = await fetch(`https://api.shobdo.me/api/v1/api/autocomplete?q=${debouncedQuery}`, {
        headers: { "Authorization": "Bearer YOUR_API_KEY" }
      });
      const data = await res.json();
      setSuggestions(data);
    };
 
    loadSuggestions();
  }, [debouncedQuery]);
 
  return (
    <div className="relative">
      <input 
        value={query} 
        onChange={e => setQuery(e.target.value)} 
        placeholder="Search a word..." 
      />
      
      {suggestions.length > 0 && (
        <ul className="absolute bg-white shadow-lg">
          {suggestions.map(word => (
            <li key={word} onClick={() => alert(`You selected: ${word}`)}>
              {word}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

Assistant

Hi! I'm the Shobdo Assistant.
Ask me anything about the documentation.