Vue Router history.state becomes null inside my app

Vue Router history.state becomes null inside my app

I am using Vue Routers to get a single page application like Nextcloud app.

Environment:

  • Nextcloud: 34 (dev)
  • App: structureddiary
  • Frontend: Vue 3 + Pinia + Vue Router
  • Vue Router: 5.0.6
  • @nextcloud/vue: 9.6.0
  • Browser: Firefox 140 on Linux
  • App URL example: http://nextcloud.local/index.php/apps/structureddiary/diaries
  • Dev setup: Vite dev server loaded through the Nextcloud app page

Problem:

During normal Vue Router navigation, I get this warning:

[Vue Router warn]: history.state seems to have been manually replaced without preserving the necessary values. Make sure to preserve existing history state if you are manually calling history.replaceState:

history.replaceState(history.state, '', url)

You can find more information at https://router.vuejs.org/guide/migration/#Usage-of-history-state chunk-6HLBDYD6.js:3715:16

I did

  • search for Migrating from Vue 2 | Vue Router for any suggestions fitting my code, but found nothing. There is no history.replaceState call (or any call to history at all, except for what I added for the next point.)
  • Immediately after Vue Router’s pushState, history.state is valid (as far as I can see).
{
  back: "/diaries",
  current: "/entries",
  forward: null,
  replaced: false,
  position: 50,
  scroll: null
  }
  • I found that history.state is fine until it leaves my code. (To be precise until the debugger hits the onClickOutside I associate with the next event (that I caused by I controlling the debugger), )
  • I added a spy wrapper to both history.pushState and history.replaceState, but all hits are calls from vue-router and before and after the call history.state was fine.
  • I did not observe an obvious full-page navigation, but I cannot ruled out a Nextcloud page lifecycle/navigation side effect.

Temporary workaround:
I added a router guard that keeps a backup of the last valid history.state and restores it if required.

Questions:

  • Has anyone seen history.state become null in a Nextcloud app page after Vue Router has written a valid state?
  • Does Nextcloud’s app shell, navigation handling, CSP, or page lifecycle code reset browser history state?
  • Should Nextcloud apps avoid using Vue Router (> 4.0)?

PS: I did some digging into the decks app, but it uses Vue Router 3.6.5, which is as of now 4 years old, so I did not want to use it in a new app.

https://github.com/search?q=org%3Anextcloud+%2Fvue-router\"%3A+\"\^5.0%2F&type=code

Well, sounds like the story of the forest and the trees.

Anyway, thanks a lot. I try to debug it with some of these and post my findings when I make progress.

OK, long story short:

HMR breaks with Nextcloud the history Vue-Router uses.

So when building the app whole and disabling the HMR it works. Should have tried that earlier.

Thanks for the help.