With Nuxt + ssr + routing, bug with the browser previous/next buttons ?
See original GitHub issueHi the team,
I am trying to implement vue-instantsearch with nuxt + ssr + routing. SSR is OK.
If I refine brand attributes with “Apple” (firstly), and secondly “Samsung”, and click on the browser back button (Chrome & Safari, Mac), the url is updated but not the app. (Apple and Samsung are always checked). If I hard reload the current page, Microsoft disappears.
What I Want : when I click on the browser back button, I want to have the previousState in my app (only “Apple” checked).
What I did :
- Create new and empty nuxt project
npx create-nuxt-app algolia-nuxt-example
cd algolia-nuxt-example
npm install vue-instantsearch algoliasearch
- Add search.vue in my app and follow Instructions in your doc (mix ssr nuxt implementation and nuxt routing /pages/search.vue
<template>
<ais-instant-search-ssr>
<ais-refinement-list attribute="brand" />
<ais-hits>
<template slot="item" slot-scope="{ item }">
<p>
<ais-highlight attribute="name" :hit="item" />
</p>
<p>
<ais-highlight attribute="brand" :hit="item" />
</p>
</template>
</ais-hits>
</ais-instant-search-ssr>
</template>
<script>
import { AisInstantSearchSsr, AisRefinementList, AisHits, AisHighlight, createServerRootMixin } from 'vue-instantsearch';
import algoliasearch from 'algoliasearch/lite';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
function nuxtRouter(vueRouter) {
return {
read() {
return vueRouter.currentRoute.query;
},
write(routeState) {
// Only push a new entry if the URL changed (avoid duplicated entries in the history)
if (this.createURL(routeState) === this.createURL(this.read())) {
return;
}
vueRouter.push({
query: routeState,
});
},
createURL(routeState) {
return vueRouter.resolve({
query: routeState,
}).href;
},
onUpdate(cb) {
if (typeof window === 'undefined') return;
this._onPopState = event => {
const routeState = event.state;
// On initial load, the state is read from the URL without
// update. Therefore, the state object isn't present. In this
// case, we fallback and read the URL.
if (!routeState) {
cb(this.read());
} else {
cb(routeState);
}
};
window.addEventListener('popstate', this._onPopState);
},
dispose() {
if (typeof window === 'undefined') return;
window.removeEventListener('popstate', this._onPopState);
},
};
}
export default {
data() {
// Create it in `data` to access the Vue Router
const mixin = createServerRootMixin({
searchClient,
indexName: 'instant_search',
routing: {
router: nuxtRouter(this.$router),
},
});
return {
...mixin.data(),
};
},
provide() {
return {
// Provide the InstantSearch instance for SSR
$_ais_ssrInstantSearchInstance: this.instantsearch,
};
},
serverPrefetch() {
return this.instantsearch.findResultsState(this).then(algoliaState => {
this.$ssrContext.nuxt.algoliaState = algoliaState;
});
},
beforeMount() {
const results =
(this.$nuxt.context && this.$nuxt.context.nuxtState.algoliaState) ||
window.__NUXT__.algoliaState;
this.instantsearch.hydrate(results);
// Remove the SSR state so it can't be applied again by mistake
delete this.$nuxt.context.nuxtState.algoliaState;
delete window.__NUXT__.algoliaState;
},
components: {
AisInstantSearchSsr,
AisRefinementList,
AisHits,
AisHighlight
},
};
</script>
nuxt.config.js
router: {
parseQuery(queryString) {
return require('qs').parse(queryString);
},
stringifyQuery(object) {
var queryString = require('qs').stringify(object);
return queryString ? '?' + queryString : '';
},
},
build: {
transpile: ['vue-instantsearch', 'instantsearch.js/es']
}
Am I making an implementation error ? Thanks if you can help me, that’s make me crazy!
Issue Analytics
- State:
- Created 2 years ago
- Comments:14 (3 by maintainers)
Top Results From Across the Web
With Nuxt + ssr + routing, bug with the browser ... - Bountysource
Hi the team,. I am trying to implement vue-instantsearch with nuxt + ssr + routing. SSR is OK. If I refine brand attributes...
Read more >SSR-Routing: Custom-/Vue-Router: History Back functionality ...
Hi, i enabled the routing functionality for NuxtJS like described in this ... + ssr + routing, bug with the browser previous/next buttons...
Read more >Server Side Rendering - Nuxt
Server-side rendering (SSR), is the ability of an application to contribute by displaying the web-page on the server instead of rendering it in...
Read more >Intercepting back button on mobile in Vue/Nuxt/Vuetify apps
Remember, we have SSR and we want to serve correct HTML immediately - before we get to the browser and can question its...
Read more >useHooks - Easy to understand React Hook recipes
We bring you easy to understand React Hook code recipes so you can learn how React hooks work and feel more comfortable writing...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
We found a solution.
First, the problem is some kind of race-condition, i guess. The vue-instantsearch callback inside the custom-routers
onUpdate
(event when doing history back) looks like this:instantSearchInstance.setUiState(stateMapping.routeToState(route));
Problem is that the
UiState
got changed but the search is not triggered again.How i solved it: Adding a watcher
$route.query
that triggers the search manually.Adding this watcher would trigger the search every time the route changes ==> also every time a refinement get’s applied and put into the URL. That would not be bad because vue-instantsearch caches the requests and does not fire them again.
Anyways, to avoid the possibility to trigger request twice, i added a dummy query-parameter when History-Back is used to only trigger the search manually when History-Back was done.
Custom-Router
Watcher
For now this is the solution we will go with.
Hi @tkrugg,
I just updated the codesandbox with my initial code, which is the mix between this documentation (SSR Nuxt) and this one (Nuxt + Routing).