@nuxt/eslint module setup
The recommended approach for Nuxt is to enable ESLint support using the @nuxt/eslint module, which sets up project-aware ESLint configuration. The module is designed for the new ESLint flat config format, which is the default format since ESLint v9.
Legacy ESLint config with @nuxt/eslint-config
If using the legacy .eslintrc config format instead of the new ESLint flat config format, manual configuration with @nuxt/eslint-config is required. Migration to the flat config format is recommended to be future-proof.
Extend tsconfig.shared.json from module
To extend tsconfig.shared.json from a module, modify nuxt.options.typescript.sharedTsConfig.include: nuxt.options.typescript.sharedTsConfig.include ??= []; nuxt.options.typescript.sharedTsConfig.include.push(resolve('./augments.d.ts'));
Extend tsconfig.server.json from module
To extend tsconfig.server.json from a module, modify nuxt.options.typescript.serverTsConfig.include: nuxt.options.typescript.serverTsConfig.include ??= []; nuxt.options.typescript.serverTsConfig.include.push(resolve('./augments.d.ts'));
compatibilityVersion example configuration
Example configuration for compatibilityVersion in nuxt.config.ts:
```ts
export default defineNuxtConfig({
future: {
compatibilityVersion: 5,
},
})
```
noScripts feature values and behavior
The noScripts feature controls rendering of Nuxt scripts and JavaScript resource hints. Possible values are: false (default, scripts rendered normally), 'production' (or true, normalized to 'production', scripts omitted in production builds only), and 'all' (scripts omitted in both development and production). When noScripts applies, the following are omitted from HTML: Nuxt entry script tags, import map for entry chunk, inlined payload script and preload link, and JavaScript resource hints (preload and prefetch links for JS chunks). CSS remains unaffected.
noScripts route rule example configuration
Example of per-route noScripts configuration in nuxt.config.ts:
```ts
export default defineNuxtConfig({
routeRules: {
'/blog/**': { noScripts: true },
},
})
```
noScripts speculation rules and navigation behavior
When pages ship without scripts via noScripts, Nuxt emits a speculation rules tag (declarative JSON that executes no JavaScript) to allow supporting browsers to prefetch and prerender targets before the user follows a link. The rules are scoped to page routes rather than every same-origin link, so links to server routes like /logout are never speculatively fetched. Client-side navigation to a noScripts route triggers a full document load instead of client-side router rendering.
noScripts route rule per-route configuration
Scripts can be disabled per-route using the noScripts route rule, which applies in all modes. Configure it under routeRules in nuxt.config.ts, for example: routeRules: { '/blog/**': { noScripts: true } }.
noScripts interaction with server components and islands
Routes with the noScripts route rule are always rendered with the buffered (non-streaming) renderer. Server components that only render static HTML work fine, but components hydrated with nuxt-client and interactive island slots rely on an inline script to relocate teleported content, so they will not become interactive on a noScripts route. When features.noScripts is set app-wide and component islands are active, Nuxt falls back to buffered rendering.
devLogs feature - stream server logs to client
The devLogs feature streams server logs to the client during development. These logs can be handled in the dev:ssr-logs hook. By default, this is enabled in development when test mode is not active. If set to 'silent', the logs will not be printed to the browser console. It is configured in nuxt.config.ts under features.devLogs.
inlineStyles feature configuration
The inlineStyles feature inlines styles when rendering HTML, currently available only when using Vite. It can be set to a boolean or a function that receives the path of a Vue component and returns a boolean indicating whether to inline the styles for that component. It defaults to (id) => id.includes('.vue'). Configure it under features.inlineStyles in nuxt.config.ts.
multiApp example configuration
Example configuration for multiApp in nuxt.config.ts:
```ts
export default defineNuxtConfig({
future: {
multiApp: true,
},
})
```
typescriptBundlerResolution example configuration
Example configuration for typescriptBundlerResolution in nuxt.config.ts:
```ts
export default defineNuxtConfig({
future: {
typescriptBundlerResolution: false,
},
})
```
multiApp experimental feature
The multiApp feature enables early access to experimental multi-app support in Nuxt. Configure it under future.multiApp in nuxt.config.ts by setting it to true. Progress can be followed in tracker issue #21635.
noScripts example configuration
Example configuration for noScripts in nuxt.config.ts:
```ts
export default defineNuxtConfig({
features: {
noScripts: 'production', // or 'all' | false
},
})
```
devLogs example configuration
Example configuration for devLogs in nuxt.config.ts:
```ts
export default defineNuxtConfig({
features: {
devLogs: true,
},
})
```
inlineStyles example configuration
Example configuration for inlineStyles in nuxt.config.ts:
```ts
export default defineNuxtConfig({
features: {
inlineStyles: false, // or a function to determine inlining
},
})
```
typescriptBundlerResolution feature for TypeScript module resolution
The typescriptBundlerResolution feature enables 'Bundler' module resolution mode for TypeScript, which is the recommended setting for frameworks like Nuxt and Vite. It improves type support when using modern libraries with exports. It defaults to true (Bundler mode). Set it to false in future.typescriptBundlerResolution to use the legacy 'Node' mode, which is the default TypeScript behavior.
compatibilityVersion feature for Nuxt v5 opt-in
Setting compatibilityVersion to 5 in the future namespace changes defaults throughout Nuxt configuration to opt in to Nuxt v5 behaviour, including enabling the Vite Environment API. Configure it under future.compatibilityVersion in nuxt.config.ts.
Enable Nitro with Nuxt Bridge configuration
To activate Nitro in a Nuxt 2 application with Nuxt Bridge, set the bridge.nitro configuration option to true in nuxt.config.ts. The configuration is: bridge: { nitro: true }.
typedPages experimental flag
The typedPages flag enables the new experimental typed router. Out of the box, this enables typed usage of navigateTo, NuxtLink, router.push() and more. You can get typed params within a page by using const route = useRoute('route-name'). Enable it by setting experimental.typedPages to true in nuxt.config.ts.
strictRouteTypes experimental flag
The strictRouteTypes flag controls whether Nuxt rejects requests to paths that no server route answers. It can be set to false (default, unknown paths typed as unknown), true (only routes reported by server builder accepted), or 'isomorphic' (as true, but pages included as GET routes returning string). Configure it via experimental.strictRouteTypes in nuxt.config.ts. With the option on, typos and unsupported methods are errors. Absolute URLs and runtime-built paths remain accepted.
watcher experimental flag
The watcher flag sets an alternative watcher for Nuxt's file watching service. It can be set to 'chokidar-granular' (default, ignores top-level excluded directories like node_modules), 'chokidar' (watch all files), 'parcel' (use @parcel/watcher for performance on large projects or Windows), or 'builder' (reuse active builder's watcher). Set to 'builder' via experimental.watcher in nuxt.config.ts to reduce file watchers in dev mode.
sharedPrerenderData experimental flag
The sharedPrerenderData flag controls whether Nuxt automatically shares payload data between pages that are prerendered. This can result in significant performance improvements for sites using useAsyncData or useFetch with the same data in different pages. This flag is enabled by default. It is important when enabling this feature to ensure that any unique key of data is always resolvable to the same data. Disable it by setting experimental.sharedPrerenderData to false in nuxt.config.ts.
clientNodeCompat experimental flag
The clientNodeCompat flag enables automatic polyfilling of Node.js imports in the client build using unenv. To make globals like Buffer work in the browser, you need to manually inject them. Enable it by setting experimental.clientNodeCompat to true in nuxt.config.ts.
scanPageMeta experimental flag
The scanPageMeta flag exposes route metadata defined in definePageMeta at build-time to modules, specifically alias, name, path, redirect, props, and middleware. This only works with static values or strings/arrays rather than variables or conditional assignment. Page metadata is scanned after all routes are registered in pages:extend hook, then pages:resolved hook is called. This flag is enabled by default. Disable it by setting experimental.scanPageMeta to false in nuxt.config.ts if it causes issues.
cookieStore experimental flag
The cookieStore flag enables CookieStore support to listen for cookie updates (if supported by the browser) and refresh useCookie ref values. This flag is enabled by default. Disable it by setting experimental.cookieStore to false in nuxt.config.ts.
buildCache experimental flag
The buildCache flag caches Nuxt build artifacts based on a hash of the configuration and source files. This only works for source files within srcDir and serverDir for the Vue/Nitro parts. Changes to .nuxtrc, .npmrc, package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, tsconfig.json, bun.lock, or bun.lockb trigger a full rebuild. Changes to files within srcDir trigger a rebuild of the Vue client/server bundle. A maximum of 10 cache tarballs are kept. This flag is disabled by default. Enable it by setting experimental.buildCache to true in nuxt.config.ts.
checkOutdatedBuildInterval experimental flag
The checkOutdatedBuildInterval flag sets the time interval in milliseconds to check for new builds. It is disabled when experimental.appManifest is false. Set to false to disable completely. Configure it via experimental.checkOutdatedBuildInterval in nuxt.config.ts. Default example is 3600000 (1 hour).
extraPageMetaExtractionKeys experimental flag
The extraPageMetaExtractionKeys flag allows passing additional keys to extract from page metadata when using scanPageMeta. By default Nuxt only reads a fixed list of definePageMeta() keys. This option extends that list to allow modules to access additional metadata from page metadata in the build context. Configure it by passing an array of key names via experimental.extraPageMetaExtractionKeys in nuxt.config.ts.
extractSerializablePageMeta experimental flag
The extractSerializablePageMeta flag enables Nuxt to write every JSON-serializable property from definePageMeta() straight into the generated route record instead of reading only fixed keys at build time. This is enabled by default when future.compatibilityVersion is 5 or higher. When every property can be resolved statically, the route no longer imports that page's meta module, removing one module per page from the dev module graph. Properties that cannot be serialized (functions, variable references, spreads, computed keys) are still resolved at runtime. This flag has no effect when scanPageMeta is false. Configure it via experimental.extractSerializablePageMeta in nuxt.config.ts.
navigationRepaint experimental flag
The navigationRepaint flag waits for a single animation frame before navigation, giving the browser an opportunity to repaint and acknowledge user interaction. It can reduce INP when navigating on prerendered routes. This flag is enabled by default. Disable it by setting experimental.navigationRepaint to false in nuxt.config.ts.
navigateToEarlyReturn experimental flag
The navigateToEarlyReturn flag transforms top-level await navigateTo() calls in <script setup> into an early return from the compiled setup() function when navigation succeeds. Without this flag, code after await navigateTo() continues to run. With this flag enabled, successful navigation stops execution of the rest of setup code and the component renders a placeholder comment. This flag is enabled by default with compatibilityVersion 5. The transform only applies to top-level await navigateTo() statements in <script setup> whose result is not used. The early return only happens when navigation succeeds; if navigation is aborted or fails, the rest of setup code continues. Configure it via experimental.navigateToEarlyReturn in nuxt.config.ts.
normalizeComponentNames experimental flag
The normalizeComponentNames flag updates auto-generated Vue component names to match the full component name used for auto-importing the component. By default Vue assigns a component name matching the component filename. With this flag enabled, the component name matches the Nuxt pattern for component naming (e.g. SomeFolderMyComponent for components/SomeFolder/MyComponent.vue). Disable it by setting experimental.normalizeComponentNames to false in nuxt.config.ts if issues occur.
normalizePageNames experimental flag
The normalizePageNames flag ensures that page component names match their route names by setting the __name property on page components. This enables Vue's <KeepAlive> to correctly identify pages by name. By default Vue assigns component names based on filename, so multiple pages can share the same name. With this flag enabled, page components are named after their route, allowing <KeepAlive> with include/exclude without manually adding defineOptions({ name: '...' }). This flag is enabled by default when future.compatibilityVersion is 5 or higher. Configure it via experimental.normalizePageNames in nuxt.config.ts.
spaLoadingTemplateLocation experimental flag
The spaLoadingTemplateLocation flag controls where the loading screen template (from ~/spa-loading-template.html) is rendered for client-only pages (ssr: false). Set to 'within' (default) to render inside the __nuxt div, or to 'body' to render alongside the Nuxt app root. Rendering to 'body' avoids a white flash when hydrating a client-only page. Configure it via experimental.spaLoadingTemplateLocation in nuxt.config.ts.
browserDevtoolsTiming experimental flag
The browserDevtoolsTiming flag enables performance markers for Nuxt hooks in browser devtools. This adds performance markers that can be tracked in the Performance tab of Chromium-based browsers, useful for debugging and optimizing performance. This is enabled by default in development mode. Disable it by setting experimental.browserDevtoolsTiming to false in nuxt.config.ts if needed.
debugModuleMutation experimental flag
The debugModuleMutation flag records mutations to nuxt.options in module context, helping to debug configuration changes made by modules during Nuxt initialization. This is enabled by default when debug mode is enabled. Enable it explicitly by setting experimental.debugModuleMutation to true in nuxt.config.ts.
lazyHydration experimental flag
The lazyHydration flag enables hydration strategies for <Lazy> components, improving performance by deferring component hydration until needed. Lazy hydration is enabled by default. Disable it by setting experimental.lazyHydration to false in nuxt.config.ts.
templateImportResolution experimental flag
The templateImportResolution flag disables resolving imports into Nuxt templates from the path of the module that added the template. By default Nuxt attempts to resolve imports in templates relative to the module that added them. Setting this to false disables this behavior, which may be useful if experiencing resolution conflicts. This flag is enabled by default. Disable it by setting experimental.templateImportResolution to false in nuxt.config.ts.
templateRouteInjection experimental flag
The templateRouteInjection flag controls whether a mixin is injected to keep the $route template object in sync with Nuxt's managed useRoute(). By default the route object returned by auto-imported useRoute() is kept in sync with the current page in <NuxtPage>, but $route is not. Enabling this injects a mixin to keep $route in sync. This flag is enabled by default. Disable it by setting experimental.templateRouteInjection to false in nuxt.config.ts.
decorators experimental flag
The decorators flag enables decorator syntax across your entire Nuxt/Nitro app. When using Vite builder, decorators are lowered via Babel using @babel/plugin-proposal-decorators. When using webpack or rspack builders, decorators are lowered via esbuild. This enables support for TC39 proposal decorators (not TypeScript's experimentalDecorators). When using Vite builder or Nitro server build, install @babel/plugin-proposal-decorators and @babel/plugin-syntax-jsx as dev dependencies. Configure it via experimental.decorators in nuxt.config.ts.
defaults experimental flag
The defaults flag allows specifying default options for core Nuxt components and composables. These options will likely be moved elsewhere in the future, such as into app.config. It can contain options for nuxtLink (componentName, prefetch, prefetchOn), useAsyncData (deep), and useState (resetOnClear). The useState.resetOnClear option controls whether clearNuxtState resets state to its initial value instead of undefined, defaulting to true with compatibilityVersion 5. Configure it via experimental.defaults in nuxt.config.ts.
prefetchPreloadTags experimental flag
The prefetchPreloadTags flag forwards <link rel="preload"> hints from prefetched routes into the current document. When a NuxtLink is prefetched and the destination route has payload extraction enabled (default for prerendered and cached routes), preload hints set via useHead are forwarded. Forwarded links are downgraded from rel="preload" to rel="prefetch", except for as="image" hints which keep rel="preload" with fetchpriority stripped. Only user-defined head tags are forwarded; build-time JS/CSS preloads are handled separately. This flag is off by default. Enable it by setting experimental.prefetchPreloadTags to true in nuxt.config.ts.
granularCachedData experimental flag
The granularCachedData flag controls whether getCachedData is called and its result used when refreshing data for useAsyncData and useFetch (whether by watch, refreshNuxtData(), or manual refresh() call). This flag is enabled by default. Disable it by setting experimental.granularCachedData to false in nuxt.config.ts.
stripNeverHydratedData experimental flag
The stripNeverHydratedData flag applies serialize: false by default to useAsyncData and useFetch calls made within components lazily hydrated with hydrate-never, keeping their data out of the __NUXT_DATA__ payload. Since these components never hydrate on the client, their data is not needed for hydration. An explicit serialize option always takes precedence. Enable it by setting experimental.stripNeverHydratedData to true in nuxt.config.ts.
headNext experimental flag
The headNext flag enables head optimisations: adds capo.js head plugin for more performant head tag rendering, and uses the hash hydration plugin to reduce initial hydration. This flag is enabled by default. Disable it by setting experimental.headNext to false in nuxt.config.ts.
pendingWhenIdle experimental flag
The pendingWhenIdle flag controls the pending ref returned by useAsyncData and useFetch. When false (default), pending is true while a request is in flight (status === 'pending') and false while idle. When true, pending is also true when status is 'idle' and no cached data is available. Use status when your loading UI needs to distinguish idle from in-flight requests. Configure it via experimental.pendingWhenIdle in nuxt.config.ts.
entryImportMap experimental flag
The entryImportMap flag controls whether Nuxt improves chunk stability using an import map to resolve the entry chunk of the bundle. By default this injects an import map at the top of the <head> tag with imports for '#entry'. This means changes to the entry do not invalidate otherwise unchanged chunks. Nuxt smartly disables this if vite.build.target includes a browser not supporting import maps or if vite.build.rolldownOptions.output.entryFileNames is configured to a value not including [hash]. Disable it by setting experimental.entryImportMap to false in nuxt.config.ts.
typescriptPlugin experimental flag
The typescriptPlugin flag enables enhanced TypeScript developer experience with the @dxup/nuxt module. This experimental plugin provides improved TypeScript integration and development tooling for better DX when working with TypeScript in Nuxt applications. This flag is disabled by default. To use this feature, typescript must be installed as a dependency and VS Code must be configured to use workspace TypeScript version. Enable it by setting experimental.typescriptPlugin to true in nuxt.config.ts.
ssrStreaming experimental flag
The ssrStreaming flag enables SSR streaming to improve Time to First Byte (TTFB). When enabled, the server sends the HTML shell (including <head>, styles, preload hints, entry scripts) immediately, then streams body content progressively using Vue's renderToWebStream. Streaming is automatically disabled for bot and crawler user agents to ensure search engines receive fully-rendered HTML. Customize which user agents are opted out with botRegex. Streaming can be controlled per-route using routeRules with streaming: false. Enable it by setting experimental.ssrStreaming to true in nuxt.config.ts, or to an object with botRegex configuration.
ssrStreaming streaming behavior details
SSR streaming commits response status and headers as soon as shell is flushed, incompatible with features that mutate response after render. Requests matching routeRules setting noScripts, cache, isr, swr, redirect, or streaming: false, ssr: false routes, bot/crawler user agents, prerendered routes, server-side navigateTo redirects, or fatal render errors are not streamed and use buffered renderer. Response mutations from plugins reach client but mutations from component rendering (after await in middleware/setup) are dropped. In development, warnings name dropped mutations and route. Stream errors after status committed set payload.error and emit closing tags so client picks up error during hydration. Route styles are streamed, JS hints entry-only. Component islands compatible with streaming via inert templates relocated before hydration.
ssrStreaming module hooks
Modules participate in streaming via render:route hook (fires once per request before rendering, read ctx.canStream to see if streaming possible, set ctx.prefersStream = false to force buffered rendering), render:html hook (fires before shell flushes with streaming: true flag, mutations to htmlAttrs, head, bodyAttrs, bodyPrepend reach wire, mutations to body/bodyAppend dropped with dev warning), render:html:chunk hook (fires for each chunk before enqueued, mutate ctx.chunk Uint8Array to transform bytes, read ctx.index to identify first chunk), and render:html:close hook (fires after body stream completes, mutate ctx.bodyAppend string[] to inject final markup).
ssrStreaming CSP nonce handling
Streaming renderer emits several inline scripts and styles that bypass unhead: bootstrap queue, IIFE, suspense head pushes, island-teleport relocation, and route <style> blocks. If a nonce is present on rendered head scripts, the renderer reuses it on all of them automatically, so strict script-src/style-src 'nonce-…' policy does not block streaming. A module only needs to put the nonce on head scripts; the render:html:chunk hook remains available for stamping scripts that components render into body.
ssrStreaming FOUC for SFC styles
In development with streaming, Vite serves SFC <style> blocks as JavaScript modules that inject styles client-side after module evaluation, with no corresponding <link> in shell. Browser starts painting streamed DOM before style-injection modules run, causing brief unstyled flash. Workaround: put paint-critical styles in global CSS file registered via css: ['~/assets/main.css']. Global CSS files emitted as <link rel="stylesheet"> in shell <head> and apply before body content streams. SFC <style> blocks fine for component-scoped styling. Production builds extract all styles to CSS files, so FOUC only affects nuxt dev. Validate streaming visuals against nuxt build && nuxt preview.
ssrStreaming FOUC for nested async components
Renderer inlines route CSS in chunk sent after shell. Can only inline styles for components whose modules already registered: page, layout, async components directly inside Suspense boundary. Async component inside another async component instantiated only once parent resolves, after first chunk streamed. Its SFC <style> misses post-shell styles chunk and emitted in closing HTML, behind component DOM. Browser paints component unstyled until final chunk arrives. Avoid by keeping paint-critical styling out of nested async components: put styles gating initial paint in global CSS file, use utility classes (Tailwind, UnoCSS), keep async components with paint-critical <style> directly under Suspense boundary, or opt route out of streaming.
Experimental features defined in @nuxt/schema
Nuxt uses @nuxt/schema to define experimental features. Reference the API documentation at /docs/4.x/guide/going-further/experimental-features or the source code at https://github.com/nuxt/nuxt/blob/main/packages/schema/src/config/experimental.ts for more information. These features are experimental and could be removed or modified in the future.
purgeCachedData experimental flag
The purgeCachedData flag controls whether to clean up Nuxt static and asyncData caches on route navigation. Nuxt automatically purges cached data from useAsyncData and nuxtApp.static.data, helping prevent memory leaks and ensuring fresh data is loaded when needed. This flag is enabled by default. Disable it by setting experimental.purgeCachedData to false in nuxt.config.ts.
alwaysRunFetchOnKeyChange experimental flag
The alwaysRunFetchOnKeyChange flag controls whether useFetch runs when the key changes, even if immediate is false and it has not been triggered yet. useFetch and useAsyncData will always run when the key changes if immediate is true or if it has already been triggered. This flag is disabled by default. Enable it by setting experimental.alwaysRunFetchOnKeyChange to true in nuxt.config.ts.