Hello,
I am using Next.js with React InstantSearch Hooks , and I have encountered an issue with the search query disappearing from the URL after submitting the search box when transitioning from one page to another. This problem does not occur if I perform a search on the result page itself.
For example, when I press enter on the search box on ‘http://localhost:3000’, the home page, I am first redirected to ‘http://localhost:3000/results?query=edp’, but then the URL immediately changes to ‘http://localhost:3000/results’, causing the search query to disappear and the ui state to reset, the searchbox is empty. No 301 occur in the network tab.
Here is the routing configuration from my current _app.js
implementation:
import { createInstantSearchRouterNext } from 'react-instantsearch-hooks-router-nextjs';
import { InstantSearch } from 'react-instantsearch-hooks-web';
import { searchClient } from '../lib/algolia/searchClient';
import { ClerkProvider } from "@clerk/nextjs";
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { history } from 'instantsearch.js/es/lib/routers';
// other imports
function MyApp({ Component, pageProps, serverState, serverUrl }) {
const router = useRouter()
const { query } = router
const routing = {
router: history({
windowTitle({ query }) {
const queryTitle = query ? `Resultats pour "${query}"` : 'Recherche';
return queryTitle;
},
createURL({ qsModule, location, routeState }) {
const { origin, pathname, hash } = location;
const indexState = routeState[process.env.NEXT_PUBLIC_ALGOLIA_DEALS_INDEX_NAME] || {};
const queryString = qsModule.stringify(routeState);
if (!indexState.query) {
return `${origin}${pathname}${hash}`;
}
return `${origin}${pathname}?${queryString}${hash}`;
},
parseURL({ qsModule, location }) {
const { query = '', brands = [] } = qsModule.parse(
location.search.slice(1)
);
// `qs` does not return an array when there's a single value.
const allBrands = Array.isArray(brands)
? brands
: [brands].filter(Boolean);
return {
query: decodeURIComponent(query),
brands: allBrands.map(decodeURIComponent),
};
},
}),
stateMapping: {
stateToRoute(uiState) {
const indexUiState = uiState[process.env.NEXT_PUBLIC_ALGOLIA_DEALS_INDEX_NAME]|| {};
return {
query: indexUiState.query,
...query
};
},
routeToState(routeState) {
return {
[process.env.NEXT_PUBLIC_ALGOLIA_DEALS_INDEX_NAME]: {
query: routeState.query,
...query
},
};
},
},
};
// ...
return(
<ClerkProvider
{...pageProps}
appearance={{
elements: {
socialButtonsBlockButton__google: {
display: isFacebook ? "none" : "flex",
},
},
}}
localization={defaultResource}
>
<InstantSearch
searchClient={searchClient()}
indexName={process.env.NEXT_PUBLIC_ALGOLIA_DEALS_INDEX_NAME}
routing={routing}
>
<Component {...pageProps} />
</InstantSearch>
</ClerkProvider>
)
}
export default MyApp
The results page is pretty basic:
// pages/results/index.js export default function Index() { const { user } = useUser(); const router = useRouter(); const { query } = router; return ( // .... ) } ```
Do you have any idea to solve this problem and maintain the uistate with the search query in the result page?
Thank you for you help.