Repository: nuxt/nuxt
File: packages/nuxt/src/pages/runtime/plugins/router.ts (TypeScript)

Code before:
      history,
      routes
    })
    nuxtApp.vueApp.use(router)

    const previousRoute = shallowRef(router.currentRoute.value)
    router.afterEach((_to, from) => {
      previousRoute.value = from
    })

    Object.defineProperty(nuxtApp.vueApp.config.globalProperties, 'previousRoute', {
      get: () => previousRoute.value
    })

    // Allows suspending the route object until page navigation completes
    const _route = shallowRef(router.resolve(initialURL) as RouteLocation)
    const syncCurrentRoute = () => { _route.value = router.currentRoute.value }
    nuxtApp.hook('page:finish', syncCurrentRoute)
    router.afterEach((to, from) => {
      // We won't trigger suspense if the component is reused between routes
      // so we need to update the route manually
      if (to.matched[0]?.components?.default === from.matched[0]?.components?.default) {
        syncCurrentRoute()
      } else {
        // assign toValue to avoid reactivity
        Object.assign(toValue(_route), router.currentRoute.value) 
      }
    })

    // https://github.com/vuejs/router/blob/main/packages/router/src/router.ts#L1225-L1233
    const route = {} as RouteLocation
    for (const key in _route.value) {
      Object.defineProperty(route, key, {
        get: () => _route.value[key as keyof RouteLocation]
      })
    }

    nuxtApp._route = shallowReactive(route)

    nuxtApp._middleware = nuxtApp._middleware || {
      global: [],
      named: {}
    }

    const error = useError()

    try {
      if (import.meta.server) {
        await router.push(initialURL)
      }


Review comment (bug):
I'm not sure this is the correct fix (but do tell me what you're thinking as I could be wrong here). This is omitted initially as the suspense resolution _should_ update the route (and I think we always want it to be reactive).

(Would also be nice to include a regression test.)

Code after:
      },
      history,
      routes,
    })

    if (import.meta.hot) {
      handleHotUpdate(router, routerOptions.routes ? routerOptions.routes : routes => routes)
    }

    if (import.meta.client && 'scrollRestoration' in window.history) {
      window.history.scrollRestoration = 'auto'
    }
    nuxtApp.vueApp.use(router)

    const previousRoute = shallowRef(router.currentRoute.value)
    router.afterEach((_to, from) => {
      previousRoute.value = from
    })

    Object.defineProperty(nuxtApp.vueApp.config.globalProperties, 'previousRoute', {
      get: () => previousRoute.value,
    })

    const initialURL = import.meta.server
      ? nuxtApp.ssrContext!.url
      : createCurrentLocation(routerBase, window.location, nuxtApp.payload.path)

    // Allows suspending the route object until page navigation completes
    const _route = shallowRef(router.currentRoute.value)
    const syncCurrentRoute = () => { _route.value = router.currentRoute.value }
    nuxtApp.hook('page:finish', syncCurrentRoute)
    router.afterEach((to, from) => {
      // We won't trigger suspense if the component is reused between routes
      // so we need to update the route manually
      if (to.matched[0]?.components?.default === from.matched[0]?.components?.default) {
        syncCurrentRoute()
      }
    })

    // https://github.com/vuejs/router/blob/8487c3e18882a0883e464a0f25fb28fa50eeda38/packages/router/src/router.ts#L1283-L1289
    const route = {} as RouteLocationNormalizedLoaded
    for (const key in _route.value) {
      Object.defineProperty(route, key, {
        get: () => _route.value[key as keyof RouteLocation],
        enumerable: true,
      })
    }

    nuxtApp._route = shallowReactive(route)

    nuxtApp._middleware ||= {