I’m using Vue instantsearch and I want to make the URL a bit pleasing to the eyes so I followed this guide: https://www.algolia.com/doc/guides/building-search-ui/going-further/routing-urls/vue/#seo-friendly-urls
But the problem is I couldn’t get the category filter to work properly. The route is generated and appended to the address bar when I use the category filter but when I access the same URL again, either by pressing enter on the address bar or refreshing the page, the category filter is stripped off and only the query string remains.
Here’s what I have so far:
routing: {
router: historyRouter({
createURL({ qsModule, routeState, location }) {
const urlParts = location.href.match(/^(.*?)\/search/);
const baseUrl = `${urlParts ? urlParts[1] : ""}/`;
const queryParameters = {};
if (routeState.query) {
queryParameters.query = encodeURIComponent(routeState.query);
}
if (routeState.categories) {
queryParameters.categories = routeState.categories.map(encodeURIComponent);
}
if (routeState.page !== 1) {
queryParameters.page = routeState.page;
}
const queryString = qsModule.stringify(queryParameters, {
addQueryPrefix: true,
arrayFormat: "repeat",
});
return `${baseUrl}search/${queryString}`;
},
}),
parseURL({ qsModule, location }) {
const pathnameMatches = location.pathname.match(/search\/(.*?)\/?$/);
const { query = "", page, categories = [] } = qsModule.parse(location.search.slice(1));
const all_categories = Array.isArray(categories) ? categories : [categories];
return {
query: decodeURIComponent(query),
page,
category: all_categories.map(decodeURIComponent),
};
},
stateMapping: {
stateToRoute(uiState) {
const indexUiState = uiState["my_index"] || {};
return {
query: indexUiState.query,
categories: indexUiState.refinementList && indexUiState.refinementList.category,
page: indexUiState.page,
};
},
routeToState(routeState) {
const category_list = routeState.category ? routeState.category.split(" ") : [];
return {
my_index: {
query: routeState.query,
page: routeState.page,
refinementList: {
category: category_list,
},
},
};
},
},
},
The category is being picked up nicely by the routeToState
function. But as soon as it gets to the stateToRoute
, the category is no longer there. The name of my index is my_index
.
Any ideas what’s wrong with my code?
update
I figured out what's causing the URL to reset. I'm using <ais-configure>
to sort the results based on the user's current location:
<ais-configure
:distinct="true"
:around-lat-lng.camel="coordinates"
:around-radius.camel="around_radius"
:hits-per-page.camel="10"
/>
The coordinates
is empty by default:
data() {
return {
coordinates: ""
}
}
But when the component is created, I determine the user's location and update the coordinates
. This will then trigger it to re-render. Thus losing the initial state supplied through the URL:
created() {
this.$getLocation().then((coordinates) => {
this.coordinates = `${coordinates.lat},${coordinates.lng}`;
});
},
How do I make it so that it doesn't do that?