SSR-Routing: Custom-/Vue-Router: History Back functionality: UiState change not triggered

Hi,

i enabled the routing functionality for NuxtJS like described in this guide.

I’m rewriting the URL/Query params in the way we need them.
(No object-structure, only simple string-params)
Example: https://my-app.com/products?query=Mais

When SSR hard-reloading with facets/filters set inside the URL, they got applied correct and the products get filtered.

The Problem:
When doing history-back, i can see/log that the query-object get converted into the UiState correct, but the search and it’s facets/filters is not getting updated.

Workflow of History-Back-Functionality:
When listening on the onUpdate => popstate event, i’m taking the Vue-Router’s current route and forwarding it’s query-object to the callback.

The query-object get’s passed to the routing->stateMapping->routeToState like when doing a SSR hard-reload.

The URL gets updated to the correct History-Page, but the search is not getting updated/triggered.

I checked the UiStates that got created out of the URL when SSR and History-Back.

The only difference i recognized is this:
UiState after routeToState when SSR

Bildschirmfoto 2021-04-23 um 12.49.02

UiState after routeToState when History-Back

Bildschirmfoto 2021-04-23 um 12.49.21

Code

The Router

function nuxtRouter(vueRouter) {
  return {
    /* read from the URL and return a routeState */
    read() {
      return vueRouter.currentRoute.query
    },

    /* write to the URL */
    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
      })
    },

    /* return a URL as a string */
    createURL(routeState) {
      return vueRouter.resolve({
        query: routeState
      }).href
    },

    /* call this callback whenever the URL changed externally */
    onUpdate(callBack) {
      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) {
          callBack(this.read())
        } else {
          callBack(vueRouter.currentRoute.query)
        }
      }

      window.addEventListener('popstate', this._onPopState)
    },

    /* remove any listeners */
    dispose() {
      if (typeof window === 'undefined') {
        return
      }

      window.removeEventListener('popstate', this._onPopState)
      window.removeEventListener('query-updated', this._onPopState)
    }
  }
}

The Routing

data() {
    // Create ServerRootMixin in `data` to access the Vue Router
    const mixin = createServerRootMixin({
      searchClient,
      indexName: ALGOLIA_SEARCH_INDEX,
      routing: {
        router: nuxtRouter(this.$router),
        stateMapping: {
          stateToRoute(uiState) {
            return convertStateToQuery(uiState)
          },
          routeToState(routeState) {
            return convertQueryToState(routeState)
          }
        }
      }
    })

    return {
      ...mixin.data()
    }
  }
  • The rest of the implementation is like in the SSR Routing docs
  • convertStateToQuery & convertQueryToState are simple helpers

Additional Information:
When returning an empty object {} inside routeToState when doing History-Back

  • the URL get’s updated to “without params” (https://my-app.com/products)
  • the UiState get’s changed
    But as you can imagine, to none facets/filters selected.

Can someone please help me, getting the history-routing running?

Versions
NuxtJS: 2.14.1
VueInstantSearch: 3.6.0

If someone wants to join the discussion: