Synchronize Search Parameters with the URL

Search pages commonly include active search parameters in the URL for sharing or bookmarking purposes. Headless provides two controllers to help you keep the URL of your application in sync with your Headless engine state. This article explains how to use those controllers, and why you would choose one over the other.

The context where you would make use of those controllers is during the initialization of your Headless application, so you may want to review how to do so before reading this article.

buildUrlManager

The UrlManager controller is the faster option, taking a few minutes to set up. It monitors the search parameters affecting the result list, and serializes them into a URL-ready string that contains values such as the query, sort criteria and selected facet values.

EXAMPLE

Your search page is in a state where the query is "hello" and where the results are sorted by descending date. The UrlManager would serialize this state as the following string: q=hello&sortCriteria=date%20descending.

The UrlManager controller can also do the reverse, i.e., deserialize a string and update the Headless engine state values accordingly. However, because the controller manages serialization and deserialization, it doesn’t offer control over the serialization form of the URL.

const fragment = window.location.hash.slice(1);
const urlManager = buildUrlManager(engine, { (1)
    initialState: {fragment}
})
 
urlManager.subscribe(() => { (2)
    const hash = `#${this.urlManager.state.fragment}`;
    history.pushState(null, document.title, hash);
});
 
window.addEventListener('hashchange', () => { (3)
    const fragment = window.location.hash.slice(1);
    urlManager.synchronize(fragment);
});
1 Set the initial search parameters to the values in the URL when a page first loads.
2 Update the hash when search parameters change.
3 Update the search parameters when an end user manually changes the hash.

buildSearchParameterManager

The SearchParameterManager controller provides the active search parameters as an object rather than a string, giving you full control over how to serialize them. Conversely, the controller can take in an object with search parameters with which to update the Headless engine state. The following sample is similar to the one above, but uses custom serialize and deserialize functions you would define yourself:

const url = getUrl();
const parameters = deserialize(url);
const manager = buildSearchParameterManager(engine, { (1)
    initialState: {parameters}
})
 
manager.subscribe(() => { (2)
    const url = serialize(manager.parameters);
    history.pushState(null, document.title, url);
});
 
window.addEventListener('hashchange', () => { (3)
    const url = getUrl();
    const parameters = deserialize(url);
    manager.synchronize(parameters);
});
 
function serialize(parameters) {
    // ...
}
 
function deserialize(url) {
    // ...
}
1 Set the initial search parameters to the values in the URL when a page first loads.
2 Update the URL when search parameters change.
3 Update the search parameters when a user manually changes the URL.

In summary, Headless offers two controllers to synchronize your engine state with the URL. The buildUrlManager controller is faster to set up, but doesn’t let you control the form of the URL. The buildSearchParameterManager controller offers full control over the form of the URL, but takes more time to set up since it does not handle search parameter serialization and deserialization.

Recommended Articles