Description
Combine vuex-router-sync
and store.replaceState(window.__INITIAL_STATE__)
cause an issue when an URL contain hash like : /guide/data.html#server-data-fetching
.
The route object in initial state does not have the hash because it's not provided over http.
So the hash is removed during the sync() from vuex-router-sync if sync()
is setup before replaceState()
. Like that :
index.js
export default function createApp() {
// some code
sync(store, router);
// some code
}
entry-client.js
import createApp from './index';
const { app, router, store } = createApp();
store.replaceState(window.__INITIAL_STATE__);
I have two solutions for now :
Solution 1 : Move sync() call after replaceState()
Actually, in my project structure the sync is made in a common file named index.js
.
Both entry-client and entry-server import it.
We can fix the issue if we move the sync after the replace and remove it from index.js
:
entry-client.js
store.replaceState(window.__INITIAL_STATE__);
sync(store, router);
entry-server.js
// some code
sync(store, router);
Pros : no initial state overriding, no extra code
Cons : duplicate sync()
call entry-client.js and entry-server.js
Solution 2 : Add hash to initial state before replaceState()
const initialState = window.__INITIAL_STATE__;
if (initialState) {
const hash = window.location.hash;
if (hash && initialState.route) {
initialState.route.hash = hash;
}
store.replaceState(initialState);
}
Pros : Avoid duplicate code (sync() remains in one place)
Cons : Manually override initial state
Solution 3*
Change the initial sync in vuex-router-sync ? (seems bad)
Conclusion :
It's not an issue by definition, but i want your opinion on this subject.
I don't like the solution 2, i think it's more a trick than a solution. But i don't know if solution 1 has side-effects, due to move the sync after Vue application creation.