diff --git a/packages/nuxt/src/app/entry.ts b/packages/nuxt/src/app/entry.ts index f6a69e82e9..0220465b16 100644 --- a/packages/nuxt/src/app/entry.ts +++ b/packages/nuxt/src/app/entry.ts @@ -9,6 +9,8 @@ import '#build/css' import _plugins from '#build/plugins' // @ts-ignore import RootComponent from '#build/root-component.mjs' +// @ts-ignore +import { appRootId } from '#build/nuxt.config.mjs' if (!globalThis.$fetch) { // @ts-ignore @@ -64,7 +66,7 @@ if (process.client) { try { await nuxt.hooks.callHook('app:created', vueApp) await nuxt.hooks.callHook('app:beforeMount', vueApp) - vueApp.mount('#__nuxt') + vueApp.mount('#' + appRootId) await nuxt.hooks.callHook('app:mounted', vueApp) await nextTick() } catch (err) { diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 4bcf34cde7..c075a3efce 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -33,7 +33,9 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { handlers: nuxt.options.serverHandlers, devHandlers: [], baseURL: nuxt.options.app.baseURL, - virtual: {}, + virtual: { + '#internal/nuxt.config.mjs': () => nuxt.vfs['#build/nuxt.config'] + }, routeRules: { '/__nuxt_error': { cache: false } }, diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 51a6a12ce9..ca596b3e88 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -8,7 +8,8 @@ import { renderToString as _renderToString } from 'vue/server-renderer' import { useRuntimeConfig, useNitroApp, defineRenderHandler, getRouteRules } from '#internal/nitro' // eslint-disable-next-line import/no-restricted-paths import type { NuxtApp, NuxtSSRContext } from '#app' - +// @ts-ignore +import { appRootId, appRootTag } from '#internal/nuxt.config.mjs' // @ts-ignore import { buildAssetsURL, publicAssetsURL } from '#paths' @@ -71,7 +72,7 @@ const getSSRRenderer = lazyCachedFunction(async () => { if (process.dev && process.env.NUXT_VITE_NODE_OPTIONS) { renderer.rendererContext.updateManifest(await getClientManifest()) } - return `
${html}
` + return `<${appRootTag} id="${appRootId}">${html}` } return renderer @@ -83,7 +84,7 @@ const getSPARenderer = lazyCachedFunction(async () => { const options = { manifest, - renderToString: () => '
', + renderToString: () => `<${appRootTag} id="${appRootId}">`, buildAssetsURL } // Create SPA renderer and cache the result for all requests diff --git a/packages/schema/src/config/app.ts b/packages/schema/src/config/app.ts index 30a7edf39e..2ab2e6e431 100644 --- a/packages/schema/src/config/app.ts +++ b/packages/schema/src/config/app.ts @@ -143,6 +143,17 @@ export default defineUntypedSchema({ * @type {typeof import('../src/types/config').NuxtAppConfig['keepalive']} */ keepalive: false, + + /** + * Customize Nuxt root element id. + */ + rootId: '__nuxt', + + /** + * Customize Nuxt root element tag. + * + */ + rootTag: 'div', }, /**