Skip to main content
Synchronizing your UI with the browser URL is considered good practice. It lets your users take one of your results pages, copy the URL, and share it. It also improves the user experience by enabling the use of the back and next browser buttons to keep track of previous searches. InstantSearch provides the necessary API entries to let you synchronize the state of your search UI (your refined widgets and current ) with any kind of storage. Use the routing option to synchronize UI state with the browser URL, so users can bookmark, share, and revisit the same search.
Don’t configure initial-ui-state and routing together.
  • Use initialUiState to set the UI state when the search first loads, such as for a default query or filter.
  • Use routing to keep the UI state synchronized with the URL, so users can bookmark or share a search.

Routing examples

The examples in this section use Vue 2. If you use Vue 3, adapt them using the Vue 3 migration guide.

Basic routing demo

Run and edit the basic routing example in CodeSandbox.

Basic routing source code

Browse the source code for the basic routing example.

SEO-friendly routing demo

Run and edit the SEO-friendly routing example in CodeSandbox.

SEO-friendly routing source code

Browse the source code for the SEO-friendly routing example.

Vue Router demo

Run and edit the Vue Router example in CodeSandbox.

Vue Router source code

Browse the source code for the Vue Router example.

Default URLs

The examples use the InstantSearch.js router. Add instantsearch.js to your project dependencies alongside vue-instantsearch.
Configure the routing prop on <ais-instant-search> to synchronize UI state with the browser URL. The default routing setup stores routing-compatible UI state in URL query parameters.
Vue
Assume the following search UI state:
  • Query: “galaxy”
  • Menu:
    • categories: “Cell Phones”
  • Refinement List:
    • brand: “Apple”, “Samsung”
  • Page: 2
This produces the following URL:
By default, routing includes state from routing-compatible widgets. With many widgets, this can create long URLs. To create shorter or more descriptive URLs, customize the URL routing.

Customize URL routing

You can customize which values appear and rename the URL parameters. The stateMapping option maps between InstantSearch’s uiState and the routeState used by the router. Use it to rename parameters or omit values that you don’t want to include in the URL.
JavaScript
InstantSearch stores widget state in uiState. The following example maps that state to shorter URL parameters. The state contains information about the user’s search, including the query, the selection, the page being viewed, and the widget hierarchy. uiState only stores modified widget values, not defaults. To persist this state in the URL, InstantSearch converts the uiState into an object called routeState: this routeState then becomes a URL. Conversely, when InstantSearch reads the URL and applies it to the search, it converts routeState into uiState. This logic lives in two functions:
  • stateToRoute: converts uiState to routeState.
  • routeToState: converts routeState to uiState.
Assume the following search UI state:
  • Query: “galaxy”
  • Menu:
    • categories: “Cell Phones”
  • Refinement List:
    • brand: “Apple” and “Samsung”
  • Page: 2
This translates into the following uiState:
JSON
Implement stateToRoute to flatten this object into a URL, and routeToState to restore the URL into a UI state:
JavaScript

Keep unrelated URL parameters

By default, routing writes only InstantSearch state to the URL. To preserve unrelated parameters, include them when implementing createURL. The following example preserves URL parameters that start with utm_:
JavaScript

Change the name of a key in routing

To rename the query route parameter to q, return q from stateToRoute and map it back to query in routeToState.

SEO-friendly URLs

This guide uses the router from InstantSearch.js. Make sure you add instantsearch.js to your project’s dependencies in addition to vue-instantsearch.
To create more descriptive URLs, move search state from query parameters into the URL path. This is a common pattern for ecommerce category and search pages.
The category appears in the URL path, while the query, page, and brands remain query parameters. This simplified routing assumes that only one widget controls each routed attribute.

Store categories in the URL path

This example stores the category in the path and the query, page, and brands as query parameters.
JavaScript
The basic routing example uses the history router. The router reads and writes URLs, while stateMapping maps uiState to routeState and back. When you configure the history router, you can customize these functions:
  • windowTitle: returns the browser window title for a routeState.
  • createURL: creates a URL from routeState. InstantSearch calls it when synchronizing the browser URL, rendering links in the menu widget, or when a connector calls createURL.
  • parseURL: creates routeState from the URL when users load or reload the page or use the browser’s back or forward navigation.

Make URLs more discoverable

Shorter category URLs can be more readable and memorable. Use a mapping object to map category names to shorter URL slugs. Given the dataset in this guide, you can make some categories more discoverable:
  • “Cameras and camcorders” → /Cameras
  • “Car electronics and GPS” → /Cars
When users open https://example.org/search/Cameras, InstantSearch selects the “Cameras and camcorders” category. Define mappings between category names and URL slugs:
JavaScript
You can build these dictionaries from your Algolia . With such a solution, you have full control over what categories are discoverable from the URL.

About SEO

For your search results to be part of a public search engine’s results, you must be selective. Trying to index too many search results pages could be considered spam. To do that, create a robots.txt and host it at https://example.org/robots.txt. Here’s an example based on the URL scheme you created.
robots.txt

Combine with Vue Router

The previous examples use the InstantSearch history router. If your search page reads the URL through Vue Router to render content outside InstantSearch, synchronize InstantSearch with Vue Router instead. Otherwise, keep the InstantSearch router. Create a router object instead of using historyRouter. The router property expects an object with these functions:
JavaScript
This example uses the default stateMapping. Configure Vue Router to parse nested query parameters and serialize them into query strings in main.js first:
JavaScript
Define the custom router in the routing object returned by data:
JavaScript

Combine with Nuxt

To enable routing in a Nuxt app, you can’t use the createServerRootMixin factory as a mixin as usual, because you need to access Vue Router which is only available on the component instance. Here’s the workaround:
  1. Use createServerRootMixin in data, so this.$router is available.
  2. Create an InstantSearch router that wraps Vue Router.
  3. Set up provide as the root mixin would otherwise do.
  4. Set up findResultsState in serverPrefetch.
  5. Call hydrate in beforeMount.
Set up a custom renderToString function.
Wrap the Vue Router for usage with Vue InstantSearch.
Vue
As in Vue Router, you must set up Nuxt to write deep query strings. In Nuxt, you do this in nuxt.config.js:
JavaScript

Group facet values

To group facet values such as “turquoise”, “ocean”, and “sky” under “blue”, add the group at indexing time. Either add a separate grouping attribute or store both the individual value and group value in the same attribute. For example, with the following dataset:
JSON
To facet on a separate grouping attribute, add colorGroup to each record:
JSON
To facet on both individual colors and their group, store both values in the color attribute:
JSON
Last modified on September 3, 2026