diff --git a/packages/nuxt/src/pages/build.d.ts b/packages/nuxt/src/pages/build.d.ts index afcc67773f..a1ac9afa37 100644 --- a/packages/nuxt/src/pages/build.d.ts +++ b/packages/nuxt/src/pages/build.d.ts @@ -5,3 +5,13 @@ declare module '#build/router.options' { const _default: RouterOptions export default _default } + +declare module '#build/routes' { + import type { RouterOptions } from '@nuxt/schema' + import type { Router, RouterOptions as VueRouterOptions } from 'vue-router' + + export const handleHotUpdate: (_router: Router, _generateRoutes: RouterOptions['routes']) => void + + const _default: VueRouterOptions['routes'] + export default _default +} diff --git a/packages/nuxt/src/pages/module.ts b/packages/nuxt/src/pages/module.ts index 44e7f527cc..b5b7d1b0ac 100644 --- a/packages/nuxt/src/pages/module.ts +++ b/packages/nuxt/src/pages/module.ts @@ -631,22 +631,32 @@ const ROUTES_HMR_CODE = /* js */` if (import.meta.hot) { import.meta.hot.accept((mod) => { const router = import.meta.hot.data.router - if (!router) { + const generateRoutes = import.meta.hot.data.generateRoutes + if (!router || !generateRoutes) { import.meta.hot.invalidate('[nuxt] Cannot replace routes because there is no active router. Reloading.') return } router.clearRoutes() - for (const route of mod.default || mod) { - router.addRoute(route) + const routes = generateRoutes(mod.default || mod) + function addRoutes (routes) { + for (const route of routes) { + router.addRoute(route) + } + router.replace('') + } + if (routes && 'then' in routes) { + routes.then(addRoutes) + } else { + addRoutes(routes) } - router.replace('') }) } -export function handleHotUpdate(_router) { +export function handleHotUpdate(_router, _generateRoutes) { if (import.meta.hot) { import.meta.hot.data ||= {} import.meta.hot.data.router = _router + import.meta.hot.data.generateRoutes = _generateRoutes } } ` diff --git a/packages/nuxt/src/pages/runtime/plugins/prerender.server.ts b/packages/nuxt/src/pages/runtime/plugins/prerender.server.ts index 1c6dcc3765..e1d2bb01da 100644 --- a/packages/nuxt/src/pages/runtime/plugins/prerender.server.ts +++ b/packages/nuxt/src/pages/runtime/plugins/prerender.server.ts @@ -5,7 +5,6 @@ import defu from 'defu' import { defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt' import { prerenderRoutes } from '#app/composables/ssr' -// @ts-expect-error virtual file import _routes from '#build/routes' import routerOptions, { hashMode } from '#build/router.options' // @ts-expect-error virtual file @@ -39,7 +38,7 @@ function shouldPrerender (path: string) { return !_routeRulesMatcher || defu({} as Record, ..._routeRulesMatcher.matchAll(path).reverse()).prerender } -function processRoutes (routes: RouteRecordRaw[], currentPath = '/', routesToPrerender = new Set()) { +function processRoutes (routes: readonly RouteRecordRaw[], currentPath = '/', routesToPrerender = new Set()) { for (const route of routes) { // Add root of optional dynamic paths and catchalls if (OPTIONAL_PARAM_RE.test(route.path) && !route.children?.length && shouldPrerender(currentPath)) { diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index 0b3f3de8c8..f2d604fd19 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -17,7 +17,6 @@ import { navigateTo } from '#app/composables/router' // @ts-expect-error virtual file import { appManifest as isAppManifestEnabled } from '#build/nuxt.config.mjs' -// @ts-expect-error virtual file import _routes, { handleHotUpdate } from '#build/routes' import routerOptions, { hashMode } from '#build/router.options' // @ts-expect-error virtual file @@ -88,7 +87,7 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ routes, }) - handleHotUpdate(router) + handleHotUpdate(router, routerOptions.routes ? routerOptions.routes : routes => routes) if (import.meta.client && 'scrollRestoration' in window.history) { window.history.scrollRestoration = 'auto'