Skip to main content
This is a pilot feature according to Algolia’s Terms of Service (“Beta Services”). Functionality may change before general availability.
In a React single-page app, routes change without a full page reload, so a plain <script> tag alone can’t re-initialize the experience between routes. This guide shows how to create a custom Hook that manages the Algolia Experiences lifecycle in your React codebase.

Before you begin

You need:

Declare the global type

If you use TypeScript, extend the Window interface so window.AlgoliaExperiences is typed:
global.d.ts
interface Window {
  AlgoliaExperiences?: { run: () => void; dispose: () => void };
}

Create the Hook

Create a Hook that loads the library script on first mount, calls run() on later route changes, and calls dispose() on cleanup:
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

export function useAlgoliaExperiences(opts: {
  src: string;
  appId: string;
  apiKey: string;
  experienceId: string;
}) {
  const { pathname } = useLocation();
  const injected = useRef(false);

  useEffect(() => {
    if (!injected.current) {
      injected.current = true;
      const { src, ...params } = opts;
      const url = new URL(src);
      for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
      const script = document.createElement('script');
      script.src = url.href;
      document.head.appendChild(script);
    } else {
      window.AlgoliaExperiences?.run();
    }
    return () => window.AlgoliaExperiences?.dispose();
  }, [pathname]);
}
The example imports useLocation from React Router. If your app uses a different router, swap it for the equivalent path Hook from that router. The Hook only needs the current path as its effect dependency. The Hook manages the experience lifecycle:
  1. On first mount, it builds the loader URL with your credentials as query parameters and appends the script to <head>.
  2. On later route changes, calls run() to remount the experience in the current page’s container.
  3. On unmount or before the next route change, calls dispose() to clean up the previous instance.

Use the Hook in your layout

Call the Hook from a component that wraps all routes where you want the experience to appear.
import { Outlet } from 'react-router-dom';
import { useAlgoliaExperiences } from './useAlgoliaExperiences';

function Layout() {
  useAlgoliaExperiences({
    src: 'https://cdn.jsdelivr.net/npm/@algolia/experiences/dist/experiences.js',
    appId: 'ALGOLIA_APPLICATION_ID',
    apiKey: 'ALGOLIA_SEARCH_API_KEY',
    experienceId: 'EXPERIENCE_ID',
  });

  return <Outlet />;
}
Make sure the container element configured in the editor (for example, <div id="autocomplete" />) renders on the pages where the experience should appear.

Next steps

  • Verify the experience renders on every route, including after browser back and forward navigation.
  • Check the troubleshooting guide for content security policy directives and common issues.
Last modified on May 21, 2026