Skip to content

Upgrading nuxt 2 to 3

Breaking2.18.1 → 3.21.11Breaking86Security52Platform5Deprecated14New527Changed429Fixed1810Other2215

BreakingUpgrade verdict

67 breaking changes and 5 platform requirement changes and 43 security fixes.

  • Removes the obsolete `shortPath` property.
  • The internal list of registered components is no longer attached to the server-side rendering context.
  • The internal middleware name changed, so code referring to the old name must be updated.
  • Removes the defineModel option as it is now stable.
Top 5 of 128 that need code or config changes

No longer runs postinstall when installed.

Requires Node.js ^20.19.0 || >=22.12.0 from 3.18.0 (none stated before).

Adds @dxup/nuxt ^0.5.6, @nuxt/devtools ^3.4.1, @nuxt/kit 3.21.11, @nuxt/nitro-server 3.21.11, @nuxt/schema 3.21.11, @nuxt/vite-builder 3.21.11, @unhead/vue ^2.1.17, @vue/shared ^3.5.40, c12 ^3.3.4, chokidar ^5.0.0, compatx ^0.2.0, consola ^3.4.2, cookie-es ^2.0.1, defu ^6.1.7, destr ^2.0.5, devalue ^5.9.0, errx ^0.1.2, escape-string-regexp ^5.0.0, exsolve ^1.1.1, h3 ^1.15.11, hookable ^5.5.3, ignore ^7.0.6, impound ^1.1.6, jiti ^2.7.0, klona ^2.0.6, knitwork ^1.3.0, magic-string ^0.30.21, mlly ^1.8.2, nanotar ^0.3.0, nypm ^0.6.9, ofetch ^1.5.1, ohash ^2.0.11, on-change ^6.0.2, oxc-minify ^0.143.0, oxc-parser ^0.143.0, oxc-transform ^0.143.0, oxc-walker ^1.1.1, pathe ^2.0.3, perfect-debounce ^2.1.0, pkg-types ^2.3.1, rou3 ^0.9.1, scule ^1.3.0, semver ^7.8.5, std-env ^4.2.0, tinyglobby ^0.2.17, ufo ^1.6.4, ultrahtml ^1.7.0, uncrypto ^0.1.3, unctx ^2.5.0, unimport ^6.4.0, unplugin ^3.3.0, unplugin-vue-router ^0.19.2, untyped ^2.0.0, vue ^3.5.40, vue-router ^4.6.4.

Drops @nuxt/babel-preset-app, @nuxt/builder, @nuxt/components, @nuxt/config, @nuxt/core, @nuxt/generator, @nuxt/loading-screen, @nuxt/opencollective, @nuxt/server, @nuxt/utils, @nuxt/vue-app, @nuxt/vue-renderer, @nuxt/webpack.

Installs 698 packages in all (was 1296).

Breaking67
Removes the obsolete shortPath property.
shortPath
Removes _registeredComponents from ssrContext.
_registeredComponentsssrContext
Renames nuxtMiddleware to appMiddleware.
nuxtMiddlewareappMiddleware
Removes the defineModel option as it is now stable.
defineModel
Enables verbatimModuleSyntax by default, so type imports must use an explicit type import.
verbatimModuleSyntax
Removes legacy support for build.extend in webpack.
build.extend
Removes default any types in RuntimeConfig, PageMeta, NuxtApp['payload'] and ModuleMeta, which may require type updates.
RuntimeConfigPageMetaNuxtApp['payload']NuxtPayloadModuleMeta
Removes the #head alias.
#head
Removes the initialCache option.
initialCache
Removes support for the 404.vue shorthand.
404.vue
Removes support for the module container in kit.
Removes deprecated APIs including PrivateRuntimeConfig, autoImports, addAutoImport, defer, throwError, useActiveRoute, <Script>, <NuxtNestedPage>, <NuxtChild>, buildModules, and…
PrivateRuntimeConfigautoImportsaddAutoImportaddImportsaddImportsDiruseAsyncDatainstallModulethrowError
Removes deprecated API.
Uses strict TypeScript mode by default.
Restricts the viewport and charset shortcuts to nuxt.config only; they can no longer be used directly within useHead.
viewportcharsetuseHeadnuxt.config
Makes refresh override previous requests by default.
refresh
Renames autoImports to imports.
autoImportsimports
Removes unused meta:register hook in nuxt.
meta:register
Removes null handling for titleTemplate.
titleTemplate
Removes the legacy app context.
Renames the package from nuxt3 to nuxt, so defineNuxtConfig must be imported from 'nuxt' instead of 'nuxt3'.
defineNuxtConfignuxtnuxt3
Updates Vue TypeScript augmentation to target vue instead of @vue/runtime-core, which can break types for libraries that have not updated.
@vue/runtime-coreComponentCustomPropertiesComponentCustomOptionsGlobalComponents
Removes the experimental.treeshakeClientOnly option, enabled by default since v3.0.0.
experimental.treeshakeClientOnly
Removes the experimental.configSchema option, enabled by default since v3.3.0.
experimental.configSchema
Removes the experimental.polyfillVueUseHead option, disabled since v3.4.0 and implementable in user-land with a plugin.
experimental.polyfillVueUseHead
Removes the experimental.respectNoSSRHeader option, disabled since v3.4.0 and implementable in user-land with server middleware.
experimental.respectNoSSRHeader
Removes some experimental options for v4 in schema.
Throws an error if setInterval is used on the server.
setInterval
Removes the experimental reactivityTransform option for Vue 3.4.
reactivityTransform
Scans layouts in subfolders of ~/layouts, naming them with dash-separated paths, which changes layout names.
~/layouts
Requires route rules to use isr instead of swr for incremental static regeneration on Vercel and Netlify.
routeRulesswrisr
Disables the undocumented x-nuxt-no-ssr header by default; re-enable with experimental.respectNoSSRHeader or set event.context.nuxt.noSSR.
x-nuxt-no-ssrexperimental.respectNoSSRHeaderevent.context.nuxt.noSSR
Removes the deprecated #head alias and disables the @vueuse/head polyfill by default; re-enable with experimental.polyfillVueUseHead.
#head@vueuse/headexperimental.polyfillVueUseHead
Removes the deprecated experimental.viteNode option; configure it with vite.devBundler instead.
experimental.viteNodevite.devBundler
Drops support for internal deprecated utilities using CJS resolve patterns as part of moving toward PnP and pnpm support without --shamefully-hoist.
Updates the fork-ts-checker-webpack-plugin dependency to v8, a breaking change.
fork-ts-checker-webpack-plugin
Adds the $f fetch prefix only to auto-generated keys.
$f
Enables payload extraction only for nuxi generate.
nuxi generate
Includes request url and params in the useFetch key.
useFetch
Fixes typo for NuxtRenderHTMLContext.bodyPrepend.
NuxtRenderHTMLContext.bodyPrepend
Moves head option support into defineNuxtComponent.
headdefineNuxtComponent
Only adds the $f fetch prefix to auto-keys.
$f
Uses a parser to generate page metadata.
Disables app.pageTransition and app.layoutTransition by default in the schema.
app.pageTransitionapp.layoutTransition
Uses a parser to generate page metadata, changing generated metadata behavior.
Requires defineEventHandler() or eventHandler(); Node.js middleware with (req, res, next?) syntax must be wrapped with fromNodeMiddleware().
defineEventHandler()eventHandler()fromNodeMiddleware()
Adds NuxtPage to the #components alias.
NuxtPage#components
Uses the component loader to add meta components, a breaking change.
Switches template init to giget, so cloning third-party GitHub repos now requires the gh: prefix.
nuxi initnuxt init
Uses giget 0.1x with template registry for nuxi init.
nuxi init
Handles prerelease constraint in kit.
Allows app:rendered to modify the SSR context and adds a new render:html hook.
app:renderedrender:html
Upgrades to Vite v3, which may require updating Vite-related configuration and plugins.
vite
Only scans the top level of the composables/ directory, with glob support.
composables/
Adds support for the components/global directory.
components/global
Changes the statusCode type to number for the error page template.
statusCode
Unwraps auto imports in SFC templates, changing how auto-imported refs behave in templates.
Supports universal global middleware, changing how global middleware runs.
Unwraps auto imports in SFC templates.
Supports global middleware without the router.
Explicitly allows optional params with [[, requiring [slug] at the end of a route to be rewritten as [[slug]].
[slug][[slug]]
Module authors using module-builder must update the @nuxt/kit dependency to ^3.0.0-rc.1.
@nuxt/kit
Static server components rely on the richer JSON payload format, so experimental.renderJsonPayloads must not be false.
experimental.renderJsonPayloads
Sets up Nuxt globally with nuxt test.
nuxt test
Uses the vitest/node subpath export in test-utils.
vitest/node
Updates vitest args in test-utils.
Cleans up the schema and splits Nuxt 2 types.
Security43
Fixes server-side RCE and unauthorized component instantiation via server island props.
Fixes a route rule authorization bypass.
Fixes a server component denial of service.
Fixes dev server path disclosure.
Refreshing the lockfile pulls in @nuxt/devtools@3.3.1, which fixes a critical development-only RCE.
@nuxt/devtools
Upgrading for the earlier route rule advisory is not enough; this release fixes a regression from that fix.
Requires a loopback peer for the chrome devtools workspace endpoint.
Bounds island props and v-for to prevent unauthenticated DoS.
v-for
Nuxt: Server-Side Remote Code Execution via Runtime Template Injection in Nuxt Server Island Props
templateruntimeCompilerHigh · CVSS 8.1
Rejects the top-level as prop for islands.
as
Nuxt: Unauthenticated CPU exhaustion parsing and hashing the Nuxt island endpoint body before hash validation
High · CVSS 7.5
Nuxt dev server discloses project root and workspace UUID via the Chrome DevTools workspace endpoint
Moderate
Nuxt: Unauthenticated out-of-memory crash via unbounded v-for expansion in island rendering
High · CVSS 7.5
Nuxt: Unauthorized Component Instantiation via Server Island Props
Moderate · CVSS 4.8
Nuxt route rules silently dropped for mixed-case paths, bypassing appMiddleware auth gates (incomplete fix for CVE-2026-53721)
High · CVSS 8.2
Prevents sibling-directory traversal in the test component wrapper.
Nuxt: URL-handling weaknesses in navigateTo and reloadNuxtApp: SSR open redirect, client-side script execution via the open option, and protocol-relative bypass in reloadNuxtApp
isScriptProtocolnavigateToreloadNuxtAppModerate · CVSS 6.1
Rejects prototype-chain keys in the island registry.
Gates the chrome devtools workspace endpoint to local requests in nitro.
Escapes props in <NuxtClientFallback> SSR output.
NuxtClientFallback
Requires a loopback host when same-origin signals are missing in rspack and webpack.
Cross-site scripting via <NoScript> slot content in Nuxt's head components
NoScriptLow
Rejects cross-origin paths in reloadNuxtApp.
reloadNuxtApp
Nuxt dev server vite-node IPC socket is world-connectable on Linux
vite-nodeModerate · CVSS 5.5
Rejects script-capable protocols in <NuxtLink> href.
NuxtLink
Nuxt: Route-rule middleware bypass via case-sensitivity mismatch between vue-router and the routeRules matcher
High
Nuxt: Reflected XSS in <NuxtLink> via unsanitised javascript: or data: URL
Moderate
Nuxt: Reflected XSS in navigateTo() external redirect
Moderate · CVSS 5.4
Nuxt: __nuxt_island endpoint does not bind responses to request props, enabling shared-cache poisoning
Low · CVSS 5.4
Nuxt's route middleware is not enforced when rendering .server.vue pages via /__nuxt_island/page_*
Moderate · CVSS 5.3
Nuxt: Route rules are matched against the raw request path, so a percent-encoded segment can bypass appMiddleware on dynamic and catch-all routes
Moderate · CVSS 6.5
Nuxt has Client-Side Path Traversal in Nuxt Island Payload Revival
Low · CVSS 3.1
Nuxt allows DOS via cache poisoning with payload rendering response
High · CVSS 7.5
Disallows cross-site requests in no-cors mode for webpack.
Restricts dev server CORS to local origins and allows configuration via devServer.cors.
devServer.cors
Nuxt vulnerable to remote code execution via the browser when running the test locally
Critical · CVSS 8.8
nuxt vulnerable to Cross-site Scripting in navigateTo if used after SSR
Moderate · CVSS 6.3
Disallows redirects to more script protocols.
Applies security best practices to CI workflows.
Pins more CI action dependencies to hashes.
nuxt Code Injection vulnerability
Critical · CVSS 8.1
Suggests adding the path to vite.server.fs.allow in nuxt.config if the Vite service allow list error occurs.
vite.server.fs.allownuxt.config
Recommends upgrading to the latest version as soon as possible.
Platform5
Updates to Nitro v2.7, which uses native fetch and cuts production bundle size by about 40%, recommending Node 18 or later.
fetch
Supports vitest 0.30.0 as a peer dependency.
vitest
Adds @types/node as a peerDependency.
@types/node
Adds support for Node.js 19 in the package build.
Downgrades the Node.js requirement from ^16.11.0 to ^16.10.0.
Deprecated13
Deprecates createError statusCode and statusMessage in favor of status and statusText, ahead of v5.
createErrorstatusCodestatusMessagestatusstatusText
Deprecates ImportPresetWithDeprecation in kit, nuxt and schema.
ImportPresetWithDeprecation
Deprecates the extend, extendConfig, and configResolved hooks in schema.
extendextendConfigconfigResolved
Deprecates process.* flags.
process.*
Deprecates the pending value in data fetching composables.
pending
Deprecates boolean values for the dedupe option.
dedupe
Explicitly deprecates the build.extend hook, which will be removed in a future minor version.
build.extend
Warns when using the deprecated build.extend hook in webpack.
build.extend
Deprecates accessing public runtime config without the public key; removal planned for v3.5.
publicruntimeConfig
Deprecates the old pre-rc runtimeConfig.
runtimeConfig
Deprecates scanning directory index plugins.
Deprecates the <Script> component tag in templates.
<Script>
Deprecates the autoImports option and hooks, renamed to imports.
autoImportsimports