Toolkit for authoring modules and interacting with Nuxt
Last release 22 days ago
05 Aug 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 55 of the last 60 stable releases
12 versions withdrawn
withdrawn after publishing
5 years old
151 releases · first in 2021
Release timeline
151 releases since 2021Releases
- 4.5.25 Aug 2026
Release notes
Open source →4.5.2 is the next patch release.
👉 Changelog
🔥 Performance
- nuxt,kit: Skip rewriting unchanged generated files (#35902)
- kit,nuxt: Use lazy imports to improve parsing speed (#35901)
- vite: Skip html entry probes in bare-import resolver (#35907)
- nuxt: Reuse app and component scans for unchanged structures (#35912)
🩹 Fixes
- vite: Resolve client manifest path from resolved config (#35883)
- nuxt: Use client-side navigation for links inside islands (#35806)
- nuxt: Generate types for route params defined with definePageMeta (#35857)
- nuxt: Serialize island payloads for components with underscores in keys (#35807)
- nitro: Dedupe island renders when prerendering (#35835)
- nuxt: Drop prefetch hints for never-hydrated chunks (#35812)
- vite: Use same asset filenames for worker builds (#35866)
- nitro: Reject non-object island props (#35867)
- nuxt: Support options api in
v-forislands transform (#35877) - nuxt: Improve page meta extraction + performance (#35869)
- nuxt: Set build outputs when restoring vue cache (#35895)
- kit: Honour nested
applyandapplyToEnvironmentin vite wrapper (#35899) - nuxt: Re-check for preview mode after prerendered page hydration (#35886)
- kit,nuxt,vite: Handle missed chokidar watch events (#35887)
- nuxt: Settle asyncData status when bailing (#35908)
- kit: Clone resolved config with klona rather than klona/full (#35914)
- kit: Honour nested plugins'
enforcein vite wrapper (#35916) - nuxt: Collect build cache once build outputs are final (#35929)
- vite: Resolve vite env api sourcemaps in
vite-node(#35758) - nuxt: Don't warn about missing
<NuxtPage>on nav + with slot (#35948) - kit: Prepend vite environment wrapper plugin when
prependis set (#35942) - nuxt: Depend on rolldown as a peer to reuse vite's copy (3fda97f60)
- nitro: Define
import.meta.testfor server code (#35987) - nuxt: Match route rules against decoded paths (9123ed850)
💅 Refactors
- nuxt: Use
vue-component-type-helpersinstead of locally maintained helpers (#35840) - nuxt: Use
isReferenceIdentifierin page-meta plugin (#35882)
📖 Documentation
- Sync mcp server page with live tools and providers (#35856)
- Add server components guide and mostly-static site recipe (#35778)
- Minor changes (#33479)
- Add accessible routing guide (#34796)
- Update testing guide to test-utils v4.1.0 (#35873)
- Update .env provider reference from dotenv to c12 (#35911)
- Add note to avoid using
defineVitestProjectin e2e tests (#35926) - Update roadmap (f6e6027fe)
📦 Build
- ui-templates: Copy generated templates from resolved output dir (#35921)
🏡 Chore
- nuxt: Bump
@nuxt/devtoolsto v3.4.0 (#35892) - Fix lint (1951a2489)
- Throw error with cause in script (a90608d5c)
- Lint notification script 🤦 (429a96b24)
- Ignore safe pull_request_target (035a3a3d4)
- Reorder ignore (3baf6fedd)
- Bump nuxt rolldown peer dep to match unctx (2c38086f5)
✅ Tests
- Skip webpack dev tests for island v-for transform (73030e55a)
- Add regression test for #35893 (#35893)
- vite: Cover windows drive letters in
toFsUrl(a5ad667f7)
🤖 CI
- Shard the critical-path test jobs and cache playwright (#35832)
- Add action to notify issues resolved on release (5fffe5718)
- Make notification script more resilient (5337bd357)
- Do not comment on issues in other repos (400dfdc11)
- Add explicit
permissions: {}to workflows (2e1a1cbeb) - Rebalance windows e2e matrix (dffe13742)
- Let contributors know prs are backported (3e416c54f)
- Regenerate templates in autofix job (95d33637f)
❤️ Contributors
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Aubakirov Asker (@Askerka00)
- Yoshihiro Yamaguchi (@yamachi4416)
- Samuel Burkhard (@samydoesit)
- Kenneth Sills (@Kenneth-Sills)
- Spunkie (@Spunkie)
- Bochkarev Ivan (@Ibochkarev)
- Amulet Iris (@KazariAI)
- Yash Bavadiya (@xevrion)
- Alexander Lichter (@TheAlexLichter)
- Mehraz Morshed (@mehrazmorshed)
- mcrapts (@mcrapts)
- Benjamin Canac (@benjamincanac)
- Anthony Fu (@antfu)
- 4.5.127 Jul 2026
Release notes
Open source →⚠️ This is a security release. We recommend upgrading as soon as possible with
npx nuxt upgrade --dedupe.It fixes server-side RCE and unauthorized component instantiation via server island props, a route rule authorization bypass, server component DoS, cross-user payload disclosure on cached pages, and dev server path disclosure. Refreshing your lockfile also pulls in
@nuxt/[email protected], which fixes a separate critical development-only RCE.If you already upgraded for the earlier route rule advisory (CVE-2026-53721), you still need this release: one of the fixes addresses a regression introduced by that fix.
If you use the
cache,swrorisrroute rules, purge any CDN or edge cache after upgrading; a leaked_payload.jsonmay already be cached upstream.Full details: Nuxt Security Patch Releases and GitHub Security Advisories.
👉 Changelog
🔥 Performance
- nitro: Replace island teleports in a single html pass (#35515)
- nuxt: Add
vue.optionsApiand disable it for v5+ (#35791) - nuxt: Without pages, skip client plugins that require routing (#35794)
- nuxt: Skip payload revival plugin when
ssr: false(#35782)
🩹 Fixes
- nitro: Read rspack dev output fs lazily for server entry (#35740)
- rspack,webpack: Resolve loaders and runtime deps from nuxt dirs (#35568)
- nuxt: Return global route for
useRoutein detached effect scope (#35659) - nuxt: Ignore custom
nameorpathwhen reusing an existing page inpages:extend(#35661) - nuxt: Render client components in nested server components (#35669)
- nuxt: Preserve explicit
useFetchmethod inference (#35671) - nuxt: Revalidate cached route payloads instead of using
force-cache(#35672) - nuxt: Correct default export detection in plugin metadata (#35676)
- nuxt: Clear hide/reset timeouts in set() (#35534)
- kit,nuxt,rspack,schema,webpack: Add
.mtsfile extension in resolver (#33845) - nuxt: Preserve trailing slash in NuxtLink href when unset (#35501)
- nuxt: Don't cross-pollute useAsyncData cache on reactive key change (#35656)
- nuxt: Filter plugin dependencies by build target (#35682)
- nuxt: Reload real page module on HMR of JSX render-function pages (#35678)
- nuxt: Resolve
@unhead/vue/*from nuxt's dependency tree (#35690) - kit: Surface module load errors instead of masking as missing (#35497)
- nuxt: Type auto-imported
$fetchwith nitro's$Fetch(#35704) - nuxt: Don't reference app config sources in shared and node tsconfigs (#35673)
- vite: Resolve SSR inlined CSS module class name mismatch (#35610)
- nuxt: Generate layout types even when pages module is disabled (#35717)
- nitro: Skip resource hints for stylesheets already rendered as blocking links (#35691)
- kit: Dedupe layers that are both auto-scanned and explicitly extended (#35712)
- nuxt: Don't apply scroll behaviour after a subsequent nav (#35719)
- vite: Ensure server sourcemap-preserver plugin actually runs (#35680)
- vite: Preserve css suffix when extracting ssr inline styles (#35714)
- nuxt: Watch external component directories in development (#35652)
- nuxt: Don't exclude client entry module from style extraction (#35720)
- nuxt: Amend cleanup command in NUXT_B7014 error message (#35735)
- nuxt: Only pull in
vue-routerwhen there are island pages (#35739) - vite: Suppress external warnings for internal vite-node paths (#35744)
- nuxt: Use scope-aware oxc parser for auto-imports (#35743)
- nuxt: Sync layout meta during middleware on SSR (#35633)
- nitro: Add alias for
h3that pins it to the version nuxt depends on (#35774) - nuxt: Preserve query params in cached payload extraction (#35696)
- nuxt: Mirror runtime route tree in generated typed-router types (#35788)
- nuxt: Warn when an imports preset
fromcannot be resolved (#35799) - kit: Avoid mutating layer configs when resolving options (#35729)
- nuxt: Convert inline route rules exactly or drop with a warning (#35455)
- nitro,nuxt,vite: Dedupe and normalise global css links in dev (#35834)
- vite: Register template HMR plugin on dev servers (929c6c138)
- nuxt: Remove dev error overlay when error is cleared (#35821)
- rspack,webpack: Resolve bundled postcss defaults from builder (#35823)
- schema: Normalise slashes in
app.buildAssetsDir(#35833) - nitro: Bound island props and v-for to prevent unauthenticated DoS (4e35ae9ba)
- nitro: Confine runtime payload cache to prerendering (ac9b41a36)
- nuxt: Case-fold route rule keys to match folded lookups (ad624a75a)
- nitro: Require loopback peer for chrome devtools workspace endpoint (0769c4f9b)
- nuxt: Reject reserved
templateisland prop under runtime compiler (ee6c84633) - nuxt: Reject top-level
asprop for islands (581651ff3)
💅 Refactors
- nuxt: Use tick based debounce for asyncData executes (#34151)
- kit,nuxt: Replace
semverwithverkit(#35713) - rspack,webpack: Use DI model to split builders (#35751)
📖 Documentation
- Add dev container setup guide (#35665)
- Fix dev container setup guide (#35666)
- Add explanation of 200.html and 404.html SPA fallbacks (#34483)
- Expand payload extraction documentation (#35648)
- Clarify NuxtLink componentName is the internal (devtools) name (#35658)
- Add example for components dir pattern option (#35663)
- Require a single root element (#35677)
- Add reason for why you should never import Vue app code in nitro code (#34481)
- Document disabling code-splitting with
codeSplitting: false(#35683) - Document nuxt-client caveat for non-SFC components (#35654)
- Clarify favicon does not use cdnURL by default (#35681)
- Standardize section order and headings across docs (#35685)
- Clarify
onPrehydrateexample comment (#35684) - Add useId as a known limitation of nuxt island (#35693)
- Recommend status over pending in data fetching (#35694)
- Fill gaps in API minimalVersion badges after #34485 (#35708, #34485)
- Explain dynamic asset paths (#35695)
- Document
runtimeConfigenv var casting edge cases (#35709) - Clarify module dependency resolution (#35718)
- Add more writing guidelines (#35662)
- Add note with alternatives to using remote layers (#35721)
- Use
nuxtrather thannuxi(8891e179c) - Document relative baseURL workarounds (#34004)
- Warn about
runtimeCompilersecurity best practices (449b63ab1) - Warn about validating server component props (2c981cb07)
📦 Build
- nitro: Re-export type from augments to preserve module (dac937675)
- nuxt: Remove
.tsfile extension fromruntime/imports (#35689) - ui-templates: Commit generated ui template files (#35770)
🏡 Chore
- Add extension 🤦 (d595fb3d4)
- Move to pnpm catalogs (#35748)
- Update knip config, resolve issues, and run in ci (#35742)
- Ignore
@nuxt/telemetryin knip (9824d4f10) - ui-templates: Pass config file path to unocss (34e7a810d)
- Allow regenerating lockfile in release script (c31389df3)
- nuxt: Bump
@nuxt/devtoolsto v3.3.1 (#35815) - Ensure types are setup before unit tests (784d8f700)
- Simplify knip configuration (#35827)
✅ Tests
- Reproduce duplicate CSS in shared chunks (#35649)
- Prepare fixtures automatically before fixture and e2e runs (e8b3e6411)
- Improve and refactor basic fixture (#35687)
- Slim down client-only, chunk-error and axis-independent suites (#35706)
- Do not run type checking when benchmarking nuxt build (6355f3bc9)
- kit: Scope loadNuxt temp dir so it doesn't delete sibling fixtures (37301dd51)
- Guard against transient undefined
_routein gotoPath (ca92d082b) - Retry fixture prepare on transient ENOTEMPTY (3a6b59f96)
- Raise route-HMR polling timeout to reduce e2e flakiness (01dc27b7e)
- Update bundle size snapshot (30d24817c)
🤖 CI
- Rebalance shards and drop non-vite windows fixtures (#35700)
- Warm windows dependency cache on main (#35730)
- Run knip in default and production modes (#35745)
- Run knip on pull requests (d620aa972)
- Prepare tests (c7bf7f738)
- Also prepare tests in
knipjob (58f68bd64) - Check internal docs links on pull requests and all links weekly (#35767)
❤️ Contributors
- Daniel Roe (@danielroe)
- Lars Kappert (@webpro)
- Matej Černý (@cernymatej)
- Anthony Fu (@antfu)
- Harlan Wilton (@harlan-zw)
- Florian Heuberger (@Flo0806)
- Anoesj Sadraee (@Anoesj)
- Ryota Watanabe (@wattanx)
- Alexander Lichter (@TheAlexLichter)
- Nestor Vera (@hacknug)
- Mateleo (@Mateleo)
- Kevin Deng (@sxzz)
- Robin (@OrbisK)
- Bochkarev Ivan (@Ibochkarev)
- Quentin Macq (@quentinmcq)
- Julien Huang (@huang-julien)
- Max (@onmax)
- Luke Nelson (@luc122c)
- Darlan José Batista do Prado (@DarlanPrado)
- kealan (@KealanAU)
- Sushant (@sushantguri)
- raminjafary (@raminjafary)
- Aubakirov Asker (@Askerka00)
- lutejka (@lutejka)
- Amulet Iris (@KazariAI)
- bdbch (@bdbch)
- Elecmonkey (@elecmonkey)
- 4.5.018 Jul 2026
Release notes
Open source →4.5.0 is the next minor release.
📣 Some News
Preparing for Nuxt 5
A good chunk of this release is (hopefully) invisible plumbing for Nuxt 5. We've moved onto the latest major versions of several core dependencies (
unheadv3,unctxv3, and Vite 8), switched the framework's own build over totsdown, and introduced a stablenuxt/*build output contract with dev exports so that type-checking in the Nuxt monorepo works without a build step (#35463, #35605).Much of this is working to shrink the gap between v4 and v5 internally, so that the migration will be as boring as possible.
[!TIP] If you want to test some of the breaking changes of Nuxt v5, you can already opt in with
future.compatibilityVersion: 5. Keep an eye on the Upgrade Guide for details as they land.With the release of Nuxt v4.5, our focus as a team will turn to stabilising Nuxt v5 and creating compatibility utilities to make the upgrade as smooth as possible.
Nuxt 3 End-of-Life
Nuxt 3 reaches end-of-life on July 31, 2026, so this is one of the last few 3.x releases we'll ship. If you're still on v3, now is a great time to move across. Most people told us the v3 to v4 upgrade was smooth, and we've kept the upgrade guide up to date.
Alongside v4.5.0 we're publishing a maintenance patch for the 3.x line (v3.21.9) with the compatible bug fixes and smaller improvements from this release backported. The headline items here (Vite 8, Rspack 2,
unheadv3,unctxv3) are major upgrades and stay v4-only, so 3.x remains stable as it approaches end-of-life.👀 Highlights
Nuxt 4.5 is a big one. This release ships three major upgrades to the build layer (Vite 8, Rspack 2, and a brand new Rsbuild-powered pipeline for the Rspack builder), an experimental SSR streaming mode, a handful of new composables and conventions, and a lot of groundwork that brings us closer to Nuxt 5.
There's a lot here, so grab a coffee. ☕️
⚡️ Vite 8
Nuxt now runs on Vite 8 (#34256). This brings faster cold starts, the latest Rolldown-powered internals, and many upstream improvements from the Vite team.
For most apps this is a transparent upgrade. If you have custom Vite plugins or config, it's worth skimming the Vite migration guide to check for anything that affects you.
[!WARNING] Vite 8 is a major version bump. If you depend on Vite directly (custom plugins,
vite.configtweaks, or ecosystem plugins that pin a Vite version), make sure those are compatible before upgrading in production.🦀 Rspack 2 and Rsbuild
If you use the Rspack builder, this release is a substantial upgrade. We've moved to Rspack 2 (#34929), which is faster and lighter, and rebuilt the builder on top of
@rsbuild/core(#35489).The public surface stays the same. You still opt in with
builder: 'rspack'and the existingrspack:*hooks continue to work:// nuxt.config.ts export default defineNuxtConfig({ builder: 'rspack', })Under the hood, though, a lot has changed for the better:
- The dev server now runs in middleware mode via Rsbuild, replacing
webpack-dev-middlewareandwebpack-hot-middleware(#35575). - We use an Rspack-specific Vue loader for correct SSR scoped-style ids and stricter ESM resolution (#35566).
[!NOTE] This is the foundation for first-class Rsbuild support. We kept the builder named
rspackfor now so nothing breaks, but the internals are now Rsbuild all the way down.🌊 Experimental SSR Streaming
This is one I'm particularly excited about. You can now enable SSR streaming to dramatically improve Time to First Byte (#34411). Instead of buffering the whole rendered page and sending it in one go, Nuxt flushes the HTML shell (your
<head>, styles, preload hints, and entry scripts) immediately, then streams the body as Vue renders it.// nuxt.config.ts export default defineNuxtConfig({ experimental: { ssrStreaming: true, }, })Streaming is automatically disabled for bots and crawlers so search engines still receive fully-rendered HTML. You can tune which user agents count as crawlers, and you can opt individual routes out:
// nuxt.config.ts export default defineNuxtConfig({ experimental: { ssrStreaming: { botRegex: /googlebot|bingbot|my-internal-crawler/i, }, }, routeRules: { '/no-stream/**': { streaming: false }, }, })There's one thing worth understanding before you turn it on. Because streaming commits the HTTP status and headers with the very first byte, anything that mutates the response after rendering has begun (a
setResponseStatus()in a<script setup>, a cookie write during middleware, and so on) can't reach the client. Nuxt handles the common cases for you: routes withredirect,cache,isr,swr,noScripts, orssr: falserules automatically fall back to the buffered renderer, and in development we log a warning naming any dropped mutations so nothing fails silently.[!WARNING] SSR streaming is experimental and off by default. It could be great for content-heavy routes where TTFB matters, but test it against your app's response-mutating logic (status codes, headers, cookies) before shipping it widely. The experimental features docs cover the fallback rules and caveats in detail.
🩺 Stable Error Codes
This one I'm really happy about. Nuxt now has a stable error code system (#35429). Warnings and errors raised during build and at runtime now carry a stable code (like
NUXT_E1001orNUXT_B5001), a short explanation of why it happened, and a concrete fix to try.Every code is greppable and bookmarkable, and the ones that need more than a one-line fix link straight to a dedicated docs page. For example, the classic "a composable was called outside a Nuxt context" now surfaces as
NUXT_E1001with the why/fix inline and a docs page explaining the context rules and how to userunWithContext().To keep production output lean, the verbose why/fix text is stripped from production builds, leaving just the stable code.
This is the foundation for much better error messages across Nuxt, and we'll keep migrating existing warnings and errors onto it over the coming releases. If you've ever squinted at a cryptic Nuxt message, this is for you.
🎨
useLayoutComposableThere's a new
useLayoutcomposable for reading the layout that's been resolved for the current route (#35623). Previously there was no clean, reactive way to ask "which layout is this page using?" from within a component.<!-- app/components/LayoutBadge.vue --> <script setup lang="ts"> const layout = useLayout() </script> <template> <span>Current layout: {{ layout }}</span> </template>It returns a read-only computed ref, so it stays in sync as you navigate or as route rules and
definePageMetachange the resolved layout.🪟 Named Views
Nuxt now supports named views through a filename convention (#35123). If a parent page renders more than one
<NuxtPage>outlet, you can give each outlet a name and provide a sibling page file for it using the[email protected]convention:# Directory Structure -| pages/ ---| parent/ -----| child.vue -----| [email protected] ---| parent.vue<!-- pages/parent.vue --> <template> <div> <NuxtPage /> <aside> <NuxtPage name="sidebar" /> </aside> </div> </template>Navigating to
/parent/childrenderschild.vueinto the default outlet and[email protected]into thesidebaroutlet. This has actually been possible in Vue Router for a long time; this release wires it up to Nuxt's file-based routing.[!NOTE]
definePageMetais read from the default route file only, and per-view rendering modes aren't supported (the parent page's mode applies to the default view).🚦
enabledOption foruseFetchanduseAsyncDataYou can now gate data fetching with a reactive
enabledoption (#33260). Whileenabledisfalse, every execution is blocked (the initial fetch,execute/refresh, and watch triggers), and if you flip it fromtruetofalsemid-flight, the in-flight request is cancelled without clearing your existingdata.<script setup lang="ts"> const query = ref('') const { data } = await useFetch('/api/search', { query: { q: query }, // Only fetch once the user has typed something enabled: () => query.value.length > 2, }) </script>This is perfect for dependent or conditional queries, where you don't want to fire a request until some precondition is met. It pairs naturally with a getter or a ref, so it stays reactive.
🔗
NuxtLinkPrefetch Control for Custom SlotsWhen you use
<NuxtLink>with thecustomprop, Nuxt no longer attaches prefetch handlers for you, because it can't know how you've structured your markup. To make that ergonomic, the slot now exposes everything you need to wire prefetching up yourself (#34539):<template> <NuxtLink v-slot="{ href, navigate, prefetch, prefetched, shouldPrefetch }" to="/about" custom > <a :href="href" :class="{ 'is-prefetched': prefetched }" @click="navigate" @pointerenter="shouldPrefetch('interaction') && prefetch()" @focus="shouldPrefetch('interaction') && prefetch()" > About page </a> </NuxtLink> </template>You get
prefetchto trigger it,prefetchedto know whether it's already happened (great for a prefetched class), andshouldPrefetchto respect the user's connection and config.⚡️ Forwarded Preload Hints on Prefetch
Here's another one we'd love you to try. When you prefetch a link to a route with payload extraction, Nuxt already primes the destination's data and chunks. With the new opt-in
experimental.prefetchPreloadTags(#35144), it also forwards the destination's<link rel="preload">andmodulepreloadhints (whatever the page sets viauseHead, or via modules like@nuxt/image's<NuxtImg preload>) into the current document, downgraded torel="prefetch"so they don't compete with the resources the user is looking at right now.// nuxt.config.ts export default defineNuxtConfig({ experimental: { prefetchPreloadTags: true, }, })The practical effect is that heavy above-the-fold assets on the next page (a hero image, a critical script) start downloading while the user is still on the current one, so the navigation feels instant. It's off by default while we gather feedback, so please give it a spin and tell us how it behaves on your app.
🌐
import.meta.envNameThe resolved Nuxt environment name is now available at runtime as
import.meta.envNamefor both Vite and webpack/Rspack builds (#34844). This is the value set by--envName(or the resolved default), so you can branch on it in your app code:if (import.meta.envName === 'staging') { // enable staging-only behaviour }🔭 Tracing Channels for SSR Events
Nuxt now publishes diagnostics-channel traces for its server-side subsystems (#35191). It's unopinionated: we emit
nuxt.render,nuxt.island,nuxt.data, andnuxt.pluginchannels following the untracing naming convention, and you can build OpenTelemetry (or anything else) on top. It works in Node, Deno, Bun, and Cloudflare Workers.// nuxt.config.ts export default defineNuxtConfig({ // Turn on Nuxt's own channels tracingChannel: true, })You can also enable it granularly. In Nuxt v5, there will be additional Nitro-level channels:
// nuxt.config.ts export default defineNuxtConfig({ tracingChannel: { nuxt: true, }, })[!NOTE] Channel names, payload shapes, and option keys may still change while the untracing registry settles.
📦 Dependency Upgrades
unheadv3Nuxt's head management now runs on
unheadv3 (#34793). It's smaller, uses a synchronous engine internally, and ships better type-safety foruseHeadout of the box. This also unblocks SSR streaming.[!WARNING]
unheadv3 introduces type-narrowing foruseHead, which can be a breaking type change if you were relying on the looser v2 types. The runtime behaviour is compatible for the vast majority of apps, and promise input (deprecated in v2) is no longer supported. If you hit type errors after upgrading, they're almost always genuine tightening rather than regressions.unctxv3We've moved to
unctxv3 (#35541), which resolves a class of long-standing async context issues (#33644). This is part of the composable-context reliability work that continues into v5.And more
We've also updated
magic-stringto v1, Babel to v8, and pulled in the latest Rolldown across the board. Runningnuxt upgrade --dedupe(see below) is the easiest way to pull these through cleanly.🛠️ Nuxt CLI
This release bundles some improvements from
@nuxt/cliv3.36 and v3.37:-
nuxt module removeto uninstall a module and clean up its config (nuxt/cli#1306), the natural companion tonuxt module add. -
Non-interactive
nuxt initfor scripting and CI (nuxt/cli#1341), plus it now respects the template's own package manager instead of prompting (nuxt/cli#1330). -
Type-check onboarding:
nuxt typechecknow offers to installvue-tscandtypescriptfor you if they're missing (nuxt/cli#1316). -
Golar support for type-checking:
nuxt typecheckcan now use Golar as an alternative tovue-tsc(nuxt/cli#1362). It's picked up automatically if it's installed (or agolar.config.*file exists), and you can force a checker with--checker=vue-tscor--checker=golar:nuxt typecheck --checker=golar -
Layer-aware dev server: the dev server now reloads on changes to local layer
nuxt.configfiles (nuxt/cli#1345).
🧩 TypeScript Plugin and Named Layout Slots
Nuxt's experimental TypeScript plugin is powered by
@dxup/nuxt, and this release bundles a newer version of it. If you haven't tried it, turning onexperimental.typescriptPlugingives you a set of editor niceties: renaming an auto-imported component updates every usage, plus go-to-definition for glob imports, Nitro routes,definePageMeta,runtimeConfig, and typed route names.New in the bundled version is an opt-in runtime feature: named layout slots (KazariEX/dxup#20). You can write a top-level named-slot template in a page and have it forwarded into the matching named slot of the active layout. That lets a page inject content into its layout's slots, which file-based layouts don't otherwise allow.
Enable it alongside the plugin:
// nuxt.config.ts export default defineNuxtConfig({ experimental: { typescriptPlugin: true, }, dxup: { features: { namedLayoutSlots: true, }, }, })Then a layout can expose named slots:
<!-- layouts/center.vue --> <template> <slot /> <slot name="side" one="one" /> </template>And any page using that layout can fill them:
<!-- pages/about.vue --> <script setup lang="ts"> definePageMeta({ layout: 'center' }) </script> <template> <template #side="{ one }"> This "{{ one }}" comes from the layout slot. </template> <div>About page</div> </template>📖
typescriptPlugindocumentation🔥 Performance and Reliability
As always, a lot of work has gone into making Nuxt faster and steadier.
One you can opt into today is the shared file watcher (#35143). Vite already runs a chokidar-based watcher, so Nuxt can piggy-back on it instead of spinning up a second one, using less memory and fewer file handles. This becomes the default with
compatibilityVersion: 5, but you can turn it on now and let us know how it goes:// nuxt.config.ts export default defineNuxtConfig({ experimental: { watcher: 'builder', }, })There are also some other good performance improvements that don't need to be opted into:
- Faster dev startup: dev-only Nitro and pages work is now deferred and streamlined (#35381, #35383).
- Leaner production builds: the island-renderer chunk is skipped entirely when you use no islands (#35456), and plugin handling is tree-shaken out of prod builds (#35278).
- Improved island hashing: more stable island and key hashing, with
getIslandHashandhashKeynow exposed (#35583). - Concurrency and I/O wins across Kit path resolution and Nitro inline styles (#35511, #35514).
A couple of other nice quality-of-life fixes:
$fetchis now auto-imported in user code, which fixes edge cases with top-level$fetch.createunder Rolldown's output format (#35581).- Nuxt now honours system
HTTP_PROXY/HTTPS_PROXYenvironment variables in the builder environment (#35183). - HMR now works for
defineNuxtComponentin JSX (#35620).
⚠️ Heads-Up Before Upgrading
As mentioned above, this release includes three major dependency bumps. For most apps they're transparent, but they're worth a moment of attention:
- Vite 8: check custom Vite plugins and config against the Vite migration guide.
- Rspack 2: if you use
builder: 'rspack', the internals are now Rsbuild-based, so custom Rspack config may need review. unheadv3: possible breaking type changes from stricteruseHeadtyping.
⬆️ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe # or, if you are staying on the 3.x line npx nuxt@latest upgrade --dedupe --channel=v3This will deduplicate your lockfile and help ensure you pull in updates from the other dependencies Nuxt relies on, particularly across the unjs ecosystem (which matters more than usual this release, given the major bumps).
[!TIP] Check out our upgrade guide if you're upgrading from an older version.
Thank you to all of the many contributors to this release. This was a big one, and it wouldn't happen without you. 💚
👉 Changelog
🚀 Enhancements
- rspack: Upgrade to rspack v2 (#34929)
- nuxt: Migrate to unhead v3 (#34793)
- nuxt: Support named views via filename convention (#35123)
- nuxt: Expose environment name on
import.meta(#34844) - nuxt: Forward destination preload hints on link prefetch (#35144)
- nuxt: Honour http proxy env vars in builder environment (#35183)
- kit: Support
allowImportingTsExtensions(87c214b34) - nitro,nuxt,schema: Add experimental SSR streaming (5f4efe5a5)
- vite: Migrate to Vite 8 (#34256)
- nitro,nuxt: Add support for tracing channels for ssr events (#35191)
- kit,nitro,nuxt,schema,vite,webpack:
nuxt/*build output contract (#35463) - nuxt: Expose
NuxtLinkprefetch props for custom slot (#34539) - rspack: Use rspack-specific Vue loader (a085e8e34)
- rspack: Use rspack-specific Vue loader (#35566)
- nuxt,vite: Attach vite HMR to the shared dev server listener (a8ea0c7e2)
- nuxt: Add
enabledoption to AsyncData (#33260) - rspack: Use rsbuild dev server in middleware mode (#35575)
- nuxt: Expose
getIslandHash+hashKey+ improve hash for keys (#35583) - nuxt: Add
useLayoutcomposable for accessing the resolved route layout (#35623) - nuxt: Support
enabledoption inuseFetch(#35627) - Error code system (#35429)
- nuxt: Require keyed function 'source' with compatibilityVersion 5 (d56662647)
- kit: Order layer aliases before generic root aliases (
~,@) (#35641) - kit: Add
updateAppConfigutil for module authors (#35651) - nuxt: Warn when parent page lacks NuxtPage (#35639)
🔥 Performance
- nuxt,vite: Reuse vite watcher via
experimental.watcher(#35143) - nuxt: Tree-shake unneeded plugin handling from prod builds (#35278)
- nuxt: Defer dev-only nitro startup work (#35381)
- nuxt: Reduce dev pages startup work (#35383)
- vite: Skip unnecessary decorator transforms (#35395)
- nuxt,rspack,vite,webpack: Migrate to
rolldown-string(#35058) - nitro,nuxt,vite: Remove unused dependencies (#34861)
- nuxt: Re-parse transformed file once in tree-shake plugin (#35509)
- nuxt: Index scanned components by name to avoid quadratic lookup (#35510)
- kit: Stat paths directly and probe extensions in parallel (#35511)
- nitro: Load inline style chunks concurrently (#35514)
- nuxt: Skip island-renderer chunk when no islands used (#35456)
🩹 Fixes
- nuxt: Fix explicit return types of factory types (40a80ec7d)
- vite: Do not await
readyevent for vite watcher (6fe539f52) - vite: Invalidate modules for legacy vite server (#35315)
- kit,nuxt: Pass error as
causewhen we re-throw (#35387) - nuxt: Make virtual module IDs stable across hosts (#35317)
- vite: Inline CSS for lazy components imported from
#components(#35215) - nuxt: Validate
<ClientOnly>fallback tag name (#35325) - vite: Extract server page CSS when
inlineStylesis disabled (#35209) - nitro: Include nested layers in nitro transforms (#35327)
- kit: Don't exclude layer module runtime files from app tsconfig (#35326)
- nitro: Export empty styles object with
ssr: false(#35330) - nuxt: Emit auto-import paths as files, not directories (#35333)
- nuxt: Suppress spurious slot warning in
NuxtPageduring nav (#35335) - vite: Preserve backslash separators in windows named pipe path (#35336)
- nuxt: Detach in-flight promise on
useAsyncDatateardown (#35328) - nuxt: Respect per-page keepalive set via
definePageMeta(#34526) - nuxt: Align useFetch error type with runtime (#35346)
- nuxt: Unwrap getter
bodyinuseFetch(#35343) - rspack,webpack: Strip invalid webpack PURE annotations (#35386)
- nuxt: Guard against -1 when unregistering a router hook (#35391)
- nuxt: Clean up load/error listeners in preloadPayload (#35392)
- nuxt: Avoid idle wait when refreshing data after hydration (#35358)
- nuxt: Hash serialized island props (#35356)
- nuxt: Ensure
page:startfinishes beforepage:finishstarts (#35408) - vite: Invalidate lazily-created SSR modules on render (#35410)
- nuxt: Preserve plugin navigation during app boot (#35344)
- vite: Invalidate stale SSR virtual modules on render (#35413)
- nitro: Don't preload JS for lazy-hydrated components (#35342)
- vite: Add extension to vite-node-runner virtual specifier (0bf3f1d5d)
- vite: Invalidate ssr copy of regenerated templates (33a581ce7)
- vite: Set define for
NODE_ENVand__VUE_PROD_DEVTOOLS__(#35444) - vite: Avoid emitted ssr styles file name collisions (#35432)
- nuxt: Avoid syncing route too early when reused page remounts (#35440)
- nuxt: Skip showing route errors for crawlers (#35411)
- nuxt: Keep nested layout on deferred route during suspended layout switch (#35443)
- nuxt: Restore deferred query route before page is mounted (#35442)
- kit,nuxt: Resolve auto-import type paths through shared resolver (#35451)
- nuxt: Make islands hash backwards-compatible (#35452)
- vite: Give ssr its own hmr websocket port on vite 8.1 (#35458)
- nuxt: Auto-import
$fetchwhere possible (#35581) - nuxt: Update unctx to v3 (#35541)
- nitro: Point cache driver at
.mjsruntime output (#35263) - nuxt: Add
head.pushfor client side (#35498) - nitro: Only reload nitro after initial nitro build (30a573733)
- nuxt: Pass nuxt
rootDirto typed-router context (#35565) - nuxt: Type
__nuxt_errormarker onNuxtError(06e976d2e) - kit:
noUncheckedSideEffectImports(v5) + disablelibReplacement(#35548) - nuxt: Node10 compatible subpath exports (a216d732d)
- nuxt: Unwrap module mutation trackers from options after installing (#35574)
- nuxt: Entity-encode redirect body to preserve query separators (#35486)
- rspack,webpack: Use async entry in dev to avoid circular import (#35586)
- nuxt: Tolerate missing dirs in parcel watcher (#35585)
- nuxt: Respect saved scroll position on same-page back navigation from hash (#35608)
- nuxt: Resolve unctx helper to an absolute path for server bundling (#35602)
- nuxt: Apply
unctxtransform marker throughmagic-string(#35618) - schema: Enable HMR for defineNuxtComponent in JSX (#35620)
- nuxt: Evict stale forwarded prefetch hints and fix key mismatch (#35621)
- nuxt: Re-add computeIslandHash for backwards compatibility (353164bb5)
- nitro: Correct nitro runtime config type key (bc3b53add)
- schema: Resolve Vite cache directory from workspace (#35626)
- nitro: Externalise dev SSR entry to avoid slow rollup re-parse (ff42c54a7)
- nuxt: Drop extension on diagnostics import (c699cc0de)
- nitro: Write prerender cache files atomically (#35619)
- nitro: Don't import
node:processin diagnostics (d73b5df6d) - nuxt: Apply latest navigation on concurrent
navigateToin built-in router (#35631) - nuxt: Update client URL to match SSR on fatal middleware error (#35637)
💅 Refactors
- nitro,nuxt: Add explicit return types to runtime files (#35139)
- nuxt: Resolve builder earlier + skip watcher for
nuxt prepare(#35141) - nuxt: Delete cleared keys in
clearNuxtData&clearNuxtState(#35142) - nuxt: Use jiti
fsCacheinstead of deprecatedcache(#35268) - nitro: Use walkResolver instead of deprecated resolveUnrefHeadInput (#35267)
- nuxt: Add type predicates (#35208)
- vite: Type vite-node-runner error data and resolve
#vite-nodetypes from source (#35334) - nuxt: Split head runtime plugin by environment (#35389)
- nuxt: Use
rolldown/utilsinstead of oxc-* dependencies (#34983) - kit,vite,webpack,nitro,schema:
ssrStylesbuild output => lazy code provider (#35601) - nuxt,nitro: Use dev exports for no-build type-checking (#35605)
- rspack: Use
rsbuildto power rspack builder (#35489) - vite: Extract TemplateHMRPlugin from DevServerPlugin (#35579)
📖 Documentation
- Add builder guide (#35576)
- Correct and improve
useAsyncDataanduseFetch(#35528) - Improving testing documentation for better understanding (#35526)
- Fix incorrect transform signature in useAsyncData/useFetch type docs (#35403)
- Add minimal version badges to API documentation (#34485)
- Clarify usage of await with useFetch (#33745)
- Add badges for new features (1839fe01d)
- Remove
enabledfromuseFetchdocs (bf7810600) - Add tip about prerendering registration for pages (#35635)
- Clarify that
useFetchkeys are unique per call site (#35645) - Clarify useFetch custom data error (#35647)
📦 Build
- Use
tsdownto build project (#35179)
🏡 Chore
- Update lockfile (92087005f)
- Handle cleaning nuxt build dist manually (aaafe9879)
- Upgrade oxc/tsdown/rolldown deps together (28173926d)
- Use
vpin nightly release script (97b56d98d) - Update lockfile for tsdown build and dev exports (5d9cd2d67)
- Update bundle size snapshots (b9d353516)
- Allow node version updates (#35297)
- Update bundle size (d37b13b60)
✅ Tests
- Strip host path from server bundle before measuring size (#35316)
- Run playwright tests in dev mode too (#35329)
- nuxt: Benchmark dev
loadNuxtstartup (#35382) - Update bundle size snapshot (64a834281)
- Use h3 v1 syntax in test (1ea2eec07)
- Use
experimental.attachDebugInfo(7c2397ae6) - Update assertions (55f7ea025)
- Pack with pnpm before running attw to honour publishConfig (e2f0dd69d)
- Reduce flakiness on hydration tests (#35457)
- Improve test stability on macos (#35462)
- Force disable
testmode for bundle size tests (#35558) - Pin typescript in basic-types fixture to dedupe vue (a3b824918)
- webpack: Cover Vue loader scope hashes (824daffa0)
- builders: Clean up Vue loader fixtures (ca18affc3)
- Reenable webpack/rspack dev tests (#35571)
- Await
expectNoClientErrors(9f3123f60) - Mark tests as succeeding for rspack/webpack (513ad306e)
- Add support for non-ascii filenames in public assets (#35636)
- Minify server bundles in bundle size snapshot (#35638)
- Run matrix-independent suites once across the fixture matrix (#35646)
- Mark webpack/rspack tests as passing on 4.x (3ae095b29)
🤖 CI
- Reenable bundle size tests 😱 (#35279)
- Only run workflow in nuxt org (#35377)
- Skip entire job, not just step (#35378)
- Error handling for webhook triggers (#35379)
- Update agentscan (#35397)
- Only run benchmark tests in Nuxt org (#35414)
- Don't auto-close team prs 🫣 (cd965f569)
- Use vite-plus to manage pnpm (#35570)
- Use parallel keyword for concurrent workflow steps (#35448)
- Handle missing base branch (for stacked prs) (8d3daa34e)
- Unlink issues from autoclosed PRs (#35615)
❤️ Contributors
- Jordan Labrosse (@Jorgagu)
- Luke Nelson (@luc122c)
- Florian Heuberger (@Flo0806)
- Daniel Roe (@danielroe)
- Yannik Schröder (@yschroe)
- Mateleo (@Mateleo)
- Matej Černý (@cernymatej)
- Eduardo San Martin Morote (@posva)
- Darlan José Batista do Prado (@DarlanPrado)
- Ulrich-Matthias Schäfer (@Fuzzyma)
- Bochkarev Ivan (@Ibochkarev)
- Julien Huang (@huang-julien)
- Damian Głowala (@DamianGlowala)
- KazariAI (@KazariAI)
- Fahad Khan (@oniChan1226)
- skoenfaelt (@skoenfaelt)
- Cynthia Rey (@cyyynthia)
- meomking (@CaptainWang98)
- antlis (@antlis)
- Néstor (@Nsttt)
- Issayah (@VividLemon)
- Alexander Lichter (@TheAlexLichter)
- Anoesj Sadraee (@Anoesj)
- Quentin Macq (@quentinmcq)
- raminjafary (@raminjafary)
- Kurt Medley (@HeavyMedl)
- isksss (@isksss)
- Matteo Gabriele (@MatteoGabriele)
- Max (@onmax)
- Harlan Wilton (@harlan-zw)
- The dev server now runs in middleware mode via Rsbuild, replacing
- 4.4.88 Jun 2026
Release notes
Open source →4.4.8 is a hotfix release to address an issue running the dev server on MacOS.
👉 Changelog
🩹 Fixes
- vite: Shorter socket name for macOs with tmp fallback (#35265)
- kit: Respect
typeoption infindPath(#35272) - deps: Update nuxt/scripts presets (905621594)
- nuxt: Revert unhead dependency back to v2 (e6d578fea)
📖 Documentation
- Fix many typos (#35266)
- Explain static fallback pages (#35277)
- Change
nulltoundefinedin data-fetching docs to match actual types (#35301) - Fix broken internal links, useAsyncData watch type, and NuxtError type (#35303)
❤️ Contributors
- Daniel Roe (@danielroe)
- Ali Mahmmoud (@AliMahmoudDev)
- Quentin Macq (@quentinmcq)
- Pranav Rajeshirke (@Pranav188)
- Eduardo San Martin Morote (@posva)
- 4.4.72 Jun 2026
Release notes
Open source →4.4.7 is a security hotfix release.
👉 make sure to check https://github.com/nuxt/nuxt/security/advisories to view open advisories resolved by this release.
👉 Changelog
🩹 Fixes
- nitro: Assign
noSSRbefore deciding payload extraction (#35108) - vite: Avoid filtering out dirs with shared prefix from
allowDirs(#35112) - nuxt: Use resolve from
pathefor buildCache path boundary check (#35111) - nuxt: Prevent sibling-directory traversal in test component wrapper (#35110)
- nitro: Pass event data to
isValidin dev clipboard-copy listener (#35109) - nuxt: Validate protocols in
reloadNuxtApppath before reload (#35115) - vite: Prefix public asset virtuals with null byte (9e303b438)
- nuxt: Re-run
getCachedDataafter initial fetch (#35122) - nuxt: Propagate
useFetch/useAsyncDatafactory types (#35133) - vite: Close vite dev server on nuxt close (a10a68abc)
- kit,nuxt: Handle cancelling prompts to install packages (e84813229)
- kit: Avoid excluding node-context files in legacy tsconfig (#35152)
- nuxt: Handle missing payload in chunkError listener (#35155)
- nuxt: Await in-lifght template generation when closing nuxt (#35181)
- nuxt: Clarify page and layout usage warnings (#35184)
- webpack: Surface compilation errors when stats.toString is empty (073b07851)
- nuxt: Reject prototype-chain keys in the island registry (#35205)
- nuxt: Apply
isScriptProtocolguard tonavigateToopen option (#35206) - nuxt: Prevent server-only page island from recursing via
<NuxtPage>(#35198) - rspack,webpack: Require loopback host when missing same-origin signals (#35200)
- nitro: Gate chrome devtools workspace endpoint to local requests (#35201)
- nuxt: Escape props in
<NuxtClientFallback>ssr output (#35199) - kit: Improve TS extension stripping/substitutions (#35233)
- nuxt: Preserve
.d.mts/.d.ctsinresolveTypePaths(#35235) - nuxt: Escape
<NoScript>slot content (4b054e9d9) - nuxt: Match route rules case-insensitively to mirror
vue-router(07e39cd6f) - nuxt: Reject script-capable protocols in
<NuxtLink>href (0103ce06f) - nuxt: Block path-normalization open redirect in
navigateTo(2cce6fb02) - nuxt: Reject cross-origin paths in
reloadNuxtApp(e447a793c) - vite: Bind vite-node IPC to a permissioned filesystem socket (1f9f4767a)
💅 Refactors
- kit,nuxt,vite: Use
es2023array methods (#34980) - nuxt: Replace
runInNewContextwith AST walker (d72a89ef4)
📖 Documentation
- Document vite client and server options (#35090)
- Add dedicated module dependencies page (#35171)
- Add nodeTsConfig and sharedTsConfig options (#35231)
- Edit for clarity and grammar (#35214)
🏡 Chore
- Use
execFileSyncfor safety in release scripts (1d7baaf01) - Assert there is always a tag (e98c47c3c)
- Add autofix action tag in comment (ffa5c0098)
- Fix type in test (a549652e2)
- Update renovate minimum release age (d12d5e58a)
- Fix lychee dynamic composable exclude (#35119)
- Update lockfile (91186dc51)
- Lint (dbc58965c)
✅ Tests
- Update test for js payload rendering (bdcb81536)
- Cover add regression test for hmr in sibling local layers (#35125)
- Improve reliability of hmr test (1d709b3cc)
🤖 CI
- Always run all tests for 4.x/3.x (0dc4665cf)
- Migrate from tibdex (ded29dc0f)
- Add zizmor github actions check (#35089)
- Update to agentscan v1.8.0 (#35120)
- Automatically close PRs from automated accounts (#35161)
- Disable provenance-change enforcement in dependency-review (a2cf43e68)
❤️ Contributors
- Daniel Roe (@danielroe)
- David Stack (@davidstackio)
- David De Sloovere (@DavidDeSloovere)
- anton-gor-dev (@anton-gor-dev)
- Noah3521 (@Noah3521)
- Shahar Aviram (@ShaharAviram1)
- Matej Černý (@cernymatej)
- Mohit Kumar (@mohitkum4r)
- Matteo Gabriele (@MatteoGabriele)
- Julien Huang (@huang-julien)
- Damian Głowala (@DamianGlowala)
- nitro: Assign
- 4.4.618 May 2026
Release notes
Open source →4.4.6 is the next patch release.
👉 Changelog
🩹 Fixes
- vite: Use spa entry for vite-node fallback (#35037)
- vite: Invalidate SSR module cache when modules are invalidated via plugin hooks (a86657a0e)
- nuxt: Match deduplicated
resolveComponentcalls in jsx blocks (#35028) - nuxt: Prefer our own builder/server deps (#35029)
- nuxt: Update
useFetchkey even withwatch: false(#35002) - nitro: Mark
@babel/plugin-syntax-typescriptas optional peer dep (#35041) - nitro: Add json extension to payload cache items (#35043)
- nuxt: Handle errors fetching app manifest (#35050)
- nuxt: Encode html-significant characters in external redirect body (#35052)
- nuxt: Preserve
setPageLayoutprops on same-path navigation (#35055) - vite: Don't strip buildAssetsDir from vite-node SSR ids (#35040)
- nuxt: Mark
useLoadingIndicatorproperties as readonly (#35062) - vite: Strip queries in css inline styles map (#35067)
- nitro: Validate island request hash matches props (#35077)
- nitro: Use regexp to strip query (163e18d4b)
- nitro: Use
statusCodefor nitro v2 compatibility (952f6841e) - nitro-server: Re-export h3 named symbols statically (cd99001c8)
- nuxt: Render component-less parent routes during client-side nav (#35036)
- kit: Respect
tsConfig.excludein legacytsconfig.json(#35079) - nuxt: Run middleware for page islands (#35092)
💅 Refactors
- rspack,webpack: Extract same-origin check for dev middleware (#35051)
📖 Documentation
- Remove CSB, set node 22 and use steps for clarity (#35066)
🏡 Chore
- One more type, one more (50dcf15bb)
- Remove unneeded (?) overrides (6997093af)
- Use explicit versions for fixture dependencies (294a734d4)
- Ignore link-like syntax in code (2584a549c)
- Narrow engines.node in test (5bb17fb47)
- Remove unused import (a52d78626)
✅ Tests
🤖 CI
- Clean up agent-scan workflow (ab8317547)
- Continue autofix workflow when
test:enginesfails (3025e561e) - Improve workflows (#35088)
❤️ Contributors
- Daniel Roe (@danielroe)
- Tim (@timhn-bm)
- Julien Huang (@huang-julien)
- Damian Głowala (@DamianGlowala)
- Sébastien Chopin (@atinux)
- Adrien Foulon (@Tofandel)
- Sami El Achi (@samiashi)
- 4.4.510 May 2026
Release notes
Open source →4.4.5 is the next patch release.
👉 Changelog
🔥 Performance
- kit: Cache layer roots and short-circuit
isIgnoredrelative (#35015)
🩹 Fixes
- vite: Resolve vite
clientServerwithssr: false(#34959) - nitro: Correct payload route rule for
/+ overridessr: true(#34990) - nitro: Break recursive rendering deadlocks during prerender (#34939)
- vite: Drop redundant css link when entry styles are inlined (#34950)
- vite: Sort
optimizeDeps.includein pre-bundle hint (#34976) - nuxt: Only force suspense remount after first resolve (#34949)
- kit: Read
.envbefore resolving nuxt schema (#34958) - nitro: Preserve
serverHandlersarray afternitro:config(#34985) - nuxt: Cast partial nitro handlers when prepending to server arrays (61dcde4db)
- vite: Only consider CSS inlined when styles are actually emitted (#35006)
- nuxt: Dedupe
getCachedDatafor concurrent callers sharing a key (#34999) - nuxt: Respect factory fetch/baseURL options in server
useFetch(#35003) - nuxt: Handle string presets in auto-imports (#35013)
- nuxt: Correct island transform for server pages and 'deep' mode (#35005)
- vite: Inline css for non-island children of server components (#35001)
- nuxt: Defer head DOM updates until page transition finishes (#35016)
- nuxt: Explicitly freeze head during island plugin phase (#35010)
- vite: Inline css imported from non-vue js modules (#35020)
📖 Documentation
- Add warning about routing in server components (#34994)
🏡 Chore
- Fix lockfile (c3ee07801)
- Pin
jiti(c8102228f) - Lint (39422b6d2)
- Pin
@vue/compiler-sfc(cd404a14c) - Ignore pnpm cyclic workspace deps warn (#34998)
- Remove jiti from build steps (#35004)
✅ Tests
- Extract server components fixture + add some failing tests (#34995)
- Isolate
buildDirper matrix project for shared fixtures (#35007) - Remove tests for 5.x runtimeBaseURL fature (816c25487)
❤️ Contributors
- Daniel Roe (@danielroe)
- Harlan Wilton (@harlan-zw)
- Jonazzzz (@Bombastickj)
- Damian Głowala (@DamianGlowala)
- Florian Heuberger (@Flo0806)
- kit: Cache layer roots and short-circuit
- 4.4.429 Apr 2026
Nothing published for this version
- 4.4.212 Mar 2026
Nothing published for this version
- 4.4.112 Mar 2026
Nothing published for this version
- 4.3.17 Feb 2026
Release notes
Open source →4.3.1 is a regularly scheduled patch release.
👉 Changelog
🩹 Fixes
- nuxt: Correct reference format of server builder (#34177)
- nuxt: Add status/statusText getters to NuxtError (#34188)
- nuxt: Don't inject shared types for differing auto-imports (#34191)
- schema: Add direnv and vendor to default ignore (#34190)
- nuxt: Focus hash links after navigation (#34193)
- nuxt: Exclude head runtime from unhead imports transform (#34195)
- kit: Include prereleases in semver satisfy check (#34210)
- nitro: Encode unicode paths in
x-nitro-prerenderheader (#34202) - nuxt: Watch
server/forbuilder:watchhook (#34208) - nitro: Preserve
error.messagefor fatal errors (#34226) - Only enable dynamic imports when ts plugin (#34205)
- webpack: Use H3Error for 403 in dev server (#34233)
- nuxt: Ensure NuxtError extends Error type (#34242)
- vite: Use H3Error for 404 in dev server (#34225)
- nuxt: Add backwards compat for
#appbarrel export in keyed functions (#34199) - nuxt: Track + re-add custom routes on hmr (#32044)
- nuxt: Keep vnode when leaving deeper nested route (#33778)
- vite: Prevent CSS flickering in dev mode after config changes (#33856)
- nuxt: Do not start view transition if there is no route (#33723)
- nuxt: Call deferHydration done on NuxtPage unmount (#34152)
- nuxt: Handle invalid
datetime in<NuxtTime>` (#33992) - nuxt: Preserve middleware error status in 404 fallback (#34148)
- nitro: Do not augment
nuxt/schema(#34255) - nuxt: Cache manifest files to preserve buildId (#34002)
- nuxt: Don't decode query string in SSR context URL (#34252)
- nuxt: Allow specifying moduleDependencies by
meta.name(#34263) - nuxt: Resolve
#componentsimport mapping conflict for packages outside rootDir (#34139) - vite,webpack: Use node.res to send 403/404 (#34266)
- nitro,nuxt: Align path encoding with vue-router (#34265)
- nitro: Augment
nuxt/schemaonce more (552bbd8d1)
💅 Refactors
- nuxt: Prefer
genObjectKeyto omit unnecessary quotes (#34245) - nuxt: Use
ComponentPropshelper to extract layout props (#34248)
📖 Documentation
- Update roadmap dates (#34166)
- Correct default value of
nitroAutoImports(#34182) - Clarify shared type context limitations for custom imports (#34194)
- Fix broken links (#34223)
- Document payload extraction for ISR/SWR routes (#34222)
- Update default aliases in configuration reference (#34237)
- Update example of email validation (#34247)
- Align server alias examples with
#serverandrootDir(#34259) - Add documentation for
keyedComposables(#34201)
🏡 Chore
✅ Tests
- Vitest v4 compatibility (825b2c202)
- Add runtime tests for deeply nested
<NuxtPage>navigation (048efc030)
❤️ Contributors
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Octavio Araiza (@8ctavio)
- Muhammad Yasir Ghaffar (@M-YasirGhaffar)
- mrkaashee (@mrkaashee)
- Max (@onmax)
- Bobbie Goede (@BobbieGoede)
- 纸鹿/Zhilu (@L33Z22L11)
- Florian Heuberger (@Flo0806)
- 山吹色御守 (@KazariEX)
- ExXTreMe315 (@ExXTreMe315)
- Eugene (@FlexIDK)
- abeer0 (@iiio2)
- Jonas Thelemann (@dargmuesli)
- Erwan Jugand (@erwanjugand)
- 4.3.022 Jan 2026
Release notes
Open source →4.3.0 is the next minor release.
Nuxt 4.3 brings powerful new features for layouts, caching, and developer experience – plus significant performance improvements under the hood.
📣 Some News
Extended v3 Support
Early this month, I opened a discussion to find out how the upgrade had gone from v3 to v4. I was really pleased to hear how well it had gone for most people.
Having said that, we're committed to making sure no one gets left behind. And so we will continue to provide security updates and critical bug fix releases beyond the previously announced end-of-life date of January 31, 2026, meaning Nuxt v3 will meet its end-of-life on July 31, 2026.
[!TIP] As usual, today also brings a minor release for v3, with many of the same improvements backported from v4.3.
Preparing for Nuxt 5
We're closer than ever to the releases of Nuxt v5 and Nitro v3. In the coming weeks, the
mainbranch of the Nuxt repository will begin receiving initial commits for Nuxt 5. However, it's still business as usual.- Continue making pull requests to the
mainbranch - We'll backport changes to the
4.xand3.xbranches
Keep an eye out on the Upgrade Guide – we'll be adding details about how you can already start migrating your projects to prepare for Nuxt v4 with
future.compatibilityVersion: 5.🗂️ Route Rule Layouts
But that's enough about the future. We have a lot of good things for you today!
First, you can now set layouts directly in route rules using the new
appLayoutproperty (#31092). This provides a centralized, declarative way to manage layouts across your application without scatteringdefinePageMetacalls throughout your pages.export default defineNuxtConfig({ routeRules: { '/admin/**': { appLayout: 'admin' }, '/dashboard/**': { appLayout: 'dashboard' }, '/auth/**': { appLayout: 'minimal' } } })This might be useful for:
- Admin panels with a shared layout across many routes
- Marketing pages that need a different layout from the app
[!TIP] Plus, you can pass props to layouts now! See the
setPageLayoutimprovements below.📦 ISR/SWR Payload Extraction
Payload extraction now works with ISR (incremental static regeneration), SWR (stale-while-revalidate) and cache
routeRules(#33467). Previously, only pre-rendered pages could generate_payload.jsonfiles.This means:
- Client-side navigation to ISR/SWR pages can use cached payloads
- CDNs (Vercel, Netlify, Cloudflare) can cache payload files alongside HTML
- Fewer API calls during navigation – data can be prefetched and served from the cached payload
export default defineNuxtConfig({ routeRules: { '/products/**': { isr: 3600, // Revalidate every hour } } })🧹 Dev Mode Payload Extraction
Related to the above, payload extraction now also works in development mode (#30784). This makes it easier to test and debug payload behavior without needing to run a production build.
[!IMPORTANT] Payload extraction works in dev mode with
nitro.staticset totrue, or for individual pages which haveisr,swr,prerenderorcacheroute rules.🚫 Disable Modules from Layers
When extending Nuxt layers, you can now disable specific modules that you don't need (#33883). Just pass
falseto the module's options:export default defineNuxtConfig({ extends: ['../shared-layer'], // disable @nuxt/image from layer image: false, })🏷️ Route Groups in Page Meta
Route groups (folders wrapped in parentheses like
(protected)/) are now exposed in page meta (#33460). This makes it easy to check which groups a route belongs to in middleware or anywhere you have access to the route.<script setup lang="ts"> // This page's meta will include: { groups: ['protected'] } useRoute().meta.groups </script>export default defineNuxtRouteMiddleware((to) => { if (to.meta.groups?.includes('protected') && !isAuthenticated()) { return navigateTo('/login') } })This provides a clean, convention-based approach to route-level authorization without needing to add
definePageMetato every protected page.🎨 Layout Props with
setPageLayoutThe
setPageLayoutcomposable now accepts a second parameter to pass props to your layout (#33805):export default defineNuxtRouteMiddleware((to) => { setPageLayout('admin', { sidebar: true, theme: 'dark' }) })<script setup lang="ts"> defineProps<{ sidebar?: boolean theme?: 'light' | 'dark' }>() </script>🔧
#serverAliasA new
#serveralias provides clean imports within your server directory (#33870), similar to how#sharedworks:// Before: relative path hell import { helper } from '../../../../utils/helper' // After: clean and predictable import { helper } from '#server/utils/helper'The alias includes import protection – you can't accidentally import
#servercode from client or shared contexts.🪟 Draggable Error Overlay
The development error overlay introduced in Nuxt 4.2 is now draggable and can be minimized (#33695). You can:
- Drag it to any corner of the screen (it snaps to edges)
- Minimize it to a small pill button when you want to keep working
- Your position and minimized state persist across page reloads
This is a quality-of-life improvement when you're iterating on fixes and don't want the overlay blocking your view.
https://github.com/user-attachments/assets/nuxt_4-3_error_demo.mp4
⚙️ Async Plugin Constructors
Module authors can now use async functions when adding build plugins (#33619):
export default defineNuxtModule({ async setup() { // Lazy load only when actually needed addVitePlugin(() => import('my-cool-plugin').then(r => r.default())) // No need to load webpack plugin if using Vite addWebpackPlugin(() => import('my-cool-plugin/webpack').then(r => r.default())) } })This enables true lazy loading of build plugins, avoiding unnecessary code loading when plugins aren't needed.
🚀 Performance Improvements
This release includes several performance optimizations for faster builds:
- Hook filters - Internal plugins now use filters to avoid running hooks unnecessarily (#33898)
- SSR styles optimization - The
nuxt:ssr-stylesplugin is now significantly faster (#33862, #33865) - Layer alias transform - Skipped when using Vite (it handles this natively) (#33864)
- Route rules compilation - Route rules are now compiled into a client chunk using
rou3, removing the need forradix3in the client bundle and eliminating app manifest fetches (#33920)
🎨 Inline Styles for Webpack/Rspack
The
inlineStylesfeature now works with webpack and rspack builders (#33966), not just Vite. This enables critical CSS inlining for better Core Web Vitals regardless of your bundler choice.⚠️ Deprecations
statusCode→status,statusMessage→statusTextIn preparation for Nitro v3 and H3 v2, we're moving to use Web API naming conventions (#33912). The old properties still work but are deprecated in advance of v5:
- throw createError({ statusCode: 404, statusMessage: 'Not Found' }) + throw createError({ status: 404, statusText: 'Not Found' })🐛 Bug Fixes
Notable fixes in this release:
- Fixed head component deduplication using
keyattribute (#33958, #33963) - Fixed async data properties not being reactive in Options API (#34119)
- Fixed
useCookieunsafe number parsing during decode (#34007) - Fixed
NuxtPagenot re-rendering when nestedNuxtLayouthas layouts disabled (#34078) - Fixed client-side pathname decoding for non-ASCII route aliases (#34043)
- Fixed suspense remounting when navigating after pending state (#33991)
- Fixed clipboard copy in error overlay (#33873)
- Enabled
allowArbitraryExtensionsby default in TypeScript config (#34084) - Added
noUncheckedIndexedAccessto server tsconfig for safer typing (#33985)
[!IMPORTANT] Enabling
noUncheckedIndexedAccessin the Nitro server TypeScript config improves type safety but may surface new type errors in your server code. This change was necessary because Nuxt's app context performs type checks on server routes (learn more).While we recommend keeping this enabled for better type safety, you can disable it if needed:
export default defineNuxtConfig({ nitro: { typescript: { tsConfig: { compilerOptions: { noUncheckedIndexedAccess: false } } } } })Note that disabling this may allow type errors to slip through that could cause runtime issues with indexed access.
📚 Documentation
- Improved module author guides with clearer structure (#33803)
- Added MCP setup instructions for Claude Desktop (#33914)
- Added layers directory documentation (#33967)
- Added Deno package manager examples (#34070)
- Clarified type-checking context limitations for server routes (#33964)
🎉 Nuxt 3.21.0
Alongside v4.3.0, we're releasing Nuxt v3.21.0 with many of the same improvements backported to the 3.x branch. This release includes:
- All the same features: Route rule layouts, ISR payload extraction, layout props with
setPageLayout,#serveralias, draggable error overlay, and more - All performance improvements: SSR styles optimization, hook filters, and route rules compilation
- Module disabling: Disable layer modules by setting options to
false - Critical bug fixes: Async data reactivity in Options API,
useCookienumber parsing, head component deduplication, and more
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe # or, if you are upgrading to v3.21 npx nuxt@latest upgrade --dedupe --channel=v3This will deduplicate your lockfile and help ensure you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
[!TIP] Check out our upgrade guide if upgrading from an older version.
👉 Changelog
🚀 Enhancements
- kit: Support async constructor for adding plugins (#33619)
- kit: Export Nuxt major version type (#33700)
- schema: Add
#serveralias for server directory imports (#33870) - ui-templates: Let it snow! ❄️ (#33804)
- schema: Hoist nitro
crosswstypes (5b16a51f5) - nitro,nuxt: Compile route rules into client chunk (#33920)
- nuxt: Allow disabling modules by setting module options to
false(#33883) - kit: Allow specifying
moduleDependenciesas an async function (#33504) - nuxt: Support
appLayoutin route rules (#31092) - nuxt: Add route groups to page meta (#33460)
- nuxt: Enable payload extraction for ISR/SWR routes (#33467)
- nuxt: Allow updating props with
setPageLayout(#33805) - nuxt: Enable dragging and minimizing for error overlay (#33695)
- nitro,nuxt: Add support for payload extraction in dev (#30784)
- rspack,webpack: Add inline styles (#33966)
- kit: Add forward-compatible nitro types (#34036)
🔥 Performance
- nuxt: Do not init layer alias transform when using vite (#33864)
- vite: Add hook filters for ssr styles plugin (#33865)
- vite: Optimize
nuxt:ssr-stylesplugin (#33862) - nuxt: Use filter for vfs plugin load (eb3d2d4c6)
- nuxt,vite: Use filters to avoid running hooks unnecessarily (6b7fc7477)
- nuxt,vite: Add more filters to internal plugins (#33898)
🩹 Fixes
- kit: Normalize local layer paths with trailing slashes (#33858)
- nuxt: Avoid overwriting multiple head input in island handler (#33849)
- nuxt: Update meta instead of calling
router.replacein page hmr (#33897) - nuxt: Don't call
page:loading:endin cache if already called (7789f73bd) - vite: Add error handling for parsing
NUXT_VITE_NODE_OPTIONS(41a564d23) - nuxt: Do not skip middleware when
appMiddlewarereferences invalid key (323f27bc8) - nitro: Clipboard copy in error overlay (#33873)
- webpack,rspack: Resolve deep imports in virtual files (#33927)
- webpack: Disable async chunks in dev mode (0310c4070)
- webpack: Correctly evaluate sourcemap name (653f364af)
- nuxt: Handle node10 resolution for
nuxt/meta(01c2c9b13) - nuxt: Do not early return if component priorities conflict (#33955)
- nuxt: Use
keyfor tag deduplication in<Head>component (#33958) - schema,vite: Resolve
build.transpilewhen initialising vite (#33868) - nuxt,rspack,webpack: Inject module identifiers for webpack builders (#33962)
- nuxt: Add key to head components for proper deduplication (#33963)
- nitro: Check prettyResponse.body type before error overlay (#33977)
- nuxt: Don't URI-encode static route paths (#33990)
- nuxt: Skip internal stub routes from prerender (#34001)
- kit,schema: Align module
onUpgradearguments with types (#33988) - nuxt: Handle unsafe number parsing in useCookie decode (#34007)
- nuxt: Do not externalise
rou3(2df4e1ae3) - nitro: Add
noUncheckedIndexedAccessto server tsconfig (#33985) - nuxt: Add auto-import declarations for
shared/context (#33978) - nuxt: Update global reference to globalThis in
useRequestFetch(#33976) - vite: Configure hmr port for server build (#33929)
- kit: Add forward compatible nitro v3 types (#34053)
- nitro,nuxt: Do not import nitro deps in builders (#34054)
- nitro: Add
h3types to auto-imports (#34035) - schema: Add some more directories to ignore (ebc2a66ab)
- nitro: Also augment
nuxt/schema(a6a044d81) - nuxt: Make asyncData properties reactive in Options API (#34119)
- nuxt: Rerender
NuxtPagewhen nestedNuxtLayouthas explicitly disabled layouts (#34078) - kit,nitro: Enable
allowArbitraryExtensionsby default (#34084) - nuxt: Decode client-side pathname for non-ASCII route aliases (#34043)
- nuxt: Force remount suspense when navigating after pending (#33991)
- nuxt: Add documentation link to server builder error message (#34122)
- nuxt: Validate placeholder/fallback tags + warn about placeholder/fallback props (567a1c6fb)
- nuxt: Force flush
useAsyncDatadebounced execute post watcher flush (#34125) - nitro: Process isr/swr/cache keys (d84278622)
- nuxt: Add
typeFromsupport forimports.d.tstemplate exports (#34135) - nuxt: Ensure we inline styles for
hydrate-nevercomponents (#34132)
💅 Refactors
- kit: Add explicit return types for kit utilities (6cd1289d1)
- nitro,nuxt,schema,vite: Provide explicit return types (1d2c0c25f)
- kit,nuxt,schema: Use named imports from
defu+consola(322dae3e0) - Add explicit
.tsfile extensions to relative imports (80778c0cd) - kit,nitro,nuxt,schema: Reduce barrels + move
<>toas(f1713850c) - nitro,nuxt: Use
~prefix for internal ssrContext properties (#33896) - nitro: Add explicit return types for runtime utils (a4fda917e)
- nitro: Move tree-shaken flags from replace plugin -> vfs (#33907)
- nitro,nuxt,vite,webpack: Use
status/statusText+ deprecate old props (#33912) - webpack: Use RuntimeModule API for chunk preloads (#33930)
- nuxt: Use AST-aware function key injection (#33446)
- nitro,nuxt,schema: Use augments for nitro schema types (#34039)
- nitro,rspack,vite,webpack: Move cors handling -> nitro builder (#34048)
📖 Documentation
- Split and improve
Module Author Guides(#33803) - Update links to module guide (86d67b24f)
- Fix
useHeadreturn type (#33857) - Add note that middleware doesn't run when rendering islands (7df27c781)
- Add note on default branch for layers (#33919)
- Add mcp setup instructions for claude desktop (#33914)
- Mention deno as package manager (#33875)
- Clarify purpose of
statusText(#32834) - Update lychee config and remove medium article link (c0b4e0f28)
- Update module count and fix typo (#33950)
- Add DeepWiki badge (#33508)
- Give example of usage of
defineWrappedResponseHandler(#33952) - Provide cleaner example code for vitest projects (#33960)
- Improve
addImportsexample (#34011) - Update yarn create command (4a3c08874)
- Update roadmap with a11y (d3453d6a5)
- Add a11y release (#34041)
- Remove Nuxtr from recommendations (#34045)
- Typo (#34050)
- Remove duplicate feature (#34058)
- Fix typo (#34057)
- Provide deno package manager examples (#34070)
- Update JSDoc for
config.experimentalproperties (#34069) - Fix transition types (#34082)
- Make custom wrapper recipe link more prominent (#34085)
- Remove
nullfromgetCachedDatatrigger (f7cf3747e) - nuxt: Mention custom serializers in
useStatedocs (#34105) - Add info about runtime directories + type checking (#34097)
- Clarify module setups in
.nuxtrcexample (#34107) - Remove duplicate entries in table (#34094)
- Clarify catch all notation for
addServerHandler(#34060) - Add layers directory documentation (#33967)
- Clarify type-checking context limitations for server routes (#33964)
- Add a tip for
appLayout(beda47955) - Add docs for disabling modules by passing
falseto its options (cdad9310c) - Add info about caching payloads with isr/swr (6e10ff04f)
- Add example for async addVitePlugin (1098254f7)
- Add example of passing props to layouts (1f9e6b82c)
- Mark vite plugin as not typed (5e09fddfb)
- Add warning about
sourcefrom<NuxtIsland>(1586bbb6e)
📦 Build
- Remove babel debugging plugin from jiti stub options (bce8248b4)
- vite: Add build entries for
vite-nodeentrypoints (#33893) - nuxt: Tidy up subpath export types (a63d4a014)
- Use
obuildexcept for nuxt + nitro-server packages (#34049) - schema: Fix
/builder-envsubpath types (7f5034288)
🏡 Chore
- Add return types to debug plugins (8f7554287)
- Add
build:stubcommand for those that need it (3e3d3d37a) - Revert change to how type augments are inserted (c1b3590ff)
- Update eslint config rule (2717d8fd3)
- Do not require aligned columns in tables (8d3c5b371)
- Lint (f89d447a1)
- Explicitly import
node:process(#33982) - Add root scripts to lint context (e22089f82)
- Tidy up configs (8b42d4c2b)
- Lint docs with eslint (51da8e681)
- Lint (1cfd3c460)
✅ Tests
- Update tests for new version of nuxt/test-utils (#33842)
- Avoid unnecessary tick (988f6657a)
- Add regression test for asyncData HMR (#32182)
- Add test for page hmr resetting state (#32418)
- Add reproduction for vite pre-transform error (#31574)
- Add regression test for #32154 (#32154)
- Use
vi.hoistedfor klona mock (#34113)
🤖 CI
- Directly call webhook url (ce15997ce)
- Use new reusable triage workflows (#34072)
- Use new shared dependency review workflow (8c01e1ce9)
❤️ Contributors
- Florian Heuberger (@Flo0806)
- Octavio Araiza (@8ctavio)
- Daniel Roe (@danielroe)
- Robin (@OrbisK)
- shaheer-arbisoft (@shaheer-arbisoft)
- Matej Černý (@cernymatej)
- Francesco Mussoni (@solidusite)
- Danila Poyarkov (@dannote)
- Victor Saa (@vis97c)
- Teages (@Teages)
- Eli Sterken (@eli-sterk)
- Ryota Watanabe (@wattanx)
- Jakub Andrzejewski (@Baroshem)
- edison (@edison1105)
- Max (@onmax)
- Aidan Hibbard (@aidanhibbard)
- Rahul Dogra (@rahuld109)
- Julien Huang (@huang-julien)
- abeer0 (@iiio2)
- James Robert Lund III (@lundjrl)
- Philipp Wagner (@imphil)
- Maxime Pauvert (@maximepvrt)
- Wind (@productdevbook)
- Agatem (@agatemosu)
- Pavel (@eL1fe)
- Alois Sečkár (@AloisSeckar)
- Lucie (@lihbr)
- Sergiu Ravliuc (@YoSoySergio)
- Saeid Zareie (@Saeid-Za)
- Alireza Jahandideh (@Youhan)
- kikuchan (@kikuchan)
- Ragura (@Ragura)
- Josh Deltener (@hecktarzuli)
- Teena (@franklin-tina)
- Frederik Bußmann (@freb97)
- Benjamin Oddou (@BenjaminOddou)
- Mukund Shah (@mukundshah)
- Jessé Correia Lins (@linspw)
- Jannik Sohn (@janniksohn)
- Dawit (@oneminch)
- Ali Sokkar (@NyllRE)
- Horu (@HigherOrderLogic)
- Anthony Fu (@antfu)
- Harlan Wilton (@harlan-zw)
- Alexander Lichter (@TheAlexLichter)
- Ryan Wilson (@rywils)
- Hugo (@HugoRCD)
- yamachi4416 (@yamachi4416)
- Continue making pull requests to the
- 4.2.29 Dec 2025
Release notes
Open source →4.2.2 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- nitro: Do not show pretty error handler when testing (243261edb)
- nuxt: Generate valid references for component declaration items (#33388)
- nuxt: Sync internal route before calling
page:finishhook (#33707) - kit: Add TypeScript path alias support for test files (#33672)
- nitro: Ensure html is a string before injecting error handler (f70b70c97)
- nitro: Include layer server directories in
tsconfig.server.json(#33510) - nuxt: Ensure deduped async data executions return latest promise (#33740)
- kit,nuxt: Type + respect
moduleDependenciesby meta name (#33774) - nuxt,schema: Ignore
.d.vue.tsdeclarations (1c73525a2) - kit,nuxt: Protect against resolved nuxt module subpath (#33767)
- nuxt: Re-execute
callOnceduring HMR (#33810) - nuxt: Resolve watch callback after reactive key change in
useAsyncData(#33802) - nuxt: Escape HTML in development error page stack trace (#33820)
- kit: Do not add resolved
rootDirto cached layer config (#33779) - kit,schema: Add
moduleDependencies->installModule(#33689)
💅 Refactors
- nuxt: Improve type safety within
callOncefunction (#33825)
📖 Documentation
- Split directory structure and re-order guides (v4) (#33691)
- Add hints release (#33701)
- Fix link to vitest globals config (#33702)
- Add mcp server and llms.txt (#33371)
- Fix 404 link (98c2f1397)
- Text consistency (#33709)
- Type
erroras non-optional prop (#33763) - Reformat tables (#33813)
🏡 Chore
- Update pnpm to 10.21 and enable trust policy (d2c9711c0)
- Revert pnpm trust policy and restore provenance action (f9d0e0a3d)
- Update markdownlint config to ignore mdc issues (e7fff7132)
- Pin to single version of unstorage (ec316eae8)
✅ Tests
- Add
patchPropandnodeOpsto excluded Vue helpers (#33754) - Use fake timers for watch params test (08d9d2f3b)
🤖 CI
❤️ Contributors
- Daniel Roe (@danielroe)
- Florian Heuberger (@Flo0806)
- Konstantin Telyakov (@kTelyakov)
- abeer0 (@iiio2)
- Julien Huang (@huang-julien)
- Matej Černý (@cernymatej)
- Robin (@OrbisK)
- Dheeraj Joshi (@dheeraj3587)
- Alexander Lichter (@TheAlexLichter)
- Edwin Samodra (@edwinsamodra)
- edison (@edison1105)
- 山吹色御守 (@KazariEX)
- Sébastien Chopin (@atinux)
- Hugo (@HugoRCD)
- pierreoa (@pierreoa)
- Maxime Pauvert (@maximepvrt)
- 4.2.16 Nov 2025
Release notes
Open source →4.2.1 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- kit,nuxt,schema: Deprecate
ImportPresetWithDeprecation(#33596) - nuxt: Correct warning message for prefetch/noPrefetch conflict (#33617)
- nitro: Remove
<nuxt-error-overlay>iframe border (#33625) - vite: Use rolldown replace only in build (#33615)
- nitro: Use directory paths in
moduleEntryPaths(#33628) - nitro: Start error overlay minimized based on status code (#33658)
- vite: Ensure
optimizeDepsconfig is applied before other plugins (#33586) - nuxt: Respect layer priority order for scanned components (#33654)
- nuxt: Process prerender routes on
pages:resolved(#33662) - nuxt: Remove abort signal event listeners after render (#33665)
- nuxt: Cleanup event listener with cleanup signal (#33667)
- vite: Update
vite-node(#33663) - vite: Respect vite proxy in dev middleware (#33670)
💅 Refactors
- kit,nitro,nuxt,schema,vite: Explicitly import process/performance (#33650)
📖 Documentation
- Fix typo in eslint flat config description (#33569)
- Add signal support to useAsyncData examples (#33601)
- Document
pendingas alias ofstatus === 'pending'(#33221) - Note that
cookieStoreistrueby default (#33572) - Add information on types for server context (#33511)
- Mark webstorm issue resolved (#33608)
- Clarify route middleware doesn't affect API routes (#33643)
- Improve docs for
useHead/useHydration/useLazy*(#33626) - Update link to nitro source to v2 branch (08018af4f)
- Add typescript documentation for module authors (#33637)
- Typo (#33655)
🏡 Chore
- Update URLs (#33567)
- Add
verifyDepsBeforeRun: install(#33603) - Reduce redirects in docs links (1cc539325)
- Lint docs (0b5fa5dea)
🤖 CI
- Disable cache in release action (ff37598bc)
❤️ Contributors
- Daniel Roe (@danielroe)
- Anthony Fu (@antfu)
- Robin (@OrbisK)
- abeer0 (@iiio2)
- Bobbie Goede (@BobbieGoede)
- Florian Heuberger (@Flo0806)
- Matej Černý (@cernymatej)
- Peter Budai (@peterbud)
- Julien Huang (@huang-julien)
- Max (@onmax)
- 纸鹿/Zhilu (@L33Z22L11)
- Hinata Oishi (@te19oishi)
- Damian Głowala (@DamianGlowala)
- Maxime Pauvert (@maximepvrt)
- Raed Abdennadher (@RaedAbr)
- kit,nuxt,schema: Deprecate
- 4.2.025 Oct 2025
Release notes
Open source →4.2.0 is the next minor release.
👀 Highlights
We're excited to announce Nuxt 4.2, bringing new capabilities for better TypeScript DX, enhanced error handling, and improved control over data fetching! 🎉
🎯 Abort Control for Data Fetching
You can now use
AbortControllersignals directly withinuseAsyncData, giving you fine-grained control over request cancellation (#32531).This works by passing an internal signal to your
useAsyncDatahandlerto cancel any promise that can be canceled, such as$fetch.<script setup lang="ts"> const controller = new AbortController() const { data, error, clear, refresh } = await useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal })) refresh() // will actually cancel the $fetch request (if dedupe: cancel) refresh() // will actually cancel the $fetch request (if dedupe: cancel) refresh() clear() // will cancel the latest pending handler </script>You also pass an
AbortControllersignal directly torefresh/execute, giving you fine-grained control over request cancellation. This is particularly useful when you need to abort requests based on user actions or component lifecycle events.const { data, refresh } = await useAsyncData('posts', fetchPosts) // Abort an ongoing refresh const abortController = new AbortController() refresh({ signal: abortController.signal }) // Later... abortController.abort()🎨 Better Error Pages in Development
When an error occurs during development, Nuxt will now display both your custom error page and a detailed technical error overlay (#33359). This gives you the best of both worlds – you can see what your users will experience while also having immediate access to stack traces and debugging information.
The technical overlay appears as a toggleable panel that doesn't interfere with your custom error page, making it easier to debug issues while maintaining a realistic preview of your error handling.
🔮 Opt-in Vite Environment API
For those wanting to experiment with cutting-edge features, you can now opt into the Vite Environment API (#33492).
The Vite Environment API is a major architectural improvement in Vite 6. It closes the gap between development and production by allowing the Vite dev server to handle multiple environments concurrently (rather than requiring multiple Vite dev servers, as we have done previously in Nuxt).
This should improve performance when developing and eliminate some edge case bugs.
... and it is the foundation for implementing Nitro as a Vite environment, which should speed up the dev server still further, as well as allowing more greater alignment in development with your Nitro preset.
export default defineNuxtConfig({ experimental: { viteEnvironmentApi: true } })This is also the first breaking change for Nuxt v5. You can opt in to these breaking changes by setting
compatibilityVersionto5:export default defineNuxtConfig({ future: { compatibilityVersion: 5 }, })Please only use this for testing, as this opts in to unlimited future breaking changes, including updating to Nitro v3 once we ship the Nuxt integration.
[!WARNING] This is highly experimental and the API may change. Only enable if you're prepared for potential breaking changes and want to help shape the future of Nuxt!
📦 New
@nuxt/nitro-serverPackageWe've extracted Nitro server integration into its own package:
@nuxt/nitro-server(#33462). This architectural change allows for different Nitro integration patterns and paves the way for future innovations in server-side rendering.While this change is mostly internal, it's part of our ongoing effort to make Nuxt more modular and flexible. The new package provides standalone Nitro integration and sets the foundation for alternative integration approaches (such as using Nitro as a Vite plugin in Nuxt v5+).
[!NOTE] This is an internal refactor – no changes should be required in your code.
⚡ Performance Improvements
We've also shipped several performance enhancements:
- Precomputed renderer dependencies – We now compute renderer dependencies at build time rather than runtime, improving cold start and initial render performance (#33361)
- Reduced dependencies – Removed unnecessary dependencies from kit and schema packages (7ae2cf563)
📉 Async Data Handler Extraction
One of the most exciting performance improvements is the new experimental async data handler extraction (#33131). When enabled, handler functions passed to
useAsyncDataanduseLazyAsyncDataare automatically extracted into separate chunks and dynamically imported.This is particularly effective for prerendered static sites, as the data fetching logic is only needed at build time and can be completely excluded from the client bundle.
[!NOTE] In testing with a previous version of nuxt.com, this feature reduced JavaScript bundle size by 39%! Of course, your mileage may vary depending on how much data fetching logic you have.
<script setup lang="ts"> // This handler will be extracted into a separate chunk // and only loaded when needed const { data: post } = await useAsyncData('post', async () => { const content = await queryContent(`/blog/${route.params.slug}`).findOne() // Complex data processing that you don't want in the client bundle const processed = await processMarkdown(content) const related = await findRelatedPosts(content.tags) return { ...processed, related } }) </script>For static/prerendered sites, enable it in your config:
export default defineNuxtConfig({ experimental: { extractAsyncDataHandlers: true } })The extracted handlers are then tree-shaken from your client bundle when prerendering, as the data is already available in the payload. This results in significantly smaller JavaScript files shipped to your users.
🔧 Experimental TypeScript Plugin Support
We're introducing experimental support for enhanced TypeScript developer experience through the
@dxup/nuxtmodule.This module adds a number of TypeScript plugins that aim to improve your experience when using Nuxt-specific features:
- Smart component renaming: Automatically updates all references when you rename auto-imported component files
- Go to definition for dynamic imports: Navigate directly to files when using glob patterns like
import(\~/assets/${name}.webp`)` - Nitro route navigation: Jump to server route handlers from data fetching functions (
$fetch,useFetch,useLazyFetch) - Runtime config navigation: Go to definition works seamlessly with runtime config properties
- Enhanced auto-import support: Includes the
@dxup/unimportplugin for better navigation with auto-imported composables and utilities
[!NOTE] Read more in the documentation.
To enable this feature, set
experimental.typescriptPlugintotruein your Nuxt configuration:export default defineNuxtConfig({ experimental: { typescriptPlugin: true } })Once enabled, the module will be automatically installed and configured by Nuxt.
[!IMPORTANT] This feature also requires selecting the workspace TypeScript version in VS Code. Run the "TypeScript: Select TypeScript Version" command and choose "Use Workspace Version".
🎁 Other Improvements
- Component
declarationPath– You can now specify a custom declaration path for components (#33419) - Module resolution extensions – Kit's
resolveModulenow accepts anextensionsoption (#33328) - Global head utility – New
setGlobalHeadutility in kit for easier head management (#33512)
🩹 Important Fixes
- Route hash is now preserved when redirecting based on
routeRules(#33222) - Fixed concurrent calls to
loadNuxtConfigwith proper cleanup (#33420) - Object-format
hrefnow works correctly in<NuxtLink>(c69e4c30d) - Component auto-imports now work as arguments to Vue's
h()function (#33509) - Fixed app config array handling during HMR (#33555)
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will refresh your lockfile and pull in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- nuxt: Allow specifying component
declarationPath(#33419) - kit: Add
extensionsoption forresolveModule(#33328) - nuxt: Add abortController option to
useAsyncData(#32531) - nuxt: Display youch error page w/ user error page in dev (#33359)
- nuxt: Experimental typescript plugin support (#33314)
- nuxt,schema: Extract asyncData handlers to chunks (#33131)
- schema: Enable setting
future.compatibilityVersionto5(22f4693a1) - kit,vite: Allow enabling vite environment api (#33492)
- kit: Add
setGlobalHeadutility (#33512)
🔥 Performance
- nuxt: Precompute renderer dependencies at build time (#33361)
- kit,schema: Remove some unnecessary dependencies (7ae2cf563)
🩹 Fixes
- nuxt: Preserve hash with redirecting based on
routeRules(#33222) - kit: Safely cleanup
loadNuxtConfigin concurrent calls (#33420) - nuxt: Allow object-format
hrefin<NuxtLink>(c69e4c30d) - nuxt: Remove
mergeModelsfrom auto imports (#33344) - nuxt: Add back
shortPathproperty (#33384) - nuxt: Do not allow native attrs to shadow nuxt link props (4751a6aca)
- nuxt: Remove
declarationPathfrom component dirs (191bcb7e9) - nuxt: Preserve root route in
isPrerenderedcheck (#33476) - nuxt: Exempt webpack vfs from pkg lookup (285eac31c)
- nitro: Exempt nightly release from import protections (dd522394a)
- webpack,rspack: Preserve prerender + nitro flags in server builds (#33503)
- nuxt: Support component auto-imports as arguments of
h()(#33509) - vite: Prevent assignment for rolldown's replacement plugin (#33526)
- nuxt: Use sha256 hash for prerender cache keys (#33505)
- nuxt: Add
NuxtTimerelative timenumericprop (#33552) - nuxt: Add
NuxtTimerelative timerelativeStyleprop (#33557) - nuxt: Handle arrays in app config correctly during HMR (#33555)
- vite: Unset
optimizeDeps.includefor server environment (#33550)
💅 Refactors
- Remove obsolete
shortPathproperty (#33384) - kit: Extract trace utilities (9687505ac)
- nuxt,vite,webpack: Allow builders to augment types (#33427)
- schema: Deprecate
extend,extendConfig, andconfigResolvedhooks (e060b9695) - vite: Make vite plugins environment-compatible (#33445)
- nitro,nuxt: Extract
@nuxt/nitro-serverpackage (#33462) - nuxt: Use
RouteLocationNormalizedLoadedGenericinternally (b51cb3067)
📖 Documentation
- Update link to localisation issue (d32859da2)
- Add nuxt module
addServerPluginnote (#33409) - Remove deprecated node version (#33411)
- Update
declarationPathinaddComponent(#33380) - Reproduction links for Nuxt v4 (#33429)
- Add some notes/deprecations for vite hooks (31c5f26a2)
- Fix incorrect ESM module field info (#33451)
- Recommend
getLayerDirectories()instead ofnuxt.options._layers(#33484) - Add
4.xprefix (5c0bb9285) - Add docs for
moduleDependencies(#33499) - Clarify extends removal in TypeScript config migration (#33523)
- Pin codemod to v0.18.7 for migration recipe (#33522)
- Fix links (#33554)
🏡 Chore
- Migrate gitpod to ona (#33159)
- Use native node to run
test:prepare(6ef632b82) - Do not use native node to run
test:prepare(eca36cfe5) - Lint docs (3b9784111)
- Update valid semantic scopes (3c38d1f8b)
- Ignore nitro templates (27cf85bdc)
- Update internal links (aac763017)
- Remove
vue-demifromignoredBuiltDependencies(#33494) - Update vscode url (#33360)
- Correct jsdoc location for function used as parameters (#33507)
- Remove code comment (#33515)
- Patch changelogen for large numbers of commits (bd36738b8)
- Link Nuxt 1.x and 2.x (2016–2022) history to main (85838dfd9)
- Filter out commits before last tag when constructing changelog (1c561daeb)
- Also respect since date for bump type (08900f610)
- Also respect
sincein nightly releases (74ca73ca1) - Ignore
@rollup/plugin-commonjs(cd12980ce)
✅ Tests
- Refactor suite to use common matrix utils (#33483)
🤖 CI
- Publish
@nuxt/nitro-serveron pkg-pr-new (b7ccf17bf) - Remove nitro-server publish until v4.2 is released (904d4f6ec)
❤️ Contributors
- 山吹色御守 (@KazariEX)
- Florian Heuberger (@Flo0806)
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Trung Dang (@NamesMT)
- 纸鹿/Zhilu (@L33Z22L11)
- Julien Huang (@huang-julien)
- Alexander Lichter (@TheAlexLichter)
- abeer0 (@iiio2)
- Max (@onmax)
- Daniel Slepov (@imslepov)
- Octavio Araiza (@8ctavio)
- Bobbie Goede (@BobbieGoede)
- DipakHalkude (@DipakHalkude)
- Aleksander Błaszkiewicz (@ablaszkiewicz)
- 4.1.36 Oct 2025
Release notes
Open source →4.1.3 is a regularly scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- vite: Use rolldown's replace plugin when applicable (#33258)
🩹 Fixes
- kit: Add default values when adding type references in
prepare:typeshook (#33239) - nuxt: Augment app config in server context (#33287)
- nuxt: Make lazy component types compatible with
h(#33046) - vite: Deduplicate inlined server style chunks (#33308)
- nuxt: Support
headoption onuseHead(#33318) - nuxt: Do not relativise importmap if
cdnURLis set (#33333) - nuxt: Resolve aliases in
imports.dirs(#33334) - nuxt: Add missing element/vnode props for
<NuxtLink>(#33335) - nuxt: Do not generate server placeholder components (#33345)
- nuxt: Dedupe generated component names (#33346)
- webpack: Test watch instance before closing it (0e5a0a5a0)
- nuxt: Correctly handle island rendering error (#33302)
- nuxt: Support
v-slot:fallbacklongform syntax in<DevOnly>(#33368) - nuxt: Support
typeFromwhen generating auto-import type templates (#33373) - nuxt: Don't trigger scroll when changing trailing slash (#33358)
- nuxt: Add stubs for new scripts from
@nuxt/scripts(bed410d60) - nuxt: Prevent duplicate execution on key change in
useAsyncData(#33325) - nuxt: Make middleware
_pathproperty configurable for HMR (#33379) - nuxt: Handle non-immediate
useAsyncDatawith different key on ssr (#33341)
💅 Refactors
- nuxt: Improve implementation of error composables (#33234)
- nuxt: Resolve path of
typed-router.d.tsearly for consistency (#33285) - nuxt: Move server references to
nitro:prepare:typeshook (#33286) - nuxt: Place
filenameintocomponentsIslandsTemplatedefinition (#33394) - nuxt,vite: Use environment-api compatible plugins (#33403)
📖 Documentation
- Add
4.xprefix to all internal links (#33264) - Fix more links (#33265)
- Update usage instructions for Windows users (#33284)
- Update app config paths to use app/app.config.ts (#33297)
- Remove d suffix in example (#33298)
- Move directory structure to top-level (#33299)
- Add information about
useFetchreactivity (#33317) - Add more
4.xprefixes in urls (47ea684c7) - Lint code samples within docs (#33271)
- Remove duplicated documentation from
nuxt.configpage (b438d44e1) - Remove docs for outdated asyncData configuration (3e4a999e6)
- Note
preparecommandNODE_ENVbehavior (#33330) - Update
nuxtcommand pages (#33336)
🏡 Chore
- Temporarily disable link to github sponsors (7e5375390)
- Update markdownlint ignore (19fc9abbb)
- Migrate pnpm settings out of
.npmrc(14514329b) - Ignore errors from npmjs (50febbbba)
- Lint (09a16d9df)
- nuxt: Align global components indent (#33340)
- Remove tea.yaml (5f567c79b)
- Remove todo comment as resolved (#33389)
✅ Tests
🤖 CI
- Add provenance action to check for downgrades in provenance (5ada6861e)
- Pass commit sha when triggering ecosystem ci (399df6bab)
❤️ Contributors
- Daniel Roe (@danielroe)
- 山吹色御守 (@KazariEX)
- Julien Huang (@huang-julien)
- Florian Heuberger (@Flo0806)
- Ondrej Brendy (@bandiasek)
- Octavio Araiza (@8ctavio)
- Alex Liu (@Mini-ghost)
- Bobbie Goede (@BobbieGoede)
- abeer0 (@iiio2)
- Harlan Wilton (@harlan-zw)
- Alexander Lichter (@TheAlexLichter)
- Sébastien Chopin (@atinux)
- Ben Hong (@bencodezen)
- Daniel Slepov (@imslepov)
- Huseyn Guliyev (@husayt)
- Hillary (@hillaryke)
- 4.1.212 Sept 2025
Release notes
Open source →4.1.2 is a regularly scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- kit: Do not normalise templates in loop if
dstis present (#33200) - nuxt: Remove watcher from
hydrate-whenlazy hydration strategy (#33199) - nuxt,schema: Normalise components + directories more efficiently (#33207)
- kit,nuxt: Reduce unnecessary iteration in nuxt code (#33212)
- nuxt: Skip running lazy hydration transform with filter (#33213)
🩹 Fixes
- schema: Add
pkg-typesto dependencies (9fe2541ca) - nuxt: Ignore errors when treeshaking composables within other composables (f99eac516)
- nuxt: Do not tree-shake composables within other composables (#33153)
- kit: Ensure module dependencies are typed correctly (4568e8451)
- nuxt: Prevent Infinity
backgroundSizein loading indicator (#33211) - nuxt: Remove unused
enabledfrom components dir options (#32844) - nuxt: Sync watch request in useAsyncData (#33192)
- nuxt: Move key imports logic after all modules run (#33214)
📖 Documentation
- Update reference to source dir (65712297a)
- Update language on bridge head migration (c9d986889)
- Update file path for pinia store (#33205)
- Add
app/suffix to a few links (#33217)
🏡 Chore
- Dedupe lockfile (d054c90d9)
- Suppress htmlnano type error (ff2e77809)
- nuxt: Unpin tinyglobby (b9ec6507b)
✅ Tests
- Update bundle size test (4d9feb00d)
❤️ Contributors
- Julien Huang (@huang-julien)
- Daniel Roe (@danielroe)
- Adrien Foulon (@Tofandel)
- Matej Černý (@cernymatej)
- Антон Стасюк (@11Alone11)
- wuiyang (@wuiyang)
- Revadike (@Revadike)
- kit: Do not normalise templates in loop if
- 4.1.15 Sept 2025
Release notes
Open source →v4.1.1 is a regularly scheduled patch release
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- nuxt: Correct relative path of auto imported components (#33122)
- nuxt: Prefer accessing
globalThisoverwindow(#33125) - nuxt: Migrate to AST-aware tree-shaking + route injection (#33128)
- nuxt: Ignore #components import mapping inside packages that use it internally (#33049)
- vite: Remove explicit vite-node configuration of
deps.inline(#33133) - nuxt: Include trace in dev-time
useRouteusage warning (#33039) - kit: Improve DX by displaying module name when possible (#33137)
- nuxt: Print route middleware path in warning (#33136)
- nuxt: Include core auto-imports from
imports:sourcesin override warning (#33050) - nuxt: Render relative importmap entry path if required (#33146)
📖 Documentation
- Add
--to bun create command (5e661f0ca) - Add
app/prefix in lots of cases (#33117) - Add JSDoc for
navigateTo(#21442)
🏡 Chore
- Correct
rou3github url (#33130) - Include
.tsextension (db9d840e1) - Build before releasing (25f9282a4)
🤖 CI
- Remove default discord reactions from thread (more noise than it's worth) (183913fe2)
- Rewrite release workflow in ts + support multiple tags (4469ead82)
- Pass correct flag (711037cda)
- Pass tag via env variable (fb83cd5ba)
- Drop
4xtags from releases (1cd8a6857)
❤️ Contributors
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Bobbie Goede (@BobbieGoede)
- Sébastien Chopin (@atinux)
- Octavio Araiza (@8ctavio)
- Michael Brevard (@GalacticHypernova)
- abeer0 (@iiio2)
- 山吹色御守 (@KazariEX)
- 4.1.02 Sept 2025
Release notes
Open source →👀 Highlights
🔥 Build and Performance Improvements
🍫 Enhanced Chunk Stability
Build stability has been significantly improved with import maps (#33075). This prevents cascading hash changes that could invalidate large portions of your build when small changes are made:
<!-- Automatically injected import map --> <script type="importmap">{"imports":{"#entry":"/_nuxt/DC5HVSK5.js"}}</script>By default, JS chunks emitted in a Vite build are hashed, which means they can be cached immutably. However, this can cause a significant issue: a change to a single component can cause every hash to be invalidated, massively increasing the chance of 404s.
In short:
- a component is changed slightly - the hash of its JS chunk changes
- the page which uses the component has to be updated to reference the new file name
- the entry now has its hash changed because it dynamically imports the page
- every other file which imports the entry has its hash changed because the entry file name is changed
Obviously this wasn't optimal. With this new feature, the hash of (otherwise) unchanged files which import the entry won't be affected.
This feature is automatically enabled and helps maintain better cache efficiency in production. It does require native import map support, but Nuxt will automatically disable it if you have configured
vite.build.targetto include a browser that doesn't support import maps.And of course you can disable it if needed:
export default defineNuxtConfig({ experimental: { entryImportMap: false } })🦀 Experimental Rolldown Support
Nuxt now includes experimental support for
rolldown-vite(#31812), bringing Rust-powered bundling for potentially faster builds.To try Rolldown in your Nuxt project, you need to override Vite with the rolldown-powered version since Vite is a dependency of Nuxt. Add the following to your
package.json:npm:
{ "overrides": { "vite": "npm:rolldown-vite@latest" } }pnpm:
{ "pnpm": { "overrides": { "vite": "npm:rolldown-vite@latest" } } }yarn:
{ "resolutions": { "vite": "npm:rolldown-vite@latest" } }bun:
{ "overrides": { "vite": "npm:rolldown-vite@latest" } }After adding the override, reinstall your dependencies. Nuxt will automatically detect when Rolldown is available and adjust its build configuration accordingly.
For more details on Rolldown integration, see the Vite Rolldown guide.
[!NOTE] This is experimental and may have some limitations, but offers a glimpse into the future of high-performance bundling in Nuxt.
🧪 Improved Lazy Hydration
Lazy hydration macros now work without auto-imports (#33037), making them more reliable when component auto-discovery is disabled:
<script setup> // Works even with components: false const LazyComponent = defineLazyHydrationComponent( 'visible', () => import('./MyComponent.vue') ) </script>This ensures that components that are not "discovered" through Nuxt (e.g., because
componentsis set tofalsein the config) can still be used in lazy hydration macros.📄 Enhanced Page Rules
If you have enabled experimental extraction of route rules, these are now exposed on a dedicated
rulesproperty onNuxtPageobjects (#32897), making them more accessible to modules and improving the overall architecture:// In your module nuxt.hook('pages:extend', pages => { pages.push({ path: '/api-docs', rules: { prerender: true, cors: true, headers: { 'Cache-Control': 's-maxage=31536000' } } }) })The
defineRouteRulesfunction continues to work exactly as before, but now provides better integration possibilities for modules.🚀 Module Development Enhancements
Module Dependencies and Integration
Modules can now specify dependencies and modify options for other modules (#33063). This enables better module integration and ensures proper setup order:
export default defineNuxtModule({ meta: { name: 'my-module', }, moduleDependencies: { 'some-module': { // You can specify a version constraint for the module version: '>=2', // By default moduleDependencies will be added to the list of modules // to be installed by Nuxt unless `optional` is set. optional: true, // Any configuration that should override `nuxt.options`. overrides: {}, // Any configuration that should be set. It will override module defaults but // will not override any configuration set in `nuxt.options`. defaults: {} } }, setup (options, nuxt) { // Your module setup logic } })This replaces the deprecated
installModulefunction and provides a more robust way to handle module dependencies with version constraints and configuration merging.🪝 Module Lifecycle Hooks
Module authors now have access to two new lifecycle hooks:
onInstallandonUpgrade(#32397). These hooks allow modules to perform additional setup steps when first installed or when upgraded to a new version:export default defineNuxtModule({ meta: { name: 'my-module', version: '1.0.0', }, onInstall(nuxt) { // This will be run when the module is first installed console.log('Setting up my-module for the first time!') }, onUpgrade(inlineOptions, nuxt, previousVersion) { // This will be run when the module is upgraded console.log(`Upgrading my-module from v${previousVersion}`) } })The hooks are only triggered when both
nameandversionare provided in the module metadata. Nuxt uses the.nuxtrcfile internally to track module versions and trigger the appropriate hooks. (If you haven't come across it before, the.nuxtrcfile should be committed to version control.)[!TIP] This means module authors can begin implementing their own 'setup wizards' to provide a better experience when some setup is required after installing a module.
🙈 Enhanced File Resolution
The new
ignoreoption forresolveFiles(#32858) allows module authors to exclude specific files based on glob patterns:// Resolve all .vue files except test files const files = await resolveFiles(srcDir, '**/*.vue', { ignore: ['**/*.test.vue', '**/__tests__/**'] })📂 Layer Directories Utility
A new
getLayerDirectoriesutility (#33098) provides a clean interface for accessing layer directories without directly accessing private APIs:import { getLayerDirectories } from '@nuxt/kit' const layerDirs = await getLayerDirectories(nuxt) // Access key directories: // layerDirs.app - /app/ by default // layerDirs.appPages - /app/pages by default // layerDirs.server - /server by default // layerDirs.public - /public by default✨ Developer Experience Improvements
🎱 Simplified Kit Utilities
Several kit utilities have been improved for better developer experience:
addServerImportsnow supports single imports (#32289):
// Before: required array addServerImports([{ from: 'my-package', name: 'myUtility' }]) // Now: can pass directly addServerImports({ from: 'my-package', name: 'myUtility' })🔥 Performance Optimizations
This release includes several internal performance optimizations:
- Improved route rules cache management (#32877)
- Optimized app manifest watching (#32880)
- Better TypeScript processing for page metadata (#32920)
🐛 Notable Fixes
- Improved
useFetchhook typing (#32891) - Better handling of TypeScript expressions in page metadata (#32902, #32914)
- Enhanced route matching and synchronization (#32899)
- Reduced verbosity of Vue server warnings in development (#33018)
- Better handling of relative time calculations in
<NuxtTime>(#32893)
✅ Upgrading
As usual, our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will refresh your lockfile and pull in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- kit: Add
ignoreoption toresolveFiles(#32858) - kit: Add
onInstallandonUpgrademodule hooks (#32397) - nuxt,vite: Add experimental support for
rolldown-vite(#31812) - nuxt: Extract
defineRouteRulesto pagerulesproperty (#32897) - nuxt,vite: Use importmap to increase chunk stability (#33075)
- nuxt: Lazy hydration macros without auto-imports (#33037)
- kit,nuxt,schema: Allow modules to specify dependencies (#33063)
- kit,nuxt: Add
getLayerDirectoriesutil and refactor to use it (#33098)
🔥 Performance
- nuxt: Clear inline route rules cache when pages change (#32877)
- nuxt: Stop watching app manifest once a change has been detected (#32880)
🩹 Fixes
- nuxt: Handle
satisfiesin page augmentation (#32902) - nuxt: Type response in
useFetchhooks (#32891) - nuxt: Add TS parenthesis and as expression for page meta extraction (#32914)
- nuxt: Use correct unit thresholds for relative time (#32893)
- nuxt: Handle uncached current build manifests (#32913)
- kit: Resolve directories in
resolvePathand normalize file extensions (#32857) - schema,vite: Bump
requestTimeout+ allow configuration (#32874) - nuxt: Deep merge extracted route meta (#32887)
- nuxt: Do not expose app components until fully resolved (#32993)
- kit: Only exclude
node_modules/if no customsrcDir(#32987) - nuxt: Transform ts before page meta extraction (#32920)
- nuxt: Compare final matched routes when syncing
routeobject (#32899) - nuxt: Make vue server warnings much less verbose in dev mode (#33018)
- schema: Allow disabling cssnano/autoprefixer postcss plugins (#33016)
- kit: Ensure local layers are prioritised alphabetically (#33030)
- kit,nuxt: Expose global types to vue compiler (#33026)
- deps: Bump devalue (#33072)
- nuxt: Support config type inference for
defineNuxtModule().with()(#33081) - nuxt: Search for colliding names in route children (b58c139d2)
- nuxt: Delete
nuxtApp._runningTransitionon resolve (#33025) - nuxt: Add validation for nuxt island reviver key (#33069)
💅 Refactors
- nuxt: Simplify page segment parsing (#32901)
- nuxt: Remove unnecessary
async/awaitinafterEach(#32999) - vite: Simplify inline chunk iteration (6f4da1b8c)
- kit,nuxt,ui-templates,vite: Address deprecations + improve regexp perf (#33093)
📖 Documentation
- Switch example to use vitest projects (#32863)
- Update testing
setupTimeoutand addteardownTimeout(#32868) - Update
webRootto use new app directory (df7177bff) - Add middleware to layers guide (6fc25ff79)
- Use
app/directory in layer guide (eee55ea41) - Add documentation for
--nightlycommand (#32907) - Update package information in roadmap section (#32881)
- Add more info about nuxt spa loader element attributes (#32871)
- Update
features.inlineStylesdefault value (6ff3fbebb) - Correct filename in example (#33000)
- Add more information about using
useRouteand accessing route in middleware (#33004) - Avoid variable shadowing in locale example (#33031)
- Add documentation for module lifecycle hooks (#33115)
🏡 Chore
- config: Migrate renovate config (#32861)
- Remove stray test file (ca84285cc)
- Ignore webpagetest.org when scanning links (6c974f0be)
- Add
type: 'module'in playground (#33099)
✅ Tests
- Add failing test for link component duplication (#32792)
- Simplify module hook tests (#32950)
- Refactor stubbing of
import.meta.dev(#33023) - Use
findWorkspaceDirrather than relative paths to repo root (a6dec5bd9) - Improve router test for global transitions (5d783662c)
- Use
expect.poll(53fb61d5d) - Use
expect.pollinstead ofexpectWithPolling(357492ca7) - Use
vi.waitUntilinstead of custom retry logic (611e66a47)
🤖 CI
- Remove double set of tests for docs prs (6bc9dccf4)
- Add workflow for discord team discussion threads (bc656a24d)
- Fix some syntax issues with discord + github integrations (f5f01b8c1)
- Use token for adding issue to project (66afbe0a2)
- Use discord bot to create thread automatically (618a3cd40)
- Only use discord bot (bfd30d8ce)
- Update format of discord message (eb79a2f07)
- Try bolding entire line (c66124d7b)
- Oops (38644b933)
- Add delay after adding each reaction (ecb49019f)
- Use last lts node version for testing (e06e37d02)
- Try npm trusted publisher (85f1e05eb)
- Use npm trusted publisher for main releases (abf5d9e9f)
- Change wording (#32979)
- Add github ai moderator (#33077)
❤️ Contributors
- Daniel Roe (@danielroe)
- abeer0 (@iiio2)
- Julien Huang (@huang-julien)
- kyumoon (@kyumoon)
- Alexander Lichter (@TheAlexLichter)
- Bobbie Goede (@BobbieGoede)
- Rich Harris (@Rich-Harris)
- mustafa60x (@mustafa60x)
- Matej Černý (@cernymatej)
- Alex Liu (@Mini-ghost)
- Amitav Chris Mostafa (@semibroiled)
- Romain Hamel (@romhml)
- Jacky Lam (@jackylamhk)
- Mukund Shah (@mukundshah)
- Luke Nelson (@luc122c)
- letianpailove (@letianpailove)
- Erwan Jugand (@erwanjugand)
- Alexander (@TheColorman)
- Ryota Watanabe (@wattanx)
- Yizack Rangel (@Yizack)
- 4.0.35 Aug 2025
Release notes
Open source →4.0.3 is a regularly scheduled patch release.
👉 Changelog
🔥 Performance
- kit: Get absolute path from
tinyglobbyinresolveFiles(#32846)
🩹 Fixes
- nuxt: Do not throw undefined
errorvariable (#32807) - vite: Include tsconfig references during
typeCheck(#32835) - nuxt: Add sourcemap path transformation for client builds (#32313)
- nuxt: Add warning for lazy-hydration missing prefix (#32832)
- nuxt: Trigger call once navigation even when no suspense (#32827)
- webpack: Handle
nullresult from webpack call (84816d8a1) - kit,nuxt: Use
reverseResolveAliasfor better errors (#32853)
📖 Documentation
- Fix publicDir alias (#32841)
- Mention
bun.lockfor lockfile (#32820) - Add a section about augmenting types with TS project references (#32843)
- Improve explanation of global middleware (#32855)
🏡 Chore
- Update reproduction help text links (#32803)
- Update pnpm ignored build scripts (#32849)
- Improve internal types (052b98a35)
✅ Tests
- Move tests for
defineNuxtComponentout of e2e test (#32848)
🤖 CI
- Move nightly releases into different concurrency group (664041be7)
❤️ Contributors
- RDistinct (@RDistinct)
- Daniel Roe (@danielroe)
- Oskar Lebuda (@OskarLebuda)
- Peter Budai (@peterbud)
- Matej Černý (@cernymatej)
- Damian Głowala (@DamianGlowala)
- Bobbie Goede (@BobbieGoede)
- Robin (@OrbisK)
- abeer0 (@iiio2)
- Julien Huang (@huang-julien)
- kit: Get absolute path from
- 4.0.229 Jul 2025
Release notes
Open source →4.0.2 is the next patch release.
Timetable: 28 July.
👉 Changelog
🩹 Fixes
- nuxt: Provide typed slots for
<ClientOnly>and<DevOnly>(#32707) - kit,nuxt,schema: Add trailing slash to some dir aliases (#32755)
- nuxt: Constrain global
defineAppConfigtype (#32760) - kit: Include module types in
appcontext (#32758) - nuxt: Include source base url for remote islands (#32772)
- vite: Use vite node server to transform requests (#32791)
- kit: Use
mllyto parse module paths (#32386) - nuxt: Execute all plugins after error rendering error.vue (#32744)
📖 Documentation
- Update Nuxt installation command to use
npm create nuxt@latest(#32726) - Add AI-assisted contribution guidelines (#32725)
- Hydration best practice (#32746)
- Add example for module
.with()(#32757) - Replace dead Vue Router docs links (#32779)
- Update nightly version references (#32776)
🏡 Chore
- Update reproduction links for bug-report template (#32722)
- Update
unbuildand use absolute path in dev stubs (#32759)
✅ Tests
- Ignore vue
module.exportsexport (c4317e057)
🤖 CI
- Release
pkg.pr.newformain/3.xbranches as well (b0f289550) - Apply
3xtag to latest v3 release (5f6c27509)
❤️ Contributors
- Daniel Roe (@danielroe)
- Bobbie Goede (@BobbieGoede)
- Damian Głowala (@DamianGlowala)
- Bobby (@xanzhu)
- Dog (@dgxo)
- Julien Huang (@huang-julien)
- Stephen Jason Wang (@stephenjason89)
- Mateleo (@Mateleo)
- Robin (@OrbisK)
- Alex Liu (@Mini-ghost)
- nuxt: Provide typed slots for
- 4.0.121 Jul 2025
Release notes
Open source →v4.0.1 is the first regularly scheduled patch release of v4
It will be followed up later this week with v3.18, which will backport a number of the features/fixes from Nuxt v4 to v3.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- nuxt: Add
nuxt.schemafiles to node tsconfig context (#32644) - nuxt,vite: Unpin
nitropack(ed5ad64ad) - nuxt: Expose shared aliases within
shared/dir (#32676)
💅 Refactors
- nuxt: Pass file language directly to parser options (#32665)
📖 Documentation
- Remove rc tag in guide (232b14e2f)
- Remove
-t v4tag from getting started (343f59235) - Added new Shared folder to the example of v4 folder structure (#32630)
- Update nuxt.new links to v4 (#32639)
- Improve grammar (#32640)
- Typos (#32567)
- Fix abbreviation (#32613)
- Reference
noUncheckedIndexedAccessrule change in v4 guide (#32643) - Add missing import in alias config example (#32648)
- Correct alias for local fonts in styling guide (#32680)
- Add best practices section (#31609)
- Fix links to Nitro docs (#32691)
📦 Build
- vite: Specify
nitropacktypes as external (39be1b3a9)
🏡 Chore
- Handle missing commit details (5018ed23a)
🤖 CI
- Trigger website redeploy on main branch (#32695)
❤️ Contributors
- Julien Huang (@huang-julien)
- Alois Sečkár (@AloisSeckar)
- Hashim Kalam (@hashimkalam)
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Peter Buglavecz (@buglavecz)
- Haythem Frikha (@Flamenate)
- abeer0 (@iiio2)
- Damian Głowala (@DamianGlowala)
- Robin (@OrbisK)
- Thomas (@ThomasWT)
- nuxt: Add
- 4.0.015 Jul 2025
Release notes
Open source →Nuxt 4.0 is here! 🎉
After a year of real-world testing, we're excited to announce the official release of Nuxt 4. This is a stability-focused major release, introducing a few thoughtful breaking changes in order to improve development experience.
If you've been following along, you'll recognize many of these features and changes — and if you're new to them, we hope you'll welcome them.
🔥 What's new?
Nuxt 4 is all about making your development experience smoother:
- Cleaner project organization with the new
app/directory structure - Smarter data fetching - we've taken the opportunity to address some inconsistencies and improve performance with the data layer
- Better TypeScript support with project-based separation between the different contexts in your project - app code, server code,
shared/folder, and configuration - Faster CLI and development with adoption of internal sockets and a faster CLI
Why these features in particular? Mostly because these kind of improvements have required making changes that are technically breaking.
In general, we aim for a hype-free approach to releases. Rather than save up features for a big release, we've been shipping improvements in Nuxt 3 minor releases.
We've also spent a lot of time figuring out how to implement these changes in a backwards-compatible way, and I hope that means that most Nuxt 3 projects can upgrade with a minimum of effort.
I'd advise reading through the upgrade guide before you start, to understand what areas of your app might be affected.
🗂️ New project structure
The biggest visible change is how projects are organized. Your application code now lives in an
app/directory by default:my-nuxt-app/ ├─ app/ │ ├─ components/ │ ├─ pages/ │ ├─ layouts/ │ └─ app.vue ├─ public/ ├─ shared/ ├─ server/ └─ nuxt.config.tsThis helps keep your code separate from
node_modules/and.git/, which makes file watchers faster (especially on Windows and Linux). It also gives your IDE better context about whether you're working with client or server code.[!TIP] Don't want to migrate? That's totally fine! Nuxt will detect your existing structure and keep working exactly as before.
🎨 Updated UI templates
Nuxt’s starter templates have an all new look, with improved accessibility, default titles, and template polish (#27843).
🔄 Smarter data fetching
We've made
useAsyncDataanduseFetchwork better. Multiple components using the same key now share their data automatically. There's also automatic cleanup when components unmount, and you can use reactive keys to refetch data when needed. Plus, we've given you more control over when cached data gets used.Some of these features have already been made available in Nuxt v3 minor releases, because we've been rolling this out gradually. Nuxt v4 brings different defaults, and we expect to continue to work on this data layer in the days to come.
🔧 Better TypeScript experience
Nuxt now creates separate TypeScript projects for your app code, server code,
shared/folder, and builder code. This should mean better autocompletion, more accurate type inference and fewer confusing errors when you're working in different contexts.[!TIP] With Nuxt 4, you will only need one
tsconfig.jsonfile in your project root!This is probably the single issue that is most likely to cause surprises when upgrading, but it should also make your TypeScript experience much smoother in the long run. Please report any issues you encounter. 🙏
⚡ Faster CLI and development
In parallel with the release of v4, we've been working on speeding up
@nuxt/cli.- Faster cold starts - Development server startup is noticeably faster
- Node.js compile cache - Automatic reuse of the v8 compile cache
- Native file watching - Uses
fs.watchAPIs for fewer system resources - Socket-based communication - The CLI and Vite dev server now communicate via internal sockets instead of network ports, reducing overhead — particularly on Windows
These improvements combined can make a really noticeable difference in your day-to-day development experience, and we have more planned.
🚀 How to upgrade
Although any major release brings breaking changes, one of our main aims for this release is to ensure that the upgrade path is as smooth as possible. Most of the breaking changes have been testable with a compatibility flag for over a year.
Most projects should upgrade smoothly, but there are a few things to be aware of:
- Nuxt 2 compatibility has been removed from
@nuxt/kit. (This will particularly affect module authors.) - Some legacy utilities and deprecated features have been cleaned up.
- The new TypeScript setup might surface some type issues that were hidden before.
- A few modules might need further updates for full Nuxt 4 compatibility.
Don't worry though — for most breaking changes, there are configuration options to revert to the old behavior while you adjust.
1. Update Nuxt
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
2. Optional: use migration tools
We’ve also partnered with Codemod to automate many, though not all, migration steps:
npx codemod@latest nuxt/4/migration-recipe3. Test and adjust
Run your tests, check that everything builds correctly, and fix any issues that come up. The upgrade guide has detailed migration steps for specific scenarios.
We'd recommend reading through it in full before starting your upgrade, to understand what areas of your app might be affected.
🗺️ What's next?
We're planning quick patch releases to address any issues that come up. Nuxt 3 will continue to receive maintenance updates (both bug fixes and backports of features from Nuxt 4) until the end of January 2026, so there's no rush if you need time to migrate.
Looking ahead, we plan to release Nuxt 5 on the sooner side, which will bring Nitro v3 and h3 v2 for even better performance, as well as adopting the Vite Environment API for an improved (and faster!) development experience. And there's a lot more in the works too!
And, quite apart from major releases, we have a lot of exciting features planned to make their way into Nuxt 3.x and 4.x release branches, including support for SSR streaming (#4753), a first-party accessibility module (#23255), built-in fetch caching strategies (#26017), more strongly typed fetch calls (landing in Nitro v3), dynamic route discovery (#32196), multi-app support (#21635) and more.
❤️ Thank you
This release is credit to so many people, particularly those who have been testing v4 compatibility mode over the past year. I'm really grateful — thank you for all your help!
Happy coding with Nuxt 4! 🚀
👉 Changelog
🚀 Enhancements
- ui-templates: Update template branding for v4 (#27843)
- deps: Upgrade to latest versions of c12, jiti and unbuild (#27995)
- kit: Reimplement cjs utils using
mlly(#28012) - nuxt: Generate basic jsdoc for module config entry (#27689)
- schema: Split dev/prod build directories (#28594)
- nuxt: Cache vue app build outputs (#28726)
- deps: Update dependency vite to v6 (main) (#30042)
- nuxt: Add integration with chrome devtools workspaces (#32084)
- kit: Support single import in
addServerImports(#32289) - nuxt: Add
onWatcherCleanupto imports presets (#32396) - kit,nuxt,schema: Separate ts projects for node/app/nitro (#30665)
- nuxt: Support lazy hydration macros (#31192)
- nuxt: Export
<NuxtTime>prop types (#32547) - nuxt: Add route announcer to default app.vue (#32621)
- nuxt: Expose page routes to nitro for o11y (#32617)
🔥 Performance
- nuxt: ⚠️ Don't call
render:htmlfor server islands (#27889) - vite: Don't write stub manifest for legacy bundler (#27957)
- kit: Update env expansion regex to match nitro (#30766)
- vite: Communicate with vite-node via internal socket (#32417)
🩹 Fixes
- schema,vite: ⚠️ Do not allow configuring vite dev bundler (#27707)
- schema: ⚠️ Default to
compatibilityVersion: 4(#27710) - nuxt: ⚠️ Emit absolute paths in
builder:watchhook (#27709) - nuxt: ⚠️ Improve default
asyncDatavalue behaviour (#27718) - nuxt: ⚠️ Remove old experimental options (#27749)
- kit: ⚠️ Support loading nuxt 4 and drop support for <=2 (#27837)
- nuxt: ⚠️ Remove
__NUXT__after hydration (#27745) - ui-templates: Add default title back (3415241a6)
- kit: ⚠️ Drop support for building nuxt 2 projects (1beddba6a)
- nuxt: ⚠️ Bump internal majorVersion to
4(7aae4033b) - kit: Mark
resolvePathutils as sync (655e1473d) - kit: Revert change to
tryResolveModule(2d136e04c) - kit: Add back
requireModuleandtryRequireModule(#28013) - nuxt: Hide unhandled error messages in prod (#28156)
- nuxt: Add
useScriptCrispscripts stub (0c3cc4cf3) - nuxt: ⚠️ Remove unused
globalNameproperty (#28391) - nuxt: Use static import for
updateAppConfigin HMR (#28349) - vite: Write dev manifest when
ssr: false(#28488) - kit,nuxt,schema: ⚠️ Remove other support for nuxt2/bridge (#28936)
- webpack: Only insert dynamic require plugin when building (b619b35e9)
- nuxt: Guard
windowaccess (d874726ff) - nuxt: Remove unneeded subpath import (18a6ef1ca)
- webpack: Handle new webpack chunk format (d293c06d2)
- kit: ⚠️ Do not check compatibility for nuxt version < 2.13 (f94cda4c8)
- ui-templates: Fix examples link and add bluesky (#30866)
- vite: Use
resolveIdfromvite-nodeto resolve deps (#30922) - nuxt: Import
isEqualfrom mainohashexport (3ec1a1e5e) - vite: Don't set
output.preserveModules(ce49734aa) - nuxt: Ignore
#app-manifestimport in dev mode (#31539) - nuxt: Ensure layer array-type config is merged in order (#31507)
- schema: Turn off
purgeCachedDatauntil v4 (7aa3a01ae) - schema: Re-enable
purgeCachedDataby default (06745604c) - webpack: Expand dynamic require regexp to match new pattern (62e700daa)
- nuxt: Add back missing reset of
.execute(d79e14612) - nuxt,schema: ⚠️ Remove support for
compatibilityVersion: 3(#32255) - kit,nuxt,schema,vite: ⚠️ Remove support for some deprecated options (#32257)
- nuxt: ⚠️ Don't rerun asyncdata w/ existing data in
useAsyncData(#32170) - nuxt: Scan nitro handlers before writing types (a3698c08b)
- nuxt: Force asyncData
errorValue/valueto be undefined (7e4eac655) - nuxt: ⚠️ Remove public and assets aliases (#32119)
- webpack: Update dynamic require pattern (#32278)
- schema: ⚠️ Remove top level generate option (#32355)
- ui-templates: Add aria tag on Nuxt logo (#32429)
- nuxt: Augment runtime config in server context (#32482)
- kit: Do not skip layer with defined
srcDir(#32487) - deps: Upgrade to rc version of
@nuxt/cli(#32488) - kit: Ensure legacy
tsConfigdoesn't exclude too many types (#32528) - kit: Ensure types of module entrypoints are in node project (#32551)
- kit: Add layer
app/andserver/folders into tsconfigs (#32592) - schema: Disable changing compat version (#32600)
- nuxt: Allow modules to add to
typescript.hoist(#32601) - nuxt: Include shared declarations in
tsconfig.server.json(#32594) - nuxt: Retain old data when computed key changes (#32616)
- nuxt: ⚠️ Bump
compatibilityDateto2025-07-15(e35e1ccb9) - nuxt: Only use
scrollBehaviorTypefor hash scrolling (#32622)
💅 Refactors
- kit,nuxt: ⚠️ Drop nuxt 2 + ejs template compile support (#27706)
- nuxt: ⚠️ Move
#app/components/layout->#app/components/nuxt-layout(209e81b60) - kit,nuxt,vite,webpack: ⚠️ Remove legacy require utils (#28008)
- nuxt: Simplify check of
dedupeoption (#28151) - nuxt: Use direct import of
installNuxtModule(501ccc375) - kit: Remove internal function (#32189)
- schema: ⚠️ Remove config.schema.json export + defaults (#32254)
- nuxt: Migrate to
oxc-walker(#32250) - nuxt,schema: Use oxc for
onPrehydratetransform (#32045)
📖 Documentation
- Indicate what
useAsyncDatamust return (#28259) - Update
deepdefault foruseAsyncData&useFetch(#28564) - Fix link to issue (4d13f1027)
- Improve wording for
deepoption (bec85dfcd) - Update v4 docs with new folder structure (#32348)
- Update
.nuxtignoreexamples for v4 structure (#32489) - Add reference to
useNuxtDatain data fetching composable pages (#32589) - Temporarily use v4 template for v4 docs (850a879d3)
- Document the --modules flag in the init command (#32599)
📦 Build
- deps: Bump esbuild from 0.23.1 to 0.25.0 (#31247)
🏡 Chore
- Manage update to
vite-plugin-checkerseparately (02d46dd3d) - Update docs typecheck command (#28433)
- Improve accuracy of 4.x changelog (#28706)
- Bump package versions internally to v4 (16fab7778)
- kit: Fix regressed version v4 (a1c052057)
- Dedupe lockfile (f14ef6bc9)
- Update once more (4d22f4d5a)
- Specify workspace
engines.nodecompatibility (a26322f5f) - Remove special treatment for typescript (08766a0cd)
- Reenable quarantine for webpack/memfs (for 3.x benefit) (9cb94e55e)
- Remove extra dep (f0ec34298)
- Add back
nuxi(9aa4c7c3b) - Remove stray
nuxiversion again (#30547) - Fix lockfile (7d345c714)
- Remove second version of vitest (#30868)
- Ignore
oxc-parserupdates temporarily (1cd0fb5cb) - Ignore
nitro/templatesdirectory (e531477f8) - Fix ui-templates build (c8a1b9e80)
- Mkdir for ui-templates (853408a1e)
- Add webpack resolution (088bcd459)
- Migrate playground + test fixtures to new directory format (#32357)
- schema: Remove duplicated documentation (349f75447)
✅ Tests
- Remove unused experimental options (6d971ddc9)
- Add additional
attwtest for built packages (#30206) - Add minimal pages fixture (#30457)
- Update bundle size assertion (f458153d9)
- Update bundle size assertion (4cce6bf8d)
- Benchmark minimal fixture instead (#31174)
- Normalise scoped css + pass logger to
configResolved(8d3bd4f9f) - More precise asyncData tests (023fb13eb)
- Extend timeout when waiting for hydration (f34c6c240)
- Also assert status (4f6bdf755)
🤖 CI
- Bump node v22 (#30251)
- Run workflows on merge groups (ff37ad9df)
- Do not invoke semantic-pr test on merge groups (fadd618d1)
⚠️ Breaking Changes
- nuxt: ⚠️ Don't call
render:htmlfor server islands (#27889) - schema,vite: ⚠️ Do not allow configuring vite dev bundler (#27707)
- schema: ⚠️ Default to
compatibilityVersion: 4(#27710) - nuxt: ⚠️ Emit absolute paths in
builder:watchhook (#27709) - nuxt: ⚠️ Improve default
asyncDatavalue behaviour (#27718) - nuxt: ⚠️ Remove old experimental options (#27749)
- kit: ⚠️ Support loading nuxt 4 and drop support for <=2 (#27837)
- nuxt: ⚠️ Remove
__NUXT__after hydration (#27745) - kit: ⚠️ Drop support for building nuxt 2 projects (1beddba6a)
- nuxt: ⚠️ Bump internal majorVersion to
4(7aae4033b) - nuxt: ⚠️ Remove unused
globalNameproperty (#28391) - kit,nuxt,schema: ⚠️ Remove other support for nuxt2/bridge (#28936)
- kit: ⚠️ Do not check compatibility for nuxt version < 2.13 (f94cda4c8)
- nuxt,schema: ⚠️ Remove support for
compatibilityVersion: 3(#32255) - kit,nuxt,schema,vite: ⚠️ Remove support for some deprecated options (#32257)
- nuxt: ⚠️ Don't rerun asyncdata w/ existing data in
useAsyncData(#32170) - nuxt: ⚠️ Remove public and assets aliases (#32119)
- schema: ⚠️ Remove top level generate option (#32355)
- nuxt: ⚠️ Bump
compatibilityDateto2025-07-15(e35e1ccb9) - kit,nuxt: ⚠️ Drop nuxt 2 + ejs template compile support (#27706)
- nuxt: ⚠️ Move
#app/components/layout->#app/components/nuxt-layout(209e81b60) - kit,nuxt,vite,webpack: ⚠️ Remove legacy require utils (#28008)
- schema: ⚠️ Remove config.schema.json export + defaults (#32254)
❤️ Contributors
- Daniel Roe (@danielroe)
- Connor Pearson (@cjpearson)
- Stephen Jason Wang (@stephenjason89)
- dwood-csi (@dwood-csi)
- Alex (@hywax)
- Alex Liu (@Mini-ghost)
- Bobbie Goede (@BobbieGoede)
- Marko (@aussieboi)
- Igor Kononenko (@igorexa34314)
- Alexander Lichter (@TheAlexLichter)
- Robin (@OrbisK)
- Matej Černý (@cernymatej)
- Michael Brevard (@GalacticHypernova)
- Andrej Adamcik (@adamcikado)
- dependabot[bot] (@dependabot[bot])
- Sébastien Chopin (@atinux)
- Yauheni Vasiukevich (@EvgenyWas)
- @beer (@iiio2)
- Anthony Fu (@antfu)
- pan93412 (@pan93412)
- Tobias Diez (@tobiasdiez)
- Aleksei Nagovitsyn (@al3xnag)
- xjccc (@xjccc)
- Julien Huang (@huang-julien)
- Cleaner project organization with the new
- 4.0.0-rc.07 Jul 2025pre-release
Release notes
Open source →4.0.0-rc.0 is our first release candidate.
🗺️ Roadmap
This is our first release candidate. From now on we're focusing on bug fixes only until the release of v4 (we don't expect to merge additional features or breaking changes unless unexpectedly necessary to resolve bugs).
We'd like to encourage users to test out adopting v4 from now on - feedback very welcome 🙏
👉 Read more at https://nuxt.com/blog/roadmap-v4
👉 Changelog
🚀 Enhancements
- nuxt: Export <NuxtTime> prop types (#32547)
🩹 Fixes
- nuxt: Skip external <NuxtLink>'s custom on click handler (#32499)
- nuxt: Safe-guard extraPageMetaExtractionKeys (#32510)
- nuxt: Expose loadBuilder error cause (3e0408bd8)
- vite: Handle resolving string vite input (#32527)
- kit: Ensure legacy tsConfig doesn't exclude too many types (#32528)
- nuxt: Wrap only server components with island generic (#32540)
- vite: Ignore when client entry cannot be resolved (6037b93dc)
- kit: Ensure types of module entrypoints are in node project (#32551)
📖 Documentation
- Adjust wording to reduce confusion in lifecycle section (#32503)
- Update fetch types (#32522)
- Clarify that runtime env variables must start with NUXT_ (#32223)
✅ Tests
❤️ Contributors
- Andrei Hudalla (@paranoidPhantom)
- Daniel Roe (@danielroe)
- Alex (@hywax)
- Julien Huang (@huang-julien)
- Sigrid Huemer (@s1gr1d)
- @xjccc
- Alex Liu (@Mini-ghost)
- Damian Głowala (@DamianGlowala)
- 4.0.0-alpha.427 Jun 2025pre-release
Release notes
Open source →4.0.0-alpha.4 is the fourth alpha release of Nuxt 4 for early testing
🗺️ Roadmap
👉 Read more at https://nuxt.com/blog/roadmap-v4
👉 Changelog
🚀 Enhancements
- nuxt: Support lazy hydration macros (#31192)
🩹 Fixes
- nuxt: Ensure
asyncDataruns if changing key while fetcher is running (#32466) - kit: Do not skip layer with defined
srcDir(#32487) - deps: Upgrade to rc version of
@nuxt/cli(#32488)
📖 Documentation
- Update
.nuxtignoreexamples for v4 structure (#32489)
❤️ Contributors
- Daniel Roe (@danielroe)
- Alex Liu (@Mini-ghost)
- Robin (@OrbisK)
- 4.0.0-alpha.326 Jun 2025pre-release
Release notes
Open source →4.0.0-alpha.3 is the third alpha release of Nuxt 4 for early testing
🗺️ Roadmap
👉 Read more at https://nuxt.com/blog/roadmap-v4
👉 Changelog
🚀 Enhancements
- nuxt: Add
onWatcherCleanupto imports presets (#32396) - kit,nuxt,schema: Separate ts projects for node/app/nitro (#30665)
🔥 Performance
- nuxt: Decrease if checks when prerendering (#32455)
- vite: Communicate with vite-node via internal socket (#32417)
🩹 Fixes
- nuxt: Handle pure hash link clicks with
navigateTo(#32393) - nuxt: Set
output.generatedCode.symbolsfor nitro build (#32358) - nuxt: Normalize segment catchall pattern before checking for parent (#32413)
- nuxt: Lazily access runtimeConfig (#32428)
- ui-templates: Add aria tag on Nuxt logo (#32429)
- nuxt: Reload at base URL in
nuxt:chunk-reload-immediate(#32382) - nuxt: Use rollup to calculate island component filenames (#32421)
- nuxt: Augment runtime config in server context (#32482)
- nuxt: Append
set-cookieheaders in error handler (#32483)
💅 Refactors
- vite: Migrate plugins internally to vite environments (#32461)
📖 Documentation
- Capitalise title (#32426)
- Mention
bun.lockfor lockfile (#32427) - Clarify where logging tag is displayed (#32440)
- Remove kit playground auto-import note (#32415)
- Migrate to
h3js(#32243) - Update the fetch
clearfunction description (#32287) defineNuxtPluginfunction documentation (#32328)- Mention that
<NuxtLink>encodes query params (#32361) - Enhance documentation for Nuxt composables (#32218)
🏡 Chore
- Rename deprecated vitest
workspacetoprojects(#32388) - Remove space in URL in comment (#32394)
- Allow setting TAG on commandline (43ac8ef01)
- Update stackblitz reproduction link (6996303c2)
✅ Tests
- nuxt: Add case for key only changes with
immediate: false(#32473) - Separate nuxt legacy runtime tests (#32481)
❤️ Contributors
- Daniel Roe (@danielroe)
- Robin (@OrbisK)
- Bobbie Goede (@BobbieGoede)
- Ibrahimm (@Ibra-cesar)
- Peter Budai (@peterbud)
- Ali Soueidan (@lazercaveman)
- Vachmara (@vachmara)
- xjccc (@xjccc)
- abeer0 (@iiio2)
- David Stack (@davidstackio)
- Damian Głowala (@DamianGlowala)
- Mihailo Bursac (@djixadin)
- Marko (@aussieboi)
- Ezra Ashenafi (@Eazash)
- Igor Kononenko (@igorexa34314)
- 翠 (@sapphi-red)
- nuxt: Add
- 4.0.0-alpha.212 Jun 2025pre-release
Release notes
Open source →4.0.0-alpha.2 is the second alpha release of Nuxt 4 for early testing
🗺️ Roadmap
👉 Read more at https://nuxt.com/blog/roadmap-v4
👉 Changelog
🚀 Enhancements
- kit: Support single import in
addServerImports(#32289)
🩹 Fixes
- webpack: Update dynamic require pattern (#32278)
- nuxt: Update component loader regexp for minified code (#32298)
- nuxt: Allow camelCase for lazy hydration attributes (#32297)
- nuxt: Respect
inheritAttrs: falseincreateClientOnlyfn (#32323) - kit: Do not double-urlify file urls when resolving schema (#32354)
- schema: ⚠️ Remove top level generate option (#32355)
- nuxt: Align scroll behavior with page transition completion (#32239)
📖 Documentation
🏡 Chore
- Update copilot instructions (483c05c9d)
- Migrate playground + test fixtures to new directory format (#32357)
- schema: Remove duplicated documentation (349f75447)
🤖 CI
- Set correct base branch label (#32325)
⚠️ Breaking Changes
- schema: ⚠️ Remove top level generate option (#32355)
❤️ Contributors
- Alex Liu (@Mini-ghost)
- Daniel Roe (@danielroe)
- Damian Głowala (@DamianGlowala)
- Bobbie Goede (@BobbieGoede)
- Julien Huang (@huang-julien)
- kit: Support single import in
- 4.0.0-alpha.12 Jun 2025pre-release
Release notes
Open source →4.0.0-alpha.1 is the first alpha release of Nuxt 4 for early testing
We originally planned Nuxt 4 for June 2024, but things don't always go according to plan. I think it's appropriate to take a different approach:
👉 Nuxt 4 alpha will ship June 2, 2025, with a stable release at the end of the month. Nuxt 5 will come later once Nitro v3 is ready.
...
Today we release Nuxt v4 alpha 1! We'd love early adopters to test it. Please do report issues to Nuxt or any modules that you may be using.
[!IMPORTANT]
At the alpha stage, we are still planning additional breaking changes (and expect there will be bugs or 'friction'); at the beta stage, we are not planning breaking changes but they may occur if necessary. At the release candidate stage we expect only bug fixes.Here's what you can expect over the next few weeks:
- We plan to open upstream PRs for community modules in the nuxt/modules registry, and create a migration guide for module authors.
- We'll create a full upgrade guide for Nuxt 3 users, including a list of breaking changes and how to migrate. (The current upgrade guide explains how to enable compatibility mode, but there are some differences with Nuxt 4.)
- We'll only release bugfixes for v3 this month, deferring backporting new features until after the release of v4.
- We'll update the docs on nuxt.com to allow switching between
3.x,4.xand (soon)5.xdocumentation. - Once we release the release candidate (we're aiming for June 23) we'd love everyone to dive in again for a last round of testing. We'll only be expecting bugfixes from this point onward.
- Once v4 is released, we'll separate the
mainbranch to4.xto adopt edge releases ofh3andnitroand begin development of Nuxt 5.
[!TIP]
You can follow the progress of the remaining work by checking these remaining tasks and the Nuxt 4 milestone on GitHub.I'm really excited with this timeline — and thank you for your patience and trust over the last year!
👉 Read more at https://nuxt.com/blog/roadmap-v4
🚀 Enhancements
- kit,nuxt,schema,vite,webpack: Nitropack v3 nightly (#27702)
- ui-templates: Update template branding for v4 (#27843)
- deps: Upgrade to latest versions of c12, jiti and unbuild (#27995)
- kit: Reimplement cjs utils using
mlly(#28012) - nuxt: Generate basic jsdoc for module config entry (#27689)
- schema: Split dev/prod build directories (#28594)
- nuxt: Cache vue app build outputs (#28726)
- deps: Update dependency vite to v6 (main) (#30042)
- nuxt: Add integration with chrome devtools workspaces (#32084)
🔥 Performance
- nuxt: ⚠️ Don't call
render:htmlfor server islands (#27889) - vite: Don't write stub manifest for legacy bundler (#27957)
- kit: Update env expansion regex to match nitro (#30766)
- nuxt: Replace remaining instance of
globby(#31688)
🩹 Fixes
- schema,vite: ⚠️ Do not allow configuring vite dev bundler (#27707)
- schema: ⚠️ Default to
compatibilityVersion: 4(#27710) - nuxt: ⚠️ Emit absolute paths in
builder:watchhook (#27709) - nuxt: ⚠️ Improve default
asyncDatavalue behaviour (#27718) - nuxt: ⚠️ Remove old experimental options (#27749)
- kit: ⚠️ Support loading nuxt 4 and drop support for <=2 (#27837)
- nuxt: ⚠️ Remove
__NUXT__after hydration (#27745) - ui-templates: Add default title back (3415241a6)
- kit: ⚠️ Drop support for building nuxt 2 projects (1beddba6a)
- nuxt: ⚠️ Bump internal majorVersion to
4(7aae4033b) - kit: Mark
resolvePathutils as sync (655e1473d) - kit: Revert change to
tryResolveModule(2d136e04c) - kit: Add back
requireModuleandtryRequireModule(#28013) - nuxt: Hide unhandled error messages in prod (#28156)
- nuxt: Add
useScriptCrispscripts stub (0c3cc4cf3) - nuxt: ⚠️ Remove unused
globalNameproperty (#28391) - nuxt: Use static import for
updateAppConfigin HMR (#28349) - vite: Write dev manifest when
ssr: false(#28488) - kit,nuxt,schema: ⚠️ Remove other support for nuxt2/bridge (#28936)
- webpack: Only insert dynamic require plugin when building (b619b35e9)
- nuxt: Guard
windowaccess (d874726ff) - nuxt: Remove unneeded subpath import (18a6ef1ca)
- webpack: Handle new webpack chunk format (d293c06d2)
- nuxt: Wrap slot with
h()in ClientOnly (#30664) - kit: ⚠️ Do not check compatibility for nuxt version < 2.13 (f94cda4c8)
- ui-templates: Fix examples link and add bluesky (#30866)
- vite: Use
resolveIdfromvite-nodeto resolve deps (#30922) - nuxt: Import
isEqualfrom mainohashexport (3ec1a1e5e) - vite: Don't set
output.preserveModules(ce49734aa) - nuxt: Ignore
#app-manifestimport in dev mode (#31539) - nuxt: Ensure layer array-type config is merged in order (#31507)
- schema: Turn off
purgeCachedDatauntil v4 (7aa3a01ae) - schema: Re-enable
purgeCachedDataby default (06745604c) - webpack: Expand dynamic require regexp to match new pattern (62e700daa)
- nuxt: Add back missing reset of
.execute(d79e14612) - nuxt: Remove unneeded pattern from regexp (cf4598d0d)
- nuxt: Ensure
appConfigsources are not duplicated (#32216) - nuxt,schema: ⚠️ Remove support for
compatibilityVersion: 3(#32255) - nuxt: Access
asyncDatastate from nuxt app instance (#32232) - kit,nuxt,schema,vite: ⚠️ Remove support for some deprecated options (#32257)
- nuxt: Make patterns relative to
srcDirinbuildCache(#32260) - nuxt: ⚠️ Don't rerun asyncdata w/ existing data in
useAsyncData(#32170) - nuxt: Return non-existent route component in RouteProvider (#32266)
- nuxt: Scan nitro handlers before writing types (a3698c08b)
- nuxt: Force asyncData
errorValue/valueto be undefined (7e4eac655) - nuxt: ⚠️ Remove public and assets aliases (#32119)
- nuxt: Use single
asyncDatawatcher (#32247)
💅 Refactors
- kit,nuxt: ⚠️ Drop nuxt 2 + ejs template compile support (#27706)
- nuxt: ⚠️ Move
#app/components/layout->#app/components/nuxt-layout(209e81b60) - kit,nuxt,vite,webpack: ⚠️ Remove legacy require utils (#28008)
- nuxt: Simplify check of
dedupeoption (#28151) - nuxt: Use direct import of
installNuxtModule(501ccc375) - kit: Remove internal function (#32189)
- Downgrade to nitro v2 (#32252)
- schema: ⚠️ Remove config.schema.json export + defaults (#32254)
- nuxt: Migrate to
oxc-walker(#32250) - nuxt,schema: Use oxc for
onPrehydratetransform (#32045)
📖 Documentation
- Indicate what
useAsyncDatamust return (#28259) - Update
deepdefault foruseAsyncData&useFetch(#28564) - Add props to special metadata (#29708)
- Fix link to issue (4d13f1027)
- Fix typos (#30413)
- Update
addRouteMiddlewarepath in example (#32171) - Narrow link to just middleware (#32203)
- Use optional chaining in error example (#32214)
- Give example of using
--env-file(15fb7b30f) - Recommend
nuxtcommand consistently (#32237) - Improve wording for
deepoption (bec85dfcd) - Fix wrong
alertwithwarningin/guide/pages(#32270)
📦 Build
- deps: Bump esbuild from 0.23.1 to 0.25.0 (#31247)
🏡 Chore
- Manage update to
vite-plugin-checkerseparately (02d46dd3d) - Update docs typecheck command (#28433)
- Improve accuracy of 4.x changelog (#28706)
- Bump package versions internally to v4 (16fab7778)
- kit: Fix regressed version v4 (a1c052057)
- Dedupe lockfile (f14ef6bc9)
- Update once more (4d22f4d5a)
- Specify workspace
engines.nodecompatibility (a26322f5f) - Remove special treatment for typescript (08766a0cd)
- Reenable quarantine for webpack/memfs (for 3.x benefit) (9cb94e55e)
- Remove extra dep (f0ec34298)
- Add back
nuxi(9aa4c7c3b) - Remove stray
nuxiversion again (#30547) - Fix lockfile (7d345c714)
- Remove second version of vitest (#30868)
- Ignore
oxc-parserupdates temporarily (1cd0fb5cb) - Ignore
nitro/templatesdirectory (e531477f8) - Fix ui-templates build (c8a1b9e80)
- Mkdir for ui-templates (853408a1e)
- Add webpack resolution (088bcd459)
- Upgrade webpack dependencies separately (b6b66069d)
- Apply lint fixes (8f8db534a)
✅ Tests
- Remove unused experimental options (6d971ddc9)
- Add additional
attwtest for built packages (#30206) - Add minimal pages fixture (#30457)
- Update bundle size assertion (f458153d9)
- Update bundle size assertion (4cce6bf8d)
- Benchmark minimal fixture instead (#31174)
- Normalise scoped css + pass logger to
configResolved(8d3bd4f9f) - More precise asyncData tests (023fb13eb)
- Add regression test for useAsyncData + transition (8d65b941c)
- Ensure builder tests run sequentially (095f5716f)
🤖 CI
- Bump node v22 (#30251)
- Run workflows on merge groups (ff37ad9df)
- Do not invoke semantic-pr test on merge groups (fadd618d1)
⚠️ Breaking Changes
- nuxt: ⚠️ Don't call
render:htmlfor server islands (#27889) - schema,vite: ⚠️ Do not allow configuring vite dev bundler (#27707)
- schema: ⚠️ Default to
compatibilityVersion: 4(#27710) - nuxt: ⚠️ Emit absolute paths in
builder:watchhook (#27709) - nuxt: ⚠️ Improve default
asyncDatavalue behaviour (#27718) - nuxt: ⚠️ Remove old experimental options (#27749)
- kit: ⚠️ Support loading nuxt 4 and drop support for <=2 (#27837)
- nuxt: ⚠️ Remove
__NUXT__after hydration (#27745) - kit: ⚠️ Drop support for building nuxt 2 projects (1beddba6a)
- nuxt: ⚠️ Bump internal majorVersion to
4(7aae4033b) - nuxt: ⚠️ Remove unused
globalNameproperty (#28391) - kit,nuxt,schema: ⚠️ Remove other support for nuxt2/bridge (#28936)
- kit: ⚠️ Do not check compatibility for nuxt version < 2.13 (f94cda4c8)
- nuxt,schema: ⚠️ Remove support for
compatibilityVersion: 3(#32255) - kit,nuxt,schema,vite: ⚠️ Remove support for some deprecated options (#32257)
- nuxt: ⚠️ Don't rerun asyncdata w/ existing data in
useAsyncData(#32170) - nuxt: ⚠️ Remove public and assets aliases (#32119)
- kit,nuxt: ⚠️ Drop nuxt 2 + ejs template compile support (#27706)
- nuxt: ⚠️ Move
#app/components/layout->#app/components/nuxt-layout(209e81b60) - kit,nuxt,vite,webpack: ⚠️ Remove legacy require utils (#28008)
- schema: ⚠️ Remove config.schema.json export + defaults (#32254)
❤️ Contributors
- Alexander Lichter (@TheAlexLichter)
- Julien Huang (@huang-julien)
- Robin (@OrbisK)
- Matej Černý (@cernymatej)
- Daniel Roe (@danielroe)
- Hugo Richard (@HugoRCD)
- mxmxmmgg (@mxmxmmgg)
- Baptiste Leproux (@larbish)
- Phojie Rengel (@phojie)
- Michael Brevard (@GalacticHypernova)
- duolaameng (@1411430556)
- David Stack (@davidstackio)
- John Tanzer (@moshetanzer)
- @beer (@iiio2)
- हिमांशु (@CodeMan62)
- Norbiros (@Norbiros)
- watsonhaw5566 (@watsonhaw5566)
- xjccc (@xjccc)
- Ryota Watanabe (@wattanx)
- Max (@onmax)
- Alex Liu (@Mini-ghost)
- Martins Zeltins (@martinszeltins)
- Ivan Martianov (@ivansky)
- Lorenzo Fiamingo (@lorenzofiamingo)
- James (@Koshux)
- Pooya Parsa (@pi0)
- Kyohei Sonokawa (@kyohei-23)
- Saeid Zareie (@Saeid-Za)
- Bobbie Goede (@BobbieGoede)
- Damian Głowala (@DamianGlowala)
- Maxime Pauvert (@maximepvrt)
- Leonid (@john-psina)
- Wind (@productdevbook)
- Arkadiusz Sygulski (@Aareksio)
- Rohan Dhimal (@drowhannn)
- Daniel Kelly (@danielkellyio)
- Jeffrey van den Hondel (@jeffreyvdhondel)
- Sébastien Chopin (@atinux)
- Anthony Fu (@antfu)
- Yizack Rangel (@Yizack)
- Joaquín Sánchez (@userquin)
- IlyaL (@ilyaliao)
- Ben McCann (@benmccann)
- Alexandru Ungureanu (@unguul)
- Andrej Adamcik (@adamcikado)
- Dennis Adriaansen (@dennisadriaans)
- Guillaume Chau (@Akryum)
- 翠 / green (@sapphi-red)
- Johannes Buchholz (@jhony1104)
- Claudiu (@sofuxro)
- Anoesj Sadraee (@Anoesj)
- Peter Radko (@Gwynerva)
- Adam DeHaven (@adamdehaven)
- Francesco Agnoletto (@Kornil)
- imreegall (@imreegall)
- Sam Blowes (@blowsie)
- Nimit012 (@Nimit012)
- Camille Coutens (@Kamsou)
- Connor Pearson (@cjpearson)
- Connor Roberts (@murshex)
- Harlan Wilton (@harlan-zw)
- dependabot[bot] (@dependabot[bot])
- Kevin Deng 三咲智子 (@sxzz)
- Maik Kowol (@94726)
- Clayton Chew (@claytonchew)
- awfulness (@awfulness)
- Vahagn Zaqaryan (@Vahagn-Zaqaryan)
- Idorenyin Udoh (@idorenyinudoh)
- Jonas Thelemann (@dargmuesli)
- Horu (@HigherOrderLogic)
- Nolhan (@Nonolanlan1007)
- Typed SIGTERM (@typed-sigterm)
- Hans Tu (@ChiaHanTu)
- David Marr (@marr)
- Charlie ✨ (@CharleeWa)
- Hussain Panahy (@HP8585)
- Lansi (@lansi951)
- Yauheni Vasiukevich (@EvgenyWas)
- Alan Schio (@schirrel)
- Zakhar Shymanchyk (@zakshyman)
- Arturs Jansons (@iegik)
- Peter Buglavecz (@buglavecz)
- ikxin (@ikxin)
- Guspan Tanadi (@guspan-tanadi)
- Vuk Marjanovic (@vmrjnvc)
- Clément Ollivier (@clemcode)
- Anders Bootsmann Larsen (@bootsmann1995)
- Nishant Aanjaney Jalan (@cybercoder-naj)
- David Nahodyl (@Smef)
- derHodrig (@skoenfaelt)
- Matt (@matt-clegg)
- Nikolay (@RokeAlvo)
- bjoaquinc (@bjoaquinc)
- wzc520pyfm (@wzc520pyfm)
- Kraig Burrows (@zync09)
- Sébastien LeBlanc (@mrleblanc101)
- Teena (@franklin-tina)
- skmedix (@skmedix)
- Daniel Rentz (@danielrentz)
- Inesh Bose (@ineshbose)
- Felix Gabler (@felixgabler)
- mianlang (@mianlang)
- Tamás H. (@Tamas-hi)
- Farnabaz (@farnabaz)
- Jan-Niklas W. (@niklas-wortmann)
- Gustavo Aquino Torres Teixeira (@guska8)
- Stephanie Smith (@stephiescastle)
- crisarji (@crisarji)
- RBV1 (@RBV1)
- Adrien Foulon (@Tofandel)
- Efraim (@EfraimGENC)
- Aurion SARL (@TonyFresneau)
- Erik Lilja (@Lilja)
- Markus Oberlehner (@maoberlehner)
- Lukas Bauer (@luxterful)
- Till Sanders (@tillsanders)
- Nils (@BracketJohn)
- Estéban (@Barbapapazes)
- Cruz (@SparK-Cruz)
- Taras Batenkov (@enkot)
- Panopoulos Andreas (@b0ul17)
- Dawit (@oneminch)
- Ryoya (@harunari0928)
- Alexander (@hywax)
- Jelmer (@jelmerdemaat)
- Christoph Heike (@cheike569)
- Jeremy Graziani (@AcelisWeaven)
- Domenik Reitzner (@dreitzner)
- Jeel Rupapara (@zeelrupapara)
- Leopold Kristjansson (@leopoldkristjansson)
- Horváth Bálint (@horvbalint)
- Bochkarev Ivan (@Ibochkarev)
- Joschua (@selfire1)
- Indrek Ardel (@Ingramz)
- DarkVen0m (@DarkVen0m)
- Ezra Ashenafi (@Eazash)
- Artem Maslov (@Twocram)
- Paulo Ricardo Severo (@prsevero)
- Liran Tal (@lirantal)
- Osama Abdallah Essa Haikal (@OsamaHaikal)
- Gianluca Di Francesco (@gianlucadifrancesco)
- Heb (@Hebilicious)
- Eckhardt (Kaizen) Dreyer (@Eckhardt-D)
- Ismail Sabet (@ismailsabet)
- riskrole (@riskrole)
- Thimo Sietsma (@th1m0)
- felix-dolderer (@felix-dolderer)
- Nicolas Payot (@nicolaspayot)
- Kewin Szlezingier (@kewinzaq1)
- Vasily Kuzin (@ExEr7um)
- Gustav Odinger (@gustavwilliam)
- Martin André (@Martichou)
- Mike Laumann Bellika (@MikeBellika)
- Son Tran (@trandaison)
- rubyisrust (@rubyisrust)
- Riley Ho (@rileychh)
- Potter (@yxw007)
- Martin Masevski (@Archetipo95)
- BoogieBen. (@boogie-ben)
- Tobias Diez (@tobiasdiez)
- Yasser Lahbibi (@yassilah)
- pan93412 (@pan93412)
- AuroraTea (@AuroraTea)
- nuxt-studio[bot] (@nuxt-studio[bot])
- Vaci (@vacijj)
- FELIPE COSTA DE OLIVEIRA (@FelipeO16)
- Aleksei Nagovitsyn (@al3xnag)
- Meo (@miaobuao)
- Mohab Sameh (@mohab-sameh)
- Quentin Macq (@quentinmcq)
- Johan Krijt (@johankrijt)
- arshcodemod (@arshcodemod)
- Santiago A (@santiagoaloi)
- Thomas (@ThomasWT)
- Dominic (@rexhent)
- Florian Metz (@Timeraa)
- Daniel Flanagan (@FlantasticDan)
- 山吹色御守 (@KazariEX)
- izzy goldman (@izzygld)
- Seno (@s-en-o)
- Aviv Keller (@avivkeller)
- Lucie (@lihbr)
- 4.0.0-015 May 2025pre-release
Nothing published for this version
- 3.21.115 Aug 2026
Release notes
Open source →3.21.11 is a patch release.
[!IMPORTANT] Nuxt v3 is now end-of-life. Please upgrade to Nuxt v4, or you may wish to check out our partner HeroDevs who provide never-ending support for end-of-life releases
👉 Changelog
🩹 Fixes
- nuxt: Serialize island payloads for components with underscores in keys (#35807)
- nitro: Dedupe island renders when prerendering (#35835)
- nitro: Reject non-object island props (#35867)
- nuxt: Re-check for preview mode after prerendered page hydration (#35886)
- nuxt: Settle asyncData status when bailing (#35908)
- kit: Clone resolved config with klona rather than klona/full (#35914)
- nuxt: Use client-side navigation for links inside islands (#35806)
- nuxt: Match route rules against decoded paths (81f86ac5e)
🏡 Chore
- Unpin
oxc-walker(a6c9dc6d3)
❤️ Contributors
- Daniel Roe (@danielroe)
- Samuel Burkhard (@samydoesit)
- Alexander Lichter (@TheAlexLichter)
- 3.21.1027 Jul 2026
Release notes
Open source →⚠️ This is a security release. We recommend upgrading as soon as possible with
npx nuxt upgrade --dedupe.It fixes server-side RCE and unauthorized component instantiation via server island props, a route rule authorization bypass, server component DoS, and dev server path disclosure. Refreshing your lockfile also pulls in
@nuxt/[email protected], which fixes a separate critical development-only RCE.If you already upgraded for the earlier route rule advisory (CVE-2026-53721), you still need this release: one of the fixes addresses a regression introduced by that fix.
Full details: Nuxt Security Patch Releases and GitHub Security Advisories.
👉 Changelog
🩹 Fixes
- nuxt: Clear hide/reset timeouts in set() (#35534)
- nuxt: Preserve trailing slash in NuxtLink href when unset (#35501)
- vite: Resolve SSR inlined CSS module class name mismatch (#35610)
- nuxt: Sync layout meta during middleware on SSR (#35633)
- nuxt: Update client URL to match SSR on fatal middleware error (#35637)
- nuxt: Watch external component directories in development (#35652)
- nuxt: Don't cross-pollute useAsyncData cache on reactive key change (#35656)
- nuxt: Return global route for
useRoutein detached effect scope (#35659) - nuxt: Ignore custom
nameorpathwhen reusing an existing page inpages:extend(#35661) - nuxt: Preserve explicit
useFetchmethod inference (#35671) - nuxt: Correct default export detection in plugin metadata (#35676)
- nuxt: Reload real page module on HMR of JSX render-function pages (#35678)
- vite: Ensure server sourcemap-preserver plugin actually runs (#35680)
- nuxt: Resolve
@unhead/vue/*from nuxt's dependency tree (#35690) - nuxt: Don't apply scroll behaviour after a subsequent nav (#35719)
- vite: Preserve css suffix when extracting ssr inline styles (#35714)
- nuxt: Don't exclude client entry module from style extraction (#35720)
- kit: Avoid mutating layer configs when resolving options (#35729)
- nuxt: Generate layout types even when pages module is disabled (#35717)
- nitro: Skip resource hints for stylesheets already rendered as blocking links (#35691)
- nuxt: Revalidate cached route payloads instead of using
force-cache(#35672) - nuxt: Preserve query params in cached payload extraction (#35696)
- rspack,webpack: Resolve loaders and runtime deps from nuxt dirs (#35568)
- nuxt: Render client components in nested server components (#35669)
- nuxt: Remove dev error overlay when error is cleared (#35821)
- rspack,webpack: Resolve bundled postcss defaults from builder (#35823)
- schema: Normalise slashes in
app.buildAssetsDir(#35833) - nuxt: Case-fold route rule keys to match folded lookups (619963309)
- nitro: Require loopback peer for chrome devtools workspace endpoint (00f71bb65)
- nitro: Bound island props and v-for to prevent unauthenticated DoS (668cdfdfd)
- nuxt: Reject reserved
templateisland prop under runtime compiler (5b60017f7) - nuxt: Reject top-level
asprop for islands (00a2b0494)
📖 Documentation
- Document relative baseURL workarounds (#34004)
- Warn about
runtimeCompilersecurity best practices (b76c1a8bd) - Warn about validating server component props (f6d72628d)
✅ Tests
- Guard against transient undefined
_routein gotoPath (5391e7e6a) - Raise route-HMR polling timeout to reduce e2e flakiness (cbc757c63)
- kit: Scope loadNuxt temp dir so it doesn't delete sibling fixtures (72e4b5578)
❤️ Contributors
- Daniel Roe (@danielroe)
- Florian Heuberger (@Flo0806)
- Matej Černý (@cernymatej)
- bdbch (@bdbch)
- Elecmonkey (@elecmonkey)
- Ryota Watanabe (@wattanx)
- kealan (@KealanAU)
- Julien Huang (@huang-julien)
- Luke Nelson (@luc122c)
- Harlan Wilton (@harlan-zw)
- Mateleo (@Mateleo)
- lutejka (@lutejka)
- Darlan José Batista do Prado (@DarlanPrado)
- Max (@onmax)
- Sushant (@sushantguri)
- raminjafary (@raminjafary)
- 3.21.918 Jul 2026
Release notes
Open source →3.21.9 is the next patch release.
👉 Changelog
🩹 Fixes
- vite: Use spa entry for vite-node fallback (3.x) (c8410a16a)
- kit,nuxt: Pass error as
causewhen we re-throw (#35387) - vite: Inline CSS for lazy components imported from
#components(#35215) - nuxt: Validate
<ClientOnly>fallback tag name (#35325) - vite: Extract server page CSS when
inlineStylesis disabled (#35209) - nitro: Include nested layers in nitro transforms (#35327)
- nitro: Export empty styles object with
ssr: false(#35330) - nuxt: Emit auto-import paths as files, not directories (#35333)
- nuxt: Suppress spurious slot warning in
NuxtPageduring nav (#35335) - vite: Preserve backslash separators in windows named pipe path (#35336)
- nuxt: Detach in-flight promise on
useAsyncDatateardown (#35328) - nuxt: Respect per-page keepalive set via
definePageMeta(#34526) - nuxt: Align useFetch error type with runtime (#35346)
- nuxt: Unwrap getter
bodyinuseFetch(#35343) - rspack,webpack: Strip invalid webpack PURE annotations (#35386)
- nuxt: Guard against -1 when unregistering a router hook (#35391)
- nuxt: Clean up load/error listeners in preloadPayload (#35392)
- nuxt: Avoid idle wait when refreshing data after hydration (#35358)
- nuxt: Ensure
page:startfinishes beforepage:finishstarts (#35408) - nuxt: Preserve plugin navigation during app boot (#35344)
- vite: Add extension to vite-node-runner virtual import (e81a0c484)
- nuxt: Make virtual module IDs stable across hosts (#35317)
- nuxt: Hash serialized island props (#35356)
- vite: Avoid emitted ssr styles file name collisions (#35432)
- nuxt: Avoid syncing route too early when reused page remounts (#35440)
- nuxt: Keep nested layout on deferred route during suspended layout switch (#35443)
- vite: Set define for
NODE_ENVand__VUE_PROD_DEVTOOLS__(#35444) - nuxt: Restore deferred query route before page is mounted (#35442)
- nuxt: Make islands hash backwards-compatible (#35452)
- nuxt: Pass nuxt
rootDirto typed-router context (#35565) - nitro: Only reload nitro after initial nitro build (6ba8e26a5)
- schema: Enable HMR for defineNuxtComponent in JSX (#35620)
- schema: Resolve Vite cache directory from workspace (#35626)
- nitro: Write prerender cache files atomically (#35619)
- nuxt: Apply latest navigation on concurrent
navigateToin built-in router (#35631)
📖 Documentation
- Improving testing documentation for better understanding (#35526)
- Add tip about prerendering registration for pages (#35635)
- Clarify useFetch custom data error (#35647)
- Drop reference to non-existent section (bd1943d04)
- Update link to /3.x slug (71bdb972d)
🏡 Chore
- Allow node version updates (#35297)
✅ Tests
- Assert dev css delivery transport for server pages (9851e993b)
- Count only render-blocking stylesheet links for page styles (b0e895a7f)
- Await
expectNoClientErrors(afffe7f09)
🤖 CI
❤️ Contributors
- Daniel Roe (@danielroe)
- Florian Heuberger (@Flo0806)
- Mateleo (@Mateleo)
- Luke Nelson (@luc122c)
- Darlan José Batista do Prado (@DarlanPrado)
- Julien Huang (@huang-julien)
- skoenfaelt (@skoenfaelt)
- Anoesj Sadraee (@Anoesj)
- raminjafary (@raminjafary)
- Kurt Medley (@HeavyMedl)
- isksss (@isksss)
- Alexander Lichter (@TheAlexLichter)
- Damian Głowala (@DamianGlowala)
- Sami El Achi (@samiashi)
- 3.21.88 Jun 2026
Release notes
Open source →3.21.8 is a hotfix release to address an issue running the dev server on MacOS.
👉 Changelog
🩹 Fixes
- vite: Shorter socket name for macOs with tmp fallback (#35265)
- kit: Respect
typeoption infindPath(#35272) - deps: Update nuxt/scripts presets (ff6b060dd)
📖 Documentation
- Change
nulltoundefinedin data-fetching docs to match actual types (#35301)
❤️ Contributors
- Daniel Roe (@danielroe)
- Ali Mahmmoud (@AliMahmoudDev)
- Quentin Macq (@quentinmcq)
- Eduardo San Martin Morote (@posva)
- 3.21.72 Jun 2026
Release notes
Open source →3.21.7 is the a security hotfix release.
👉 make sure to check https://github.com/nuxt/nuxt/security/advisories to view open advisories resolved by this release.
👉 Changelog
🩹 Fixes
- nitro: Assign
noSSRbefore deciding payload extraction (#35108) - vite: Avoid filtering out dirs with shared prefix from
allowDirs(#35112) - nuxt: Use resolve from
pathefor buildCache path boundary check (#35111) - nuxt: Prevent sibling-directory traversal in test component wrapper (#35110)
- nitro: Pass event data to
isValidin dev clipboard-copy listener (#35109) - nuxt: Validate protocols in
reloadNuxtApppath before reload (#35115) - vite: Resolve vite
clientServerwithssr: false(#34959) - vite: Prefix public asset virtuals with null byte (38d330179)
- nuxt: Handle missing payload in chunkError listener (#35155)
- vite: Close vite dev server on nuxt close (d007d7060)
- kit,nuxt: Handle cancelling prompts to install packages (59821a5ca)
- nuxt: Await in-lifght template generation when closing nuxt (#35181)
- webpack: Surface compilation errors when stats.toString is empty (71dccff2b)
- kit: Improve TS extension stripping/substitutions (#35233)
- nuxt: Preserve
.d.mts/.d.ctsinresolveTypePaths(#35235) - nuxt: Reject prototype-chain keys in the island registry (#35205)
- nitro: Gate chrome devtools workspace endpoint to local requests (#35201)
- nuxt: Escape props in
<NuxtClientFallback>ssr output (#35199) - nuxt: Apply
isScriptProtocolguard tonavigateToopen option (#35206) - rspack,webpack: Require loopback host when missing same-origin signals (#35200)
- nuxt: Absolutely resolve
defuin app config template (40bedf0db) - nuxt: Match route rules case-insensitively to mirror
vue-router(3f3e3fa7b) - nuxt: Escape
<NoScript>slot content (7fea9fd68) - nuxt: Block path-normalization open redirect in
navigateTo(1f2dd5e78) - nuxt: Reject cross-origin paths in
reloadNuxtApp(6497d99dd) - vite: Bind vite-node IPC to a permissioned filesystem socket (c293bf950)
- nuxt: Reject script-capable protocols in
<NuxtLink>href (53284043d) - nuxt: Clarify page and layout usage warnings (#35184)
- nuxt: Do not absolutely resolve
defu(d11d7b1b5)
📖 Documentation
🏡 Chore
- Use
execFileSyncfor safety in release scripts (9a455a658) - Assert there is always a tag (8da21fba8)
- Fix type in test (bc2837125)
- Fix lychee dynamic composable exclude (#35119)
- Add autofix action tag in comment (70eba297f)
- Update renovate minimum release age (27a6821a1)
✅ Tests
🤖 CI
- Always run all tests for 4.x/3.x (0519c0ade)
- Update to agentscan v1.8.0 (#35120)
- Automatically close PRs from automated accounts (#35161)
- Migrate from tibdex (6277aedcb)
- Disable provenance-change enforcement in dependency-review (1d4910eed)
- Add zizmor github actions check (#35089)
❤️ Contributors
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- anton-gor-dev (@anton-gor-dev)
- Julien Huang (@huang-julien)
- David Stack (@davidstackio)
- Noah3521 (@Noah3521)
- Matteo Gabriele (@MatteoGabriele)
- Mohit Kumar (@mohitkum4r)
- Florian Heuberger (@Flo0806)
- nitro: Assign
- 3.21.618 May 2026
Release notes
Open source →3.21.6 is the next patch release.
👉 Changelog
🩹 Fixes
- nuxt: Prefer our own builder/server deps (#35029)
- nitro: Add json extension to payload cache items (#35043)
- nuxt: Handle errors fetching app manifest (#35050)
- nuxt: Preserve
setPageLayoutprops on same-path navigation (#35055) - vite: Don't strip buildAssetsDir from vite-node SSR ids (#35040)
- nuxt: Mark
useLoadingIndicatorproperties as readonly (#35062) - vite: Strip queries in css inline styles map (#35067)
- nuxt: Encode html-significant characters in external redirect body (#35052)
- nitro: Validate island request hash matches props (#35077)
- nitro: Use regexp to strip query (042b615e6)
- nitro: Use
statusCodefor nitro v2 compatibility (82dcd6a31) - nuxt: Render component-less parent routes during client-side nav (#35036)
- nuxt: Run middleware for page islands (#35092)
💅 Refactors
- rspack,webpack: Extract same-origin check for dev middleware (#35051)
📖 Documentation
- Remove CSB, set node 22 and use steps for clarity (#35066)
🏡 Chore
- Ignore link-like syntax in code (f9bf11b11)
- Narrow engines.node in test (5ed9a2691)
- Remove unused import (3a8bb0030)
✅ Tests
🤖 CI
- Clean up agent-scan workflow (31590cf07)
- Continue autofix workflow when
test:enginesfails (958abb882) - Improve workflows (#35088)
❤️ Contributors
- Daniel Roe (@danielroe)
- Julien Huang (@huang-julien)
- Damian Głowala (@DamianGlowala)
- Sébastien Chopin (@atinux)
- Adrien Foulon (@Tofandel)
- 3.21.510 May 2026
Release notes
Open source →3.21.5 is the next patch release.
👉 Changelog
🔥 Performance
- kit: Cache layer roots and short-circuit
isIgnoredrelative (#35015)
🩹 Fixes
- nitro: Correct payload route rule for
/+ overridessr: true(#34990) - nitro: Break recursive rendering deadlocks during prerender (#34939)
- vite: Drop redundant css link when entry styles are inlined (#34950)
- nuxt: Only force suspense remount after first resolve (#34949)
- kit: Read
.envbefore resolving nuxt schema (#34958) - nitro: Preserve
serverHandlersarray afternitro:config(#34985) - vite: Only consider CSS inlined when styles are actually emitted (#35006)
- nuxt: Handle string presets in auto-imports (#35013)
- nuxt: Correct island transform for server pages and 'deep' mode (#35005)
- vite: Inline css for non-island children of server components (#35001)
- nuxt: Defer head DOM updates until page transition finishes (#35016)
- nuxt: Explicitly freeze head during island plugin phase (#35010)
- vite: Inline css imported from non-vue js modules (#35020)
- nitro: Remove unused middleware (fe857d36b)
📖 Documentation
- Add warning about routing in server components (#34994)
🏡 Chore
- Ignore pnpm cyclic workspace deps warn (#34998)
- Remove jiti from build steps (#35004)
- Fix lockfile (48e56a509)
- nuxt: Cast to nitro event handler type (5b358ca19)
✅ Tests
- Extract server components fixture + add some failing tests (#34995)
- Isolate
buildDirper matrix project for shared fixtures (#35007) - Split env testing into separate file (fd4019cf8)
- Use 3.x style tsconfig (86625efad)
- Use more 3.x style tsconfigs (4a9bde3f3)
- Correct import path (133d5f6d7)
- Update snapshots (9fc42f788)
❤️ Contributors
- Daniel Roe (@danielroe)
- Harlan Wilton (@harlan-zw)
- Jonazzzz (@Bombastickj)
- Damian Głowala (@DamianGlowala)
- Florian Heuberger (@Flo0806)
- kit: Cache layer roots and short-circuit
- 3.21.429 Apr 2026
Nothing published for this version
- 3.21.212 Mar 2026
Nothing published for this version
- 3.21.17 Feb 2026
Release notes
Open source →3.21.1 is a regularly schedule patch release.
👉 Changelog
🩹 Fixes
- nuxt: Correct reference format of server builder (#34177)
- nuxt: Add status/statusText getters to NuxtError (#34188)
- schema: Add direnv and vendor to default ignore (#34190)
- nuxt: Focus hash links after navigation (#34193)
- nuxt: Exclude head runtime from unhead imports transform (#34195)
- kit: Include prereleases in semver satisfy check (#34210)
- nuxt: Watch
server/forbuilder:watchhook (#34208) - nitro: Encode unicode paths in
x-nitro-prerenderheader (#34202) - nitro: Preserve
error.messagefor fatal errors (#34226) - Only enable dynamic imports when ts plugin (#34205)
- webpack: Use H3Error for 403 in dev server (#34233)
- nuxt: Ensure NuxtError extends Error type (#34242)
- vite: Use H3Error for 404 in dev server (#34225)
- nuxt: Add backwards compat for
#appbarrel export in keyed functions (#34199) - nuxt: Track + re-add custom routes on hmr (#32044)
- nuxt: Keep vnode when leaving deeper nested route (#33778)
- vite: Prevent CSS flickering in dev mode after config changes (#33856)
- nuxt: Do not start view transition if there is no route (#33723)
- nuxt: Call deferHydration done on NuxtPage unmount (#34152)
- nuxt: Handle invalid
datetime in<NuxtTime>` (#33992) - nuxt: Preserve middleware error status in 404 fallback (#34148)
- nitro: Do not augment
nuxt/schema(#34255) - nuxt: Cache manifest files to preserve buildId (#34002)
- nuxt: Don't decode query string in SSR context URL (#34252)
- nuxt: Allow specifying moduleDependencies by
meta.name(#34263) - nuxt: Resolve
#componentsimport mapping conflict for packages outside rootDir (#34139) - vite,webpack: Use node.res to send 403/404 (#34266)
- nitro,nuxt: Align path encoding with vue-router (#34265)
- nitro: Augment
nuxt/schemaonce more (9f5bb611d)
💅 Refactors
- nuxt: Prefer
genObjectKeyto omit unnecessary quotes (#34245) - nuxt: Use
ComponentPropshelper to extract layout props (#34248)
📖 Documentation
- Remove link to ai guide entirely (084b5d7f2)
- Update roadmap dates (#34166)
- Clarify shared type context limitations for custom imports (#34194)
- Fix broken links (#34223)
- Document payload extraction for ISR/SWR routes (#34222)
- Update example of email validation (#34247)
- Add documentation for
keyedComposables(#34201)
🏡 Chore
✅ Tests
- Vitest v4 compatibility (70e147b71)
- Add runtime tests for deeply nested
<NuxtPage>navigation (707a9dc44) - Resolve merge issues in tests (85abddc54)
❤️ Contributors
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Octavio Araiza (@8ctavio)
- Muhammad Yasir Ghaffar (@M-YasirGhaffar)
- Max (@onmax)
- Bobbie Goede (@BobbieGoede)
- 纸鹿/Zhilu (@L33Z22L11)
- Florian Heuberger (@Flo0806)
- 山吹色御守 (@KazariEX)
- ExXTreMe315 (@ExXTreMe315)
- Eugene (@FlexIDK)
- abeer0 (@iiio2)
- Jonas Thelemann (@dargmuesli)
- Erwan Jugand (@erwanjugand)
- 3.21.022 Jan 2026
Release notes
Open source →3.21.0 is the next minor release.
Nuxt 4.3 and 3.21 bring powerful new features for layouts, caching, and developer experience – plus significant performance improvements under the hood.
📣 Some News
Extended v3 Support
Early this month, I opened a discussion to find out how the upgrade had gone from v3 to v4. I was really pleased to hear how well it had gone for most people.
Having said that, we're committed to making sure no one gets left behind. And so we will continue to provide security updates and critical bug fix releases beyond the previously announced end-of-life date of January 31, 2026, meaning Nuxt v3 will meet its end-of-life on July 31, 2026.
[!TIP] As usual, today also brings a minor release for v3, with many of the same improvements backported from v4.3.
Preparing for Nuxt 5
We're closer than ever to the releases of Nuxt v5 and Nitro v3. In the coming weeks, the
mainbranch of the Nuxt repository will begin receiving initial commits for Nuxt 5. However, it's still business as usual.- Continue making pull requests to the
mainbranch - We'll backport changes to the
4.xand3.xbranches
Keep an eye out on the Upgrade Guide – we'll be adding details about how you can already start migrating your projects to prepare for Nuxt v4 with
future.compatibilityVersion: 5.🗂️ Route Rule Layouts
But that's enough about the future. We have a lot of good things for you today!
First, you can now set layouts directly in route rules using the new
appLayoutproperty (#31092). This provides a centralized, declarative way to manage layouts across your application without scatteringdefinePageMetacalls throughout your pages.export default defineNuxtConfig({ routeRules: { '/admin/**': { appLayout: 'admin' }, '/dashboard/**': { appLayout: 'dashboard' }, '/auth/**': { appLayout: 'minimal' } } })This might be useful for:
- Admin panels with a shared layout across many routes
- Marketing pages that need a different layout from the app
[!TIP] Plus, you can pass props to layouts now! See the
setPageLayoutimprovements below.📦 ISR/SWR Payload Extraction
Payload extraction now works with ISR (incremental static regeneration), SWR (stale-while-revalidate) and cache
routeRules(#33467). Previously, only pre-rendered pages could generate_payload.jsonfiles.This means:
- Client-side navigation to ISR/SWR pages can use cached payloads
- CDNs (Vercel, Netlify, Cloudflare) can cache payload files alongside HTML
- Fewer API calls during navigation – data can be prefetched and served from the cached payload
export default defineNuxtConfig({ routeRules: { '/products/**': { isr: 3600, // Revalidate every hour } } })🧹 Dev Mode Payload Extraction
Related to the above, payload extraction now also works in development mode (#30784). This makes it easier to test and debug payload behavior without needing to run a production build.
[!IMPORTANT] Payload extraction works in dev mode with
nitro.staticset totrue, or for individual pages which haveisr,swr,prerenderorcacheroute rules.🚫 Disable Modules from Layers
When extending Nuxt layers, you can now disable specific modules that you don't need (#33883). Just pass
falseto the module's options:export default defineNuxtConfig({ extends: ['../shared-layer'], // disable @nuxt/image from layer image: false, })🏷️ Route Groups in Page Meta
Route groups (folders wrapped in parentheses like
(protected)/) are now exposed in page meta (#33460). This makes it easy to check which groups a route belongs to in middleware or anywhere you have access to the route.<script setup lang="ts"> // This page's meta will include: { groups: ['protected'] } useRoute().meta.groups </script>export default defineNuxtRouteMiddleware((to) => { if (to.meta.groups?.includes('protected') && !isAuthenticated()) { return navigateTo('/login') } })This provides a clean, convention-based approach to route-level authorization without needing to add
definePageMetato every protected page.🎨 Layout Props with
setPageLayoutThe
setPageLayoutcomposable now accepts a second parameter to pass props to your layout (#33805):export default defineNuxtRouteMiddleware((to) => { setPageLayout('admin', { sidebar: true, theme: 'dark' }) })<script setup lang="ts"> defineProps<{ sidebar?: boolean theme?: 'light' | 'dark' }>() </script>🔧
#serverAliasA new
#serveralias provides clean imports within your server directory (#33870), similar to how#sharedworks:// Before: relative path hell import { helper } from '../../../../utils/helper' // After: clean and predictable import { helper } from '#server/utils/helper'The alias includes import protection – you can't accidentally import
#servercode from client or shared contexts.🪟 Draggable Error Overlay
The development error overlay introduced in Nuxt 4.2 is now draggable and can be minimized (#33695). You can:
- Drag it to any corner of the screen (it snaps to edges)
- Minimize it to a small pill button when you want to keep working
- Your position and minimized state persist across page reloads
This is a quality-of-life improvement when you're iterating on fixes and don't want the overlay blocking your view.
https://github.com/user-attachments/assets/nuxt_4-3_error_demo.mp4
⚙️ Async Plugin Constructors
Module authors can now use async functions when adding build plugins (#33619):
export default defineNuxtModule({ async setup() { // Lazy load only when actually needed addVitePlugin(() => import('my-cool-plugin').then(r => r.default())) // No need to load webpack plugin if using Vite addWebpackPlugin(() => import('my-cool-plugin/webpack').then(r => r.default())) } })This enables true lazy loading of build plugins, avoiding unnecessary code loading when plugins aren't needed.
🚀 Performance Improvements
This release includes several performance optimizations for faster builds:
- Hook filters - Internal plugins now use filters to avoid running hooks unnecessarily (#33898)
- SSR styles optimization - The
nuxt:ssr-stylesplugin is now significantly faster (#33862, #33865) - Layer alias transform - Skipped when using Vite (it handles this natively) (#33864)
- Route rules compilation - Route rules are now compiled into a client chunk using
rou3, removing the need forradix3in the client bundle and eliminating app manifest fetches (#33920)
🎨 Inline Styles for Webpack/Rspack
The
inlineStylesfeature now works with webpack and rspack builders (#33966), not just Vite. This enables critical CSS inlining for better Core Web Vitals regardless of your bundler choice.⚠️ Deprecations
statusCode→status,statusMessage→statusTextIn preparation for Nitro v3 and H3 v2, we're moving to use Web API naming conventions (#33912). The old properties still work but are deprecated in advance of v5:
- throw createError({ statusCode: 404, statusMessage: 'Not Found' }) + throw createError({ status: 404, statusText: 'Not Found' })🐛 Bug Fixes
Notable fixes in this release:
- Fixed head component deduplication using
keyattribute (#33958, #33963) - Fixed async data properties not being reactive in Options API (#34119)
- Fixed
useCookieunsafe number parsing during decode (#34007) - Fixed
NuxtPagenot re-rendering when nestedNuxtLayouthas layouts disabled (#34078) - Fixed client-side pathname decoding for non-ASCII route aliases (#34043)
- Fixed suspense remounting when navigating after pending state (#33991)
- Fixed clipboard copy in error overlay (#33873)
- Enabled
allowArbitraryExtensionsby default in TypeScript config (#34084) - Added
noUncheckedIndexedAccessto server tsconfig for safer typing (#33985)
[!IMPORTANT] Enabling
noUncheckedIndexedAccessin the Nitro server TypeScript config improves type safety but may surface new type errors in your server code. This change was necessary because Nuxt's app context performs type checks on server routes (learn more).While we recommend keeping this enabled for better type safety, you can disable it if needed:
export default defineNuxtConfig({ nitro: { typescript: { tsConfig: { compilerOptions: { noUncheckedIndexedAccess: false } } } } })Note that disabling this may allow type errors to slip through that could cause runtime issues with indexed access.
📚 Documentation
- Improved module author guides with clearer structure (#33803)
- Added MCP setup instructions for Claude Desktop (#33914)
- Added layers directory documentation (#33967)
- Added Deno package manager examples (#34070)
- Clarified type-checking context limitations for server routes (#33964)
🎉 Nuxt 3.21.0
Alongside v4.3.0, we're releasing Nuxt v3.21.0 with many of the same improvements backported to the 3.x branch. This release includes:
- All the same features: Route rule layouts, ISR payload extraction, layout props with
setPageLayout,#serveralias, draggable error overlay, and more - All performance improvements: SSR styles optimization, hook filters, and route rules compilation
- Module disabling: Disable layer modules by setting options to
false - Critical bug fixes: Async data reactivity in Options API,
useCookienumber parsing, head component deduplication, and more
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt@latest upgrade --dedupe --channel=v3This will deduplicate your lockfile and help ensure you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
[!TIP] Check out our upgrade guide if upgrading from an older version.
👉 Changelog
🚀 Enhancements
- kit: Support async constructor for adding plugins (#33619)
- kit: Export Nuxt major version type (#33700)
- schema: Add
#serveralias for server directory imports (#33870) - schema: Hoist nitro
crosswstypes (6ff79ea6c) - nitro,nuxt: Compile route rules into client chunk (#33920)
- nuxt: Allow disabling modules by setting module options to
false(#33883) - kit: Allow specifying
moduleDependenciesas an async function (#33504) - nuxt: Support
appLayoutin route rules (#31092) - nuxt: Add route groups to page meta (#33460)
- nuxt: Enable payload extraction for ISR/SWR routes (#33467)
- nuxt: Allow updating props with
setPageLayout(#33805) - nuxt: Enable dragging and minimizing for error overlay (#33695)
- nitro,nuxt: Add support for payload extraction in dev (#30784)
- rspack,webpack: Add inline styles (#33966)
- kit: Add forward-compatible nitro types (#34036)
🔥 Performance
- nuxt: Do not init layer alias transform when using vite (#33864)
- vite: Add hook filters for ssr styles plugin (#33865)
- vite: Optimize
nuxt:ssr-stylesplugin (#33862) - nuxt: Use filter for vfs plugin load (5bd8e81ed)
- nuxt,vite: Use filters to avoid running hooks unnecessarily (e762a1e20)
- nuxt,vite: Add more filters to internal plugins (#33898)
🩹 Fixes
- kit: Normalize local layer paths with trailing slashes (#33858)
- nuxt: Avoid overwriting multiple head input in island handler (#33849)
- nuxt: Update meta instead of calling
router.replacein page hmr (#33897) - nuxt: Don't call
page:loading:endin cache if already called (fbbe10133) - vite: Add error handling for parsing
NUXT_VITE_NODE_OPTIONS(8abb7ef5b) - nuxt: Do not skip middleware when
appMiddlewarereferences invalid key (ed8bb68c5) - nitro: Clipboard copy in error overlay (#33873)
- webpack,rspack: Resolve deep imports in virtual files (#33927)
- webpack: Disable async chunks in dev mode (c4bfd0a49)
- webpack: Correctly evaluate sourcemap name (93e3d92b9)
- nuxt: Handle node10 resolution for
nuxt/meta(b748840bc) - nuxt: Do not early return if component priorities conflict (#33955)
- nuxt: Use
keyfor tag deduplication in<Head>component (#33958) - schema,vite: Resolve
build.transpilewhen initialising vite (#33868) - nuxt,rspack,webpack: Inject module identifiers for webpack builders (#33962)
- nuxt: Add key to head components for proper deduplication (#33963)
- nitro: Check prettyResponse.body type before error overlay (#33977)
- nuxt: Don't URI-encode static route paths (#33990)
- nuxt: Skip internal stub routes from prerender (#34001)
- kit,schema: Align module
onUpgradearguments with types (#33988) - nuxt: Handle unsafe number parsing in useCookie decode (#34007)
- nuxt: Do not externalise
rou3(7da94e8c3) - nitro: Add
noUncheckedIndexedAccessto server tsconfig (#33985) - nuxt: Update global reference to globalThis in
useRequestFetch(#33976) - vite: Configure hmr port for server build (#33929)
- kit: Add forward compatible nitro v3 types (#34053)
- nitro,nuxt: Do not import nitro deps in builders (#34054)
- nitro: Add
h3types to auto-imports (#34035) - schema: Add some more directories to ignore (9cb9a19dd)
- nitro: Also augment
nuxt/schema(9b40196a6) - nuxt: Make asyncData properties reactive in Options API (#34119)
- nuxt: Rerender
NuxtPagewhen nestedNuxtLayouthas explicitly disabled layouts (#34078) - nuxt,schema: Clean up types (5ce351d0f)
- nuxt: Allow user augmentation of runtime config (dd30410cb)
- kit,nitro: Enable
allowArbitraryExtensionsby default (#34084) - nuxt: Decode client-side pathname for non-ASCII route aliases (#34043)
- nuxt: Force remount suspense when navigating after pending (#33991)
- nuxt: Add documentation link to server builder error message (#34122)
- nuxt: Validate placeholder/fallback tags + warn about placeholder/fallback props (f7912d3f3)
- nuxt: Force flush
useAsyncDatadebounced execute post watcher flush (#34125) - nitro: Process isr/swr/cache keys (7f2bf4d13)
- nuxt: Add
typeFromsupport forimports.d.tstemplate exports (#34135) - nuxt: Ensure we inline styles for
hydrate-nevercomponents (#34132)
💅 Refactors
- kit: Add explicit return types for kit utilities (ec2239cb4)
- nitro,nuxt,schema,vite: Provide explicit return types (2564002de)
- kit,nuxt,schema: Use named imports from
defu+consola(e31668f67) - Add explicit
.tsfile extensions to relative imports (458f3c9b6) - kit,nitro,nuxt,schema: Reduce barrels + move
<>toas(08f72881e) - nitro,nuxt: Use
~prefix for internal ssrContext properties (#33896) - nitro: Add explicit return types for runtime utils (74bb6ddeb)
- nitro: Move tree-shaken flags from replace plugin -> vfs (#33907)
- nitro,nuxt,vite,webpack: Use
status/statusText+ deprecate old props (#33912) - webpack: Use RuntimeModule API for chunk preloads (#33930)
- nuxt: Use AST-aware function key injection (#33446)
- nitro,nuxt,schema: Use augments for nitro schema types (#34039)
- nitro,rspack,vite,webpack: Move cors handling -> nitro builder (#34048)
- nitro: Move to
nitropack/runtimenamespace (b06d53166) - nitro,nuxt: Move to
nitropack/runtimenamespace (897a2259f)
📖 Documentation
- Fix
useHeadreturn type (#33857) - Add correct instructions to upgrade to latest Nuxt 3.x (#33866)
- Improve grammar (#34093)
- Use h2 for nuxt add command page (a0a1763d5)
- Update links to module guide (c9c1282f8)
- Split and improve
Module Author Guides(#33803) - Split directory structure and re-order guides (v4) (#33691)
- Add mcp server and llms.txt (#33371)
- Add note that middleware doesn't run when rendering islands (d22cf7903)
- Add note on default branch for layers (#33919)
- Add mcp setup instructions for claude desktop (#33914)
- Mention deno as package manager (#33875)
- Clarify purpose of
statusText(#32834) - Update lychee config and remove medium article link (36c19ce73)
- Update module count and fix typo (#33950)
- Add DeepWiki badge (#33508)
- Give example of usage of
defineWrappedResponseHandler(#33952) - Provide cleaner example code for vitest projects (#33960)
- Update yarn create command (b30432979)
- Update roadmap with a11y (7ea35137c)
- Add a11y release (#34041)
- Remove Nuxtr from recommendations (#34045)
- Remove duplicate feature (#34058)
- Provide deno package manager examples (#34070)
- Make custom wrapper recipe link more prominent (#34085)
- nuxt: Mention custom serializers in
useStatedocs (#34105) - Clarify module setups in
.nuxtrcexample (#34107) - Add layers directory documentation (#33967)
- Add a tip for
appLayout(9b78698c3) - Add docs for disabling modules by passing
falseto its options (18500730c) - Add info about caching payloads with isr/swr (4b055548e)
- Add example for async addVitePlugin (4407f6862)
- Add example of passing props to layouts (401aa90ab)
- Mark vite plugin as not typed (25eae7699)
- Add warning about
sourcefrom<NuxtIsland>(08778c98c) - Sync with main branch (e8c04aaa6)
- Fix ai guide link (01c173b78)
📦 Build
- Remove babel debugging plugin from jiti stub options (1ec010681)
- vite: Add build entries for
vite-nodeentrypoints (#33893) - nuxt: Tidy up subpath export types (fe92e9c17)
- Use
obuildexcept for nuxt + nitro-server packages (#34049) - schema: Fix
/builder-envsubpath types (1951648fa)
🏡 Chore
- Add return types to debug plugins (1d4f9a3ae)
- Add
build:stubcommand for those that need it (c682b2681) - Revert change to how type augments are inserted (6a238b576)
- Do not require aligned columns in tables (d8a90b3d5)
- Update eslint config rule (d87ed519a)
- Explicitly import
node:process(#33982) - Add root scripts to lint context (ee83838b4)
- Tidy up configs (ab131b464)
- Add
.nuxtrcwith test-utils setup (b5879351f) - Add eslint ignore (87811234d)
- Upgrade
vite-nodeseparately fromvitest(8114e886f) - Lint docs with eslint (d2d5f6733)
- Lint (b9df0e847)
- Lint (0efcf01fa)
✅ Tests
- Update tests for new version of nuxt/test-utils (#33842)
- Avoid unnecessary tick (fb4720840)
- Add regression test for asyncData HMR (#32182)
- Add test for page hmr resetting state (#32418)
- Add reproduction for vite pre-transform error (#31574)
- Add regression test for #32154 (#32154)
- Use
vi.hoistedfor klona mock (#34113) - Update bundle size (e6c8d10c6)
- Fix paths in hmr test (3b8b2138a)
- Update snapshots (51c83b8ec)
- Update bundle size (22708c05c)
🤖 CI
- Directly call webhook url (4eedbcae5)
- Use new reusable triage workflows (#34072)
- Use new shared dependency review workflow (9e6770f18)
❤️ Contributors
- Daniel Roe (@danielroe)
- Florian Heuberger (@Flo0806)
- Octavio Araiza (@8ctavio)
- Robin (@OrbisK)
- shaheer-arbisoft (@shaheer-arbisoft)
- Francesco Mussoni (@solidusite)
- Danila Poyarkov (@dannote)
- Teages (@Teages)
- Anthony Fu (@antfu)
- Eli Sterken (@eli-sterk)
- Ryota Watanabe (@wattanx)
- edison (@edison1105)
- Max (@onmax)
- Rahul Dogra (@rahuld109)
- abeer0 (@iiio2)
- Philipp Wagner (@imphil)
- Maxime Pauvert (@maximepvrt)
- Wind (@productdevbook)
- Agatem (@agatemosu)
- Pavel (@eL1fe)
- Lucie (@lihbr)
- Sergiu Ravliuc (@YoSoySergio)
- Julien Huang (@huang-julien)
- Saeid Zareie (@Saeid-Za)
- Alireza Jahandideh (@Youhan)
- kikuchan (@kikuchan)
- Ragura (@Ragura)
- Josh Deltener (@hecktarzuli)
- Teena (@franklin-tina)
- Matej Černý (@cernymatej)
- Frederik Bußmann (@freb97)
- Benjamin Oddou (@BenjaminOddou)
- Mukund Shah (@mukundshah)
- Jessé Correia Lins (@linspw)
- Jannik Sohn (@janniksohn)
- Dawit (@oneminch)
- Ali Sokkar (@NyllRE)
- Horu (@HigherOrderLogic)
- Hugo (@HugoRCD)
- Sébastien Chopin (@atinux)
- David Stack (@davidstackio)
- Ruslan Stelmachenko (@xak2000)
- Harlan Wilton (@harlan-zw)
- Alexander Lichter (@TheAlexLichter)
- Ryan Wilson (@rywils)
- yamachi4416 (@yamachi4416)
- Continue making pull requests to the
- 3.20.29 Dec 2025
Release notes
Open source →3.20.2 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe --channel=v3This will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
[!NOTE] This will only work if you already have a version of
@nuxt/cliwhich has the--channelflag. If this does not work, you can instead runnpx nuxi@latestfor the initial upgrade.👉 Changelog
🩹 Fixes
- nitro: Do not show pretty error handler when testing (cc75ce409)
- nuxt: Generate valid references for component declaration items (#33388)
- nuxt: Sync internal route before calling
page:finishhook (#33707) - nitro: Ensure html is a string before injecting error handler (6f51a25e9)
- nitro: Include layer server directories in
tsconfig.server.json(#33510) - nuxt: Ensure deduped async data executions return latest promise (#33740)
- kit,nuxt: Type + respect
moduleDependenciesby meta name (#33774) - nuxt,schema: Ignore
.d.vue.tsdeclarations (9a6a770ab) - kit,nuxt: Protect against resolved nuxt module subpath (#33767)
- nuxt: Re-execute
callOnceduring HMR (#33810) - nuxt: Resolve watch callback after reactive key change in
useAsyncData(#33802) - nuxt: Escape HTML in development error page stack trace (#33820)
- kit: Do not add resolved
rootDirto cached layer config (#33779) - kit,schema: Add
moduleDependencies->installModule(#33689)
💅 Refactors
- nuxt: Improve type safety within
callOncefunction (#33825)
📖 Documentation
- Split directory structure and re-order guides (v3) (#33690)
- Fix link (016ef66e3)
- Add hints release (#33701)
- Fix link to vitest globals config (#33702)
- Fix 404 link (5543b7cf7)
- Text consistency (#33709)
- Type
erroras non-optional prop (#33763)
🏡 Chore
- Update pnpm to 10.21 and enable trust policy (1cb55efc0)
- Revert pnpm trust policy and restore provenance action (103ae1351)
- Update markdownlint config to ignore mdc issues (d4933e26e)
- Pin to single version of unstorage (619956e7f)
✅ Tests
- Add
patchPropandnodeOpsto excluded Vue helpers (#33754) - Use fake timers for watch params test (58607fbea)
- Update test for v3 defaults (daa002638)
🤖 CI
❤️ Contributors
- Daniel Roe (@danielroe)
- Alexander Lichter (@TheAlexLichter)
- Florian Heuberger (@Flo0806)
- Konstantin Telyakov (@kTelyakov)
- abeer0 (@iiio2)
- Julien Huang (@huang-julien)
- Robin (@OrbisK)
- Dheeraj Joshi (@dheeraj3587)
- Edwin Samodra (@edwinsamodra)
- edison (@edison1105)
- 山吹色御守 (@KazariEX)
- Sébastien Chopin (@atinux)
- pierreoa (@pierreoa)
- Maxime Pauvert (@maximepvrt)
- 3.20.16 Nov 2025
Release notes
Open source →3.20.1 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe --channel=v3This will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- vite: Unset
optimizeDeps.includefor server environment (#33550) - kit,nuxt,schema: Deprecate
ImportPresetWithDeprecation(#33596) - nuxt: Correct warning message for prefetch/noPrefetch conflict (#33617)
- nitro: Remove
<nuxt-error-overlay>iframe border (#33625) - vite: Use rolldown replace only in build (#33615)
- nitro: Use directory paths in
moduleEntryPaths(#33628) - nitro: Start error overlay minimized based on status code (#33658)
- vite: Ensure
optimizeDepsconfig is applied before other plugins (#33586) - nuxt: Respect layer priority order for scanned components (#33654)
- nuxt: Process prerender routes on
pages:resolved(#33662) - nuxt: Remove abort signal event listeners after render (#33665)
- nuxt: Cleanup event listener with cleanup signal (#33667)
- vite: Respect vite proxy in dev middleware (#33670)
💅 Refactors
- kit,nitro,nuxt,schema,vite: Explicitly import process/performance (#33650)
📖 Documentation
- Fix typo in eslint flat config description (#33569)
- Add signal support to useAsyncData examples (#33601)
- Note that
cookieStoreistrueby default (#33572) - Document
pendingas alias ofstatus === 'pending'(#33221) - Clarify route middleware doesn't affect API routes (#33643)
- Improve docs for
useHead/useHydration/useLazy*(#33626) - Typo (#33655)
🏡 Chore
- Add
verifyDepsBeforeRun: install(#33603) - Reduce redirects in docs links (bbdc72e35)
- Lint docs (352bdbc93)
- Remove verify deps before run (e9e1c5b97)
🤖 CI
- Disable cache in release action (885df65f4)
❤️ Contributors
- Daniel Roe (@danielroe)
- Robin (@OrbisK)
- abeer0 (@iiio2)
- Bobbie Goede (@BobbieGoede)
- Florian Heuberger (@Flo0806)
- Matej Černý (@cernymatej)
- Peter Budai (@peterbud)
- Julien Huang (@huang-julien)
- Max (@onmax)
- 纸鹿/Zhilu (@L33Z22L11)
- Hinata Oishi (@te19oishi)
- Damian Głowala (@DamianGlowala)
- Maxime Pauvert (@maximepvrt)
- Raed Abdennadher (@RaedAbr)
- vite: Unset
- 3.20.028 Oct 2025
Release notes
Open source →3.20.0 is the next minor release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupe --channel=v3This will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- nuxt: Allow specifying component
declarationPath(#33419) - kit: Add
extensionsoption forresolveModule(#33328) - nuxt: Add abortController option to
useAsyncData(#32531) - nuxt: Display youch error page w/ user error page in dev (#33359)
- nuxt: Experimental typescript plugin support (#33314)
- nuxt,schema: Extract asyncData handlers to chunks (#33131)
- kit: Add
setGlobalHeadutility (#33512) - kit,vite: Allow enabling vite environment api (#33492)
🔥 Performance
- nuxt: Precompute renderer dependencies at build time (#33361)
- kit,schema: Remove some unnecessary dependencies (bdf34c263)
🩹 Fixes
- nuxt: Preserve hash with redirecting based on
routeRules(#33222) - kit: Safely cleanup
loadNuxtConfigin concurrent calls (#33420) - nuxt: Allow object-format
hrefin<NuxtLink>(b97ae2f70) - nuxt: Remove
mergeModelsfrom auto imports (#33344) - nuxt: Add back
shortPathproperty (#33384) - nuxt: Do not allow native attrs to shadow nuxt link props (0981990a7)
- nuxt: Remove
declarationPathfrom component dirs (e384ba3cb) - nuxt: Preserve root route in
isPrerenderedcheck (#33476) - nuxt: Exempt webpack vfs from pkg lookup (4df1e8275)
- nitro: Exempt nightly release from import protections (272d9abbe)
- webpack,rspack: Preserve prerender + nitro flags in server builds (#33503)
- nuxt: Support component auto-imports as arguments of
h()(#33509) - vite: Prevent assignment for rolldown's replacement plugin (#33526)
- nuxt: Use sha256 hash for prerender cache keys (#33505)
- nuxt: Add
NuxtTimerelative timenumericprop (#33552) - nuxt: Add
NuxtTimerelative timerelativeStyleprop (#33557) - nuxt: Handle arrays in app config correctly during HMR (#33555)
💅 Refactors
- Remove obsolete
shortPathproperty (#33384) - kit: Extract trace utilities (ddaedfa51)
- nuxt,vite,webpack: Allow builders to augment types (#33427)
- schema: Deprecate
extend,extendConfig, andconfigResolvedhooks (932a80dc6) - nitro,nuxt: Extract
@nuxt/nitro-serverpackage (#33462) - nuxt: Use
RouteLocationNormalizedLoadedGenericinternally (aa211fb4f) - vite: Make vite plugins environment-compatible (#33445)
📖 Documentation
- Add nuxt module
addServerPluginnote (#33409) - Remove deprecated node version (#33411)
- Update
declarationPathinaddComponent(#33380) - Add some notes/deprecations for vite hooks (2c6912d2f)
- Fix incorrect ESM module field info (#33451)
- Recommend
getLayerDirectories()instead ofnuxt.options._layers(#33484) - Add docs for
moduleDependencies(#33499) - Pin codemod to v0.18.7 for migration recipe (#33522)
🏡 Chore
- Migrate gitpod to ona (#33159)
- Use native node to run
test:prepare(cbad63c02) - Do not use native node to run
test:prepare(672c09423) - Update valid semantic scopes (4ca29168b)
- Ignore nitro templates (ec59aceeb)
- Remove
vue-demifromignoredBuiltDependencies(#33494) - Update vscode url (#33360)
- Correct jsdoc location for function used as parameters (#33507)
- Remove code comment (#33515)
- Patch changelogen for large numbers of commits (b6530b5b6)
- Filter out commits before last tag when constructing changelog (257049712)
- Ignore
@rollup/plugin-commonjs(c2bd323b8) - Pin
@rollup/plugin-commonjs(a524522ea)
✅ Tests
- Update runtime test to use
asyncDataDefaults.errorValue(b6f1c9b0d) - Refactor suite to use common matrix utils (#33483)
- Update typed router test (c55db2854)
🤖 CI
- Publish
@nuxt/nitro-serveron pkg-pr-new (d37ef17b0) - Remove nitro-server publish until v4.2 is released (e34c2f52f)
- For now, use tag push to trigger release (0705b835f)
❤️ Contributors
- Daniel Roe (@danielroe)
- 山吹色御守 (@KazariEX)
- Matej Černý (@cernymatej)
- Trung Dang (@NamesMT)
- 纸鹿/Zhilu (@L33Z22L11)
- Florian Heuberger (@Flo0806)
- Alexander Lichter (@TheAlexLichter)
- Julien Huang (@huang-julien)
- abeer0 (@iiio2)
- Max (@onmax)
- Octavio Araiza (@8ctavio)
- Bobbie Goede (@BobbieGoede)
- DipakHalkude (@DipakHalkude)
- Aleksander Błaszkiewicz (@ablaszkiewicz)
- nuxt: Allow specifying component
- 3.19.36 Oct 2025
Release notes
Open source →3.19.3 is a regularly scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- vite: Use rolldown's replace plugin when applicable (#33258)
🩹 Fixes
- nuxt: Make lazy component types compatible with
h(#33046) - vite: Deduplicate inlined server style chunks (#33308)
- nuxt: Support
headoption onuseHead(#33318) - nuxt: Do not relativise importmap if
cdnURLis set (#33333) - nuxt: Resolve aliases in
imports.dirs(#33334) - nuxt: Add missing element/vnode props for
<NuxtLink>(#33335) - nuxt: Do not generate server placeholder components (#33345)
- nuxt: Dedupe generated component names (#33346)
- webpack: Test watch instance before closing it (3314bc9a1)
- nuxt: Correctly handle island rendering error (#33302)
- nuxt: Support
v-slot:fallbacklongform syntax in<DevOnly>(#33368) - nuxt: Support
typeFromwhen generating auto-import type templates (#33373) - nuxt: Don't trigger scroll when changing trailing slash (#33358)
- nuxt: Add stubs for new scripts from
@nuxt/scripts(057ade490) - nuxt: Prevent duplicate execution on key change in
useAsyncData(#33325) - nuxt: Make middleware
_pathproperty configurable for HMR (#33379) - nuxt: Handle non-immediate
useAsyncDatawith different key on ssr (#33341)
💅 Refactors
- nuxt: Improve implementation of error composables (#33234)
- nuxt: Resolve path of
typed-router.d.tsearly for consistency (#33285) - nuxt: Place
filenameintocomponentsIslandsTemplatedefinition (#33394) - nuxt,vite: Use environment-api compatible plugins (#33403)
📖 Documentation
- Update usage instructions for Windows users (#33284)
- Remove d suffix in example (#33298)
- Move directory structure to top-level (#33299)
- Add
3.xprefix to all internal links (0fef864d6) - Add information about
useFetchreactivity (#33317) - Lint code samples within docs (#33271)
- Note
preparecommandNODE_ENVbehavior (#33330) - Update
nuxtcommand pages (#33336)
🏡 Chore
- Update bundle size test (15334d0c1)
- Temporarily disable link to github sponsors (53b02251f)
- Update markdownlint ignore (557656e54)
- Migrate pnpm settings out of
.npmrc(101682a6b) - Ignore errors from npmjs (d56790347)
- nuxt: Align global components indent (#33340)
- Remove tea.yaml (8b2188848)
- Remove todo comment as resolved (#33389)
- Downgrade nitropack in vite (3419f3414)
✅ Tests
🤖 CI
- Add provenance action to check for downgrades in provenance (18ab6e5fa)
- Pass commit sha when triggering ecosystem ci (7b2949a3c)
❤️ Contributors
- Daniel Roe (@danielroe)
- 山吹色御守 (@KazariEX)
- Julien Huang (@huang-julien)
- Florian Heuberger (@Flo0806)
- Ondrej Brendy (@bandiasek)
- Octavio Araiza (@8ctavio)
- Alex Liu (@Mini-ghost)
- Bobbie Goede (@BobbieGoede)
- abeer0 (@iiio2)
- Harlan Wilton (@harlan-zw)
- Alexander Lichter (@TheAlexLichter)
- Sébastien Chopin (@atinux)
- Ben Hong (@bencodezen)
- Huseyn Guliyev (@husayt)
- 3.19.212 Sept 2025
Release notes
Open source →3.19.2 is a regularly scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- kit: Do not normalise templates in loop if
dstis present (#33200) - nuxt: Remove watcher from
hydrate-whenlazy hydration strategy (#33199) - nuxt,schema: Normalise components + directories more efficiently (#33207)
- kit,nuxt: Reduce unnecessary iteration in nuxt code (#33212)
- nuxt: Skip running lazy hydration transform with filter (#33213)
🩹 Fixes
- schema: Add
pkg-typesto dependencies (a6e5dd756) - nuxt: Ignore errors when treeshaking composables within other composables (e3e42ac77)
- nuxt: Do not tree-shake composables within other composables (#33153)
- kit: Ensure module dependencies are typed correctly (ea16d182a)
- nuxt: Prevent Infinity
backgroundSizein loading indicator (#33211) - nuxt: Remove unused
enabledfrom components dir options (#32844) - nuxt: Sync watch request in useAsyncData (#33192)
- nuxt: Move key imports logic after all modules run (#33214)
📖 Documentation
- Update language on bridge head migration (32e76f609)
🏡 Chore
- nuxt: Unpin tinyglobby (1811db080)
❤️ Contributors
- Daniel Roe (@danielroe)
- Adrien Foulon (@Tofandel)
- Matej Černý (@cernymatej)
- Антон Стасюк (@11Alone11)
- wuiyang (@wuiyang)
- kit: Do not normalise templates in loop if
- 3.19.15 Sept 2025
Release notes
Open source →v3.19.1 is a regularly scheduled patch release
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- nuxt: Correct relative path of auto imported components (#33122)
- nuxt: Prefer accessing
globalThisoverwindow(#33125) - nuxt: Migrate to AST-aware tree-shaking + route injection (#33128)
- nuxt: Ignore #components import mapping inside packages that use it internally (#33049)
- vite: Remove explicit vite-node configuration of
deps.inline(#33133) - nuxt: Include trace in dev-time
useRouteusage warning (#33039) - nuxt: Print route middleware path in warning (#33136)
- nuxt: Include core auto-imports from
imports:sourcesin override warning (#33050) - nuxt: Render relative importmap entry path if required (#33146)
📖 Documentation
- Add documentation for module lifecycle hooks (#33115)
- Add
--to bun create command (ab6aa8ee5) - Add JSDoc for
navigateTo(#21442)
🏡 Chore
✅ Tests
🤖 CI
- Remove default discord reactions from thread (more noise than it's worth) (2e3c91e0c)
- Rewrite release workflow in ts + support multiple tags (478c64342)
- Pass correct flag (a954f383f)
- Pass tag via env variable (dcfc82688)
- Drop
4xtags from releases (e3aa50d11)
❤️ Contributors
- Daniel Roe (@danielroe)
- Matej Černý (@cernymatej)
- Bobbie Goede (@BobbieGoede)
- Octavio Araiza (@8ctavio)
- Michael Brevard (@GalacticHypernova)
- abeer0 (@iiio2)
- 山吹色御守 (@KazariEX)
- 3.19.02 Sept 2025
Release notes
Open source →👀 Highlights
Please see the release notes for Nuxt v4.1 for full details on the features and fixes in Nuxt v3.19.
✅ Upgrading
As usual, our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will refresh your lockfile and pull in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- kit: Add
ignoreoption toresolveFiles(#32858) - kit: Add
onInstallandonUpgrademodule hooks (#32397) - nuxt,vite: Add experimental support for
rolldown-vite(#31812) - nuxt: Extract
defineRouteRulesto pagerulesproperty (#32897) - nuxt,vite: Use importmap to increase chunk stability (#33075)
- nuxt: Lazy hydration macros without auto-imports (#33037)
- kit,nuxt,schema: Allow modules to specify dependencies (#33063)
- kit,nuxt: Add
getLayerDirectoriesutil and refactor to use it (#33098)
🔥 Performance
- nuxt: Clear inline route rules cache when pages change (#32877)
- nuxt: Stop watching app manifest once a change has been detected (#32880)
🩹 Fixes
- nuxt: Handle
satisfiesin page augmentation (#32902) - nuxt: Type response in
useFetchhooks (#32891) - nuxt: Add TS parenthesis and as expression for page meta extraction (#32914)
- nuxt: Use correct unit thresholds for relative time (#32893)
- nuxt: Handle uncached current build manifests (#32913)
- kit: Resolve directories in
resolvePathand normalize file extensions (#32857) - schema,vite: Bump
requestTimeout+ allow configuration (#32874) - nuxt: Deep merge extracted route meta (#32887)
- nuxt: Do not expose app components until fully resolved (#32993)
- kit: Only exclude
node_modules/if no customsrcDir(#32987) - nuxt: Compare final matched routes when syncing
routeobject (#32899) - nuxt: Make vue server warnings much less verbose in dev mode (#33018)
- schema: Allow disabling cssnano/autoprefixer postcss plugins (#33016)
- kit: Ensure local layers are prioritised alphabetically (#33030)
- kit,nuxt: Expose global types to vue compiler (#33026)
- nuxt: Support config type inference for
defineNuxtModule().with()(#33081) - nuxt: Search for colliding names in route children (31a9282c2)
- nuxt: Delete
nuxtApp._runningTransitionon resolve (#33025) - nuxt: Add validation for nuxt island reviver key (#33069)
- kit: Prioritise local layers over extended layers (ae8b0d2b8)
- kit: Address merge conflict (89ccbbebb)
- kit: Do not resolve public dir aliases (5d87d3a80)
💅 Refactors
- nuxt: Simplify page segment parsing (#32901)
- nuxt: Remove unnecessary
async/awaitinafterEach(#32999) - vite: Simplify inline chunk iteration (9ea90fc33)
- kit,nuxt,ui-templates,vite: Address deprecations + improve regexp perf (#33093)
📖 Documentation
- Add a section about augmenting types with TS project references (#32843)
- Switch example to use vitest projects (#32863)
- Update testing
setupTimeoutand addteardownTimeout(#32868) - Add middleware to layers guide (fa516d440)
- Add documentation for
--nightlycommand (#32907) - Update package information in roadmap section (#32881)
- Add more info about nuxt spa loader element attributes (#32871)
- Correct filename in example (#33000)
- Add more information about using
useRouteand accessing route in middleware (#33004) - Avoid variable shadowing in locale example (#33031)
🏡 Chore
- Remove stray test file (42fd247a4)
- Ignore webpagetest.org when scanning links (cb18f4960)
- Add
type: 'module'in playground (#33099)
✅ Tests
- Add failing test for link component duplication (#32792)
- Simplify module hook tests (#32950)
- Refactor stubbing of
import.meta.dev(#33023) - Use
findWorkspaceDirrather than relative paths to repo root (c4c3ada96) - Improve router test for global transitions (7e6a6fc35)
- Use
expect.poll(f4354203a) - Use
expect.pollinstead ofexpectWithPolling(15ca5be95) - Use
vi.waitUntilinstead of custom retry logic (4c8c13090) - Update test for app creation (9a3b44515)
- Update bundle size snapshot (76988ce97)
🤖 CI
- Remove double set of tests for docs prs (14c006ac4)
- Add workflow for discord team discussion threads (f14854fc3)
- Fix some syntax issues with discord + github integrations (c059f7cd1)
- Use token for adding issue to project (51661bac3)
- Use discord bot to create thread automatically (37f9eb27b)
- Only use discord bot (38ce2dcbb)
- Update format of discord message (0047b3059)
- Try bolding entire line (6e9f40eb9)
- Oops (8b044cad2)
- Add delay after adding each reaction (37b7e2108)
- Use last lts node version for testing (98719c065)
- Try npm trusted publisher (ea33502c3)
- Use npm trusted publisher for main releases (31a55437f)
- Change wording (#32979)
- Add github ai moderator (#33077)
❤️ Contributors
- Daniel Roe (@danielroe)
- abeer0 (@iiio2)
- Julien Huang (@huang-julien)
- kyumoon (@kyumoon)
- Alexander Lichter (@TheAlexLichter)
- Bobbie Goede (@BobbieGoede)
- mustafa60x (@mustafa60x)
- Matej Černý (@cernymatej)
- Alex Liu (@Mini-ghost)
- Amitav Chris Mostafa (@semibroiled)
- Romain Hamel (@romhml)
- Jacky Lam (@jackylamhk)
- Mukund Shah (@mukundshah)
- Luke Nelson (@luc122c)
- letianpailove (@letianpailove)
- Erwan Jugand (@erwanjugand)
- Alexander (@TheColorman)
- Ryota Watanabe (@wattanx)
- Yizack Rangel (@Yizack)
- kit: Add
- 3.18.15 Aug 2025
Release notes
Open source →3.18.1 is a regularly scheduled patch release.
👉 Changelog
🔥 Performance
- kit: Get absolute path from
tinyglobbyinresolveFiles(#32846)
🩹 Fixes
- nuxt: Do not throw undefined
errorvariable (#32807) - vite: Include tsconfig references during
typeCheck(#32835) - nuxt: Add sourcemap path transformation for client builds (#32313)
- nuxt: Add warning for lazy-hydration missing prefix (#32832)
- nuxt: Trigger call once navigation even when no suspense (#32827)
- webpack: Handle
nullresult from webpack call (65aa17158) - kit,nuxt: Use
reverseResolveAliasfor better errors (#32853)
📖 Documentation
🏡 Chore
- Update reproduction help text links (#32803)
- Update pnpm ignored build scripts (#32849)
- Improve internal types (f271c66c4)
✅ Tests
- Move tests for
defineNuxtComponentout of e2e test (#32848)
🤖 CI
- Move nightly releases into different concurrency group (26f9baa6a)
❤️ Contributors
- RDistinct (@RDistinct)
- Daniel Roe (@danielroe)
- Oskar Lebuda (@OskarLebuda)
- Peter Budai (@peterbud)
- Matej Černý (@cernymatej)
- Damian Głowala (@DamianGlowala)
- Bobbie Goede (@BobbieGoede)
- Robin (@OrbisK)
- Bobby (@xanzhu)
- kit: Get absolute path from
- 3.18.029 Jul 2025
Release notes
Open source →3.18.0 is the next minor release.
👀 Highlights
A huge thank you to everyone who's been a part of this release, which is mostly about backporting features + bugfixes from Nuxt v4.
Over the next six months, we'll continue backporting compatible v4 features and bug fixes, so please keep the feedback coming! ❤️
🧪 Lazy Hydration Macros
Building on the delayed hydration support from v3.16, we now support lazy hydration macros (#31192)! These provide a more ergonomic way to control component hydration:
<script setup lang="ts"> const LazyHydrationMyComponent = defineLazyHydrationComponent( 'visible', () => import('./components/MyComponent.vue') ) </script> <template> <div> <!-- Hydration will be triggered when the element(s) is 100px away from entering the viewport. --> <LazyHydrationMyComponent :hydrate-on-visible="{ rootMargin: '100px' }" /> </div> </template>These macros make it possible to use Nuxt's lazy hydration utilities alongside explicit component imports.
♿️ Accessibility Improvements
We've enhanced accessibility by including
<NuxtRouteAnnouncer>in the built-inapp.vue(#32621). This means page changes will be announced to screen readers, making navigation more accessible for users with visual impairments. (This only applies if you do not have anapp.vuein your project. If you do, please keep<NuxtRouteAnnouncer>in yourapp.vue!)🛠️ Enhanced Development Experience
Chrome DevTools Workspace Integration
We've added Chrome DevTools workspace integration (#32084), allowing you to edit your Nuxt source files directly from Chrome DevTools. This creates a better debugging experience where changes made in DevTools are reflected in your actual source files.
Better Component Type Safety
Component type safety has been improved with:
- Typed slots for
<ClientOnly>and<DevOnly>(#32707) - better IntelliSense and error checking - Exported
<NuxtTime>prop types (#32547) - easier to extend and customize
New Auto-Import:
onWatcherCleanupThe
onWatcherCleanupfunction fromvueis now available as an auto-import (#32396), making it easier to clean up watchers and prevent memory leaks:const { data } = useAsyncData('users', fetchUsers) watch(data, (newData) => { const interval = setInterval(() => { // Some periodic task }, 1000) // Clean up when the watcher is stopped onWatcherCleanup(() => { clearInterval(interval) }) })📊 Observability Enhancements
Page routes are now exposed to Nitro for observability (#32617), enabling better monitoring and analytics integration with supported platforms. This allows observability tools to track page-level metrics more effectively.
🔧 Module Development Improvements
Module authors get several quality-of-life improvements:
Simplified Server Imports
The
addServerImportskit utility now supports single imports (#32289), making it easier to add individual server utilities:// Before: had to wrap in array addServerImports([{ from: 'my-package', name: 'myUtility' }]) // Now: can pass directly addServerImports({ from: 'my-package', name: 'myUtility' })TypeScript Configuration
Modules can now add to
typescript.hoist(#32601), giving them more control over TypeScript configuration and type generation.⚡️ Performance Improvements
We've made several performance optimizations:
- Improved Vite-node communication via internal socket (#32417) for faster development builds
- Migration to
oxc-walker(#32250) and oxc foronPrehydratetransforms (#32045) for faster code transformations
🐛 Bug Fixes
This release also includes several important fixes:
- Improved data fetching: When computed keys change, old data is now properly retained (#32616)
- Better scroll behavior:
scrollBehaviorTypeis now only used for hash scrolling (#32622) - Fixed directory aliases: Added trailing slashes to some directory aliases for better consistency (#32755)
✅ Upgrading
As usual, our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis refreshes your lockfile and pulls in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- nuxt: Expose page routes to nitro for o11y (#32617)
- nuxt: Export
<NuxtTime>prop types (#32547) - nuxt: Add integration with chrome devtools workspaces (#32084)
- kit: Support single import in
addServerImports(#32289) - nuxt: Add
onWatcherCleanupto imports presets (#32396) - nuxt: Add route announcer to default app.vue (#32621)
- nuxt: Support lazy hydration macros (#31192)
🔥 Performance
- vite: Communicate with vite-node via internal socket (#32417)
- kit: Update env expansion regex to match nitro (#30766)
🩹 Fixes
- nuxt: Allow modules to add to
typescript.hoist(#32601) - nuxt: Retain old data when computed key changes (#32616)
- nuxt: Only use
scrollBehaviorTypefor hash scrolling (#32622) - nuxt: Add missing
async(fd312af03) - nuxt: Fix transform/minify types + bump oxc-transform (d2ba19963)
- nuxt: Provide typed slots for
<ClientOnly>and<DevOnly>(#32707) - kit,nuxt,schema: Add trailing slash to some dir aliases (#32755)
- nuxt: Include source base url for remote islands (#32772)
- vite: Use vite node server to transform requests (#32791)
- kit: Use
mllyto parse module paths (#32386) - nuxt: Execute all plugins after error rendering error.vue (#32744)
💅 Refactors
- nuxt: Migrate to
oxc-walker(#32250) - nuxt,schema: Use oxc for
onPrehydratetransform (#32045) - nuxt: Pass file language directly to parser options (#32665)
- nuxt: Use direct import of
installNuxtModule(228e3585e)
📖 Documentation
- Pass
v3template to create nuxt examples (03182202f) - Add reference to
useNuxtDatain data fetching composable pages (#32589) - Document the --modules flag in the init command (#32599)
- Added new Shared folder to the example of v4 folder structure (#32630)
- Improve grammar (#32640)
- Typos (#32567)
- Fix abbreviation (#32613)
- Reference
noUncheckedIndexedAccessrule change in v4 guide (#32643) - Fix links to Nitro docs (#32691)
- Add best practices section (#31609)
- Correct alias for local fonts in styling guide (#32680)
- Update nuxt.new links to v4 (#32639)
- Set correct default value for deep option in usefetch (#32724)
- Fix link to issue (ca03f533f)
- Add AI-assisted contribution guidelines (#32725)
- Update Nuxt installation command to use
npm create nuxt@latest(#32726) - Hydration best practice (#32746)
- Add example for module
.with()(#32757) - Replace dead Vue Router docs links (#32779)
🏡 Chore
- Handle missing commit details (0af98763d)
- Update reproduction links for bug-report template (#32722)
- Update
unbuildand use absolute path in dev stubs (#32759)
✅ Tests
- Also assert status (4b4b224f7)
- Ignore vue
module.exportsexport (ac8b02d09) - Extend timeout when waiting for hydration (49c01ba81)
- Benchmark minimal fixture instead (#31174)
- Add minimal pages fixture (#30457)
- Bump bundle size (bafa953c3)
🤖 CI
- Trigger website redeploy on main branch (#32695)
- Release
pkg.pr.newformain/3.xbranches as well (ca4f0b1da) - Apply
3xtag to latest v3 release (5e8dfc150)
❤️ Contributors
- Daniel Roe (@danielroe)
- Bobbie Goede (@BobbieGoede)
- Damian Głowala (@DamianGlowala)
- Dog (@dgxo)
- Julien Huang (@huang-julien)
- Yauheni Vasiukevich (@EvgenyWas)
- Alex Liu (@Mini-ghost)
- Robin (@OrbisK)
- Mateleo (@Mateleo)
- Stephen Jason Wang (@stephenjason89)
- Maurits Meester (@mmeester)
- Igor Kononenko (@igorexa34314)
- Alex (@hywax)
- Matej Černý (@cernymatej)
- Alexander Lichter (@TheAlexLichter)
- Hashim Kalam (@hashimkalam)
- Alois Sečkár (@AloisSeckar)
- Haythem Frikha (@Flamenate)
- abeer0 (@iiio2)
- Thomas (@ThomasWT)
- Connor Pearson (@cjpearson)
- dwood-csi (@dwood-csi)
- Typed slots for
- 3.17.713 Jul 2025
Release notes
Open source →3.17.7 is the last patch release before v3.18.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- nuxt: Safe-guard
extraPageMetaExtractionKeys(#32510) - nuxt: Expose
loadBuildererror cause (8f13ce3c2) - vite: Handle resolving string vite input (#32527)
- nuxt: Wrap only server components with island generic (#32540)
- vite: Ignore when client entry cannot be resolved (19a292f34)
- nuxt: Normalize segment catchall pattern before checking for parent (#32413)
- nuxt: Update warning message to warn against
nullvalues (c1b83eab5) - nuxt: Ensure
semver.satisfiesreturns true for pre-release versions (#32574) - nuxt: Scroll to anchor if present when changing page without saved position (#32376)
- nuxt: Handle
execute being passed towatch` (#32591)
📖 Documentation
- Update fetch types (#32522)
- Clarify that runtime env variables must start with
NUXT_(#32223) - Fix key change behavior in
useAsyncDataanduseFetchmigration (#32560) - Change return type of async data from
undefinedtonullin v3 docs (#32562) - Add section on custom hooks for Nuxt modules (#32586)
- Provide
asynckeyword (#32587) - Move augmenting hook types in hooks page (#32595)
- Add section about module loading order (#32597)
✅ Tests
- Reenable skipped unit tests (8fc9b9ee9)
- Update test snapshot for
generateTypes(c0855439d) - Improve page scanning test stability (84b96f3de)
- Pass timeZone in to
<NuxtTime>test (#32558) - Add more useAsyncData + useFetch tests (#32585)
- Avoid hard-coding async-data keys (bfca95118)
❤️ Contributors
- Daniel Roe (@danielroe)
- Julien Huang (@huang-julien)
- abeer0 (@iiio2)
- Bobbie Goede (@BobbieGoede)
- Damian Głowala (@DamianGlowala)
- Nestor Vera (@hacknug)
- Ezra Ashenafi (@Eazash)
- Mike Laumann Bellika (@MikeBellika)
- Maxime Pauvert (@maximepvrt)
- Chriest Yu (@jcppman)
- Andrei Hudalla (@paranoidPhantom)
- Sigrid Huemer (@s1gr1d)
- xjccc (@xjccc)
- nuxt: Safe-guard
- 3.17.61 Jul 2025
Release notes
Open source →3.17.6 is a regularly scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- nuxt: Decrease if checks when prerendering (#32455)
🩹 Fixes
- nuxt: Generate correct types for async data defaults based on
nuxt.config(#32324) - nuxt: Reload at base URL in
nuxt:chunk-reload-immediate(#32382) - nuxt: Use rollup to calculate island component filenames (#32421)
- nuxt: Append
set-cookieheaders in error handler (#32483) - nuxt: Ensure
asyncDataruns if changing key while fetcher is running (#32466) - nuxt: Handle pure hash link clicks with
navigateTo(#32393) - nuxt: Skip external
<NuxtLink>'s custom on click handler (#32499) - nuxt: Update component loader regexp for minified code (#32298)
- nuxt: Allow camelCase for lazy hydration attributes (#32297)
- nuxt: Respect
inheritAttrs: falseincreateClientOnlyfn (#32323) - kit: Do not double-urlify file urls when resolving schema (#32354)
- nuxt: Align scroll behavior with page transition completion (#32239)
- nuxt: Set
output.generatedCode.symbolsfor nitro build (#32358) - nuxt: Lazily access runtimeConfig (#32428)
💅 Refactors
- vite: Migrate plugins internally to vite environments (#32461)
📖 Documentation
- Clarify where logging tag is displayed (#32440)
- Remove kit playground auto-import note (#32415)
- Remove webstorm warning (#32513)
- Migrate to
h3js(#32243) - Update the fetch
clearfunction description (#32287) defineNuxtPluginfunction documentation (#32328)- Mention that
<NuxtLink>encodes query params (#32361) - Enhance documentation for Nuxt composables (#32218)
- Adjust wording to reduce confusion in lifecycle section (#32503)
- Improve useCookie example (367b85405)
- Capitalise title (#32426)
- Mention
bun.lockfor lockfile (#32427)
🏡 Chore
- Update stackblitz reproduction link (6ab5bac66)
- Update copilot instructions (220439055)
- Rename deprecated vitest
workspacetoprojects(#32388) - Remove space in URL in comment (#32394)
- Allow setting TAG on commandline (d387e07a3)
✅ Tests
- nuxt: Add case for key only changes with
immediate: false(#32473) - Separate nuxt legacy runtime tests (#32481)
🤖 CI
- Set correct base branch label (#32325)
❤️ Contributors
- Mihailo Bursac (@djixadin)
- Daniel Roe (@danielroe)
- abeer0 (@iiio2)
- 翠 (@sapphi-red)
- Robin (@OrbisK)
- Alex Liu (@Mini-ghost)
- Damian Głowala (@DamianGlowala)
- Julien Huang (@huang-julien)
- Ibrahimm (@Ibra-cesar)
- Peter Budai (@peterbud)
- Ali Soueidan (@lazercaveman)
- Vachmara (@vachmara)
- xjccc (@xjccc)
- Paul Melero (@paulmelero)
- David Stack (@davidstackio)
- 3.17.53 Jun 2025
Release notes
Open source →3.17.5 is a regularly scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxt upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- nuxt: Replace remaining instance of
globby(#31688)
🩹 Fixes
- nuxt: Export
useScriptRybbitAnalyticsfrom script stubs (d275ae1a0) - nuxt: Remove unneeded pattern from regexp (2954c092c)
- nuxt: Ensure
appConfigsources are not duplicated (#32216) - nuxt: Wrap slot with
h()in ClientOnly (#30664) - kit: Ensure template filename uses safe patterns (4372b24dd)
- nuxt: Access
asyncDatastate from nuxt app instance (#32232) - nuxt: Make patterns relative to
srcDirinbuildCache(#32260) - nuxt: Return non-existent route component in RouteProvider (#32266)
- nuxt: Use single
asyncDatawatcher (#32247) - vite: Use arrow functions in dynamic imports (#32285)
- webpack: Use plugin for rollup-compatible dynamic imports (#32281)
📖 Documentation
- Update
addRouteMiddlewarepath in example (#32171) - Narrow link to just middleware (#32203)
- Use optional chaining in error example (#32214)
- Give example of using
--env-file(29f6392cd) - Recommend
nuxtcommand consistently (#32237) - Fix typos (#30413)
- Add props to special metadata (#29708)
- Fix wrong
alertwithwarningin/guide/pages(#32270) - Update upgrade guide + roadmap (0040ee5e7)
📦 Build
- nuxt: Ensure cache is typed (33df20d17)
🏡 Chore
- Upgrade webpack dependencies separately (444d60936)
- Apply lint fixes (221ce99eb)
- Add missing dependency (720170dea)
✅ Tests
- Add regression test for useAsyncData + transition (29f7c8cb4)
- Ensure builder tests run sequentially (defa32829)
❤️ Contributors
- Daniel Roe (@danielroe)
- Julien Huang (@huang-julien)
- Hugo Richard (@HugoRCD)
- mxmxmmgg (@mxmxmmgg)
- xjccc (@xjccc)
- Horu (@HigherOrderLogic)
- Baptiste Leproux (@larbish)
- Phojie Rengel (@phojie)
- duolaameng (@1411430556)
- David Stack (@davidstackio)
- nuxt: Replace remaining instance of
- 3.17.420 May 2025
Release notes
Open source →3.17.4 is a regularly-scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- nuxt: Use Set for circular dep plugin (#32110)
- Refactor Array.includes checks to use Sets (#32133)
- nuxt: Use
shallowReffor primitive values (#32152) - nuxt: Skip route rules processing for empty child array (#32166)
- nuxt: Use
Intl.Collatorinstead oflocaleCompare(#32167)
🩹 Fixes
- nuxt: Do not await lazy asyncData inside
<ClientOnly>(#32101) - nuxt: Respect cachedData with multiple asyncData calls (#32099)
- nuxt: Clear async data after a tick (#32096)
- nuxt: Support reactive keys in
useLazyAsyncData(#32092) - rspack: Use
ts-checker-rspack-plugin(#32115) - nuxt: Clear previous head in island-renderer (#32100)
- nuxt: Handle virtual files prefixed with
/(#32129) - schema: Remove nitro options from
DeepPartial(#31990) - nuxt: Ensure legacy async data remains reactive (#32134)
- nuxt: Pass attrs down to single child of
<ClientOnly>(#32131) - nuxt: Fix merge conflicts (7044450d4)
- nuxt: Clone vnode when passing attrs down to client-only (b3acf0c78)
- vite: Do not replace
globalwithglobalThis(#32130) - nuxt: Suppress client-side errors by crawlers (#32137)
- nuxt: Use fresh route when
<NuxtLayout>first renders (#24673) - nuxt: Add additional logging when skipping error page for bot (68c270083)
- nuxt: Add watch paths outside
srcDirto parcel strategy (#32139)
📖 Documentation
- Use emphasis instead of quotes (#32078)
- Update
useNuxtDatadefault return toundefined(#32054) - Capitalise headings (#32095)
- Prefix
imports.dirswith alias (0dbf314d9) - Mention node v20 is minimum requirement for nuxt setup (#32148)
- Use more descriptive link text (d0b1b9d35)
🏡 Chore
✅ Tests
- Add universal routing tests + clean up output (64178b6f4)
- nuxt: Add unit tests for watch strategies (#32138)
- Resolve watch path (8fb562c04)
- Use fake timers instead of
setTimeoutmock (#32142)
🤖 CI
❤️ Contributors
- John Tanzer (@moshetanzer)
- Daniel Roe (@danielroe)
- Robin (@OrbisK)
- @beer (@iiio2)
- Julien Huang (@huang-julien)
- हिमांशु (@CodeMan62)
- Norbiros (@Norbiros)
- watsonhaw5566 (@watsonhaw5566)
- xjccc (@xjccc)
- 3.17.312 May 2025
Release notes
Open source →3.17.3 is a regularly-scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- nuxt: Pre-calculate extension glob before app resolution (#32052)
- nuxt: Improve islands client components chunks (#32015)
🩹 Fixes
- nuxt: Preload async layouts (#32002)
- nuxt: Handle File within
FormData(#32013) - schema: Respect user-provided
ignorepatterns (#32020) - nuxt: Allow loading virtual files with query params (#32022)
- nuxt: Don't use reactive key for
useFetchwithwatch: false(#32019) - nuxt: Do not clear data if custom
getCachedDatais provided (#32003) - nuxt: Provide
nuxtAppfor asyncData functions run on server (#32038) - vite: Strip queries when skipping vite transform middleware (#32041)
- nuxt: Sort hash sources and files (#32048)
- nuxt: Do not suppress chunk import error (#32064)
💅 Refactors
- nuxt: Directly access initialised
asyncData(e779d6cd5)
📖 Documentation
- Fix module initialization command for pnpm (#32024)
- Provide nuxt installation guide with deno (#32029)
- Add codeblock closing tag (#32043)
- Tweak nuxt doc (#32063)
- Add space between sentences (#32069)
🤖 CI
- Convert
bug/enhancementlabels to issue types (3ff743fe0) - Update payload for issue types (791e5f443)
❤️ Contributors
- Ryota Watanabe (@wattanx)
- Julien Huang (@huang-julien)
- John Tanzer (@moshetanzer)
- @beer (@iiio2)
- Daniel Roe (@danielroe)
- xjccc (@xjccc)
- Max (@onmax)
- 3.17.25 May 2025
Release notes
Open source →3.17.2 is a regularly-scheduled patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- nuxt: Tree-shake router's
handleHotUpdatein production (#31971)
🩹 Fixes
- nuxt: Ensure asyncData is initialised before effects run (#31946)
- nuxt: Skip view transition if user agent provides one before defining
transition(#31945) - nuxt: Improve hashing for complex body in
useFetch(#31963) - nuxt: Immediately call asyncData within client-only components (#31964)
- nuxt: Don't render errors if event is already handled (#31966)
- nuxt: Track whether need to reinit asyncData separately from deps (#31965)
- nuxt: Preserve params/meta/matched with universal router (#31950)
- nuxt: Respect scroll behavior set by
scrollToTop(#31914) - nuxt: Load live data from
vfseven if a file exists inbuildDir(#31969) - nuxt: Short circuit middleware when validate returns false (#31967)
- nuxt: Ensure
useAsyncDatareactive tokeychanges whenimmediate: false(#31987) - nuxt: Resolve real paths imported into virtual files (0bb07f129)
- webpack: Broaden
WarningFiltertype (2a79dbd68) - schema: Broaden
warningIgnoreFilters(a62e808ac)
📖 Documentation
- Add missing article (#31952)
- Improve
@nuxt/kitdocumentation (#31793) - Fix type issues in twoslash blocks (85ab105b8)
- Add events page (#31977)
🏡 Chore
✅ Tests
- Update bundle size snapshot (e03d44b47)
- Update bundle size (7f75f5ea5)
- Update bundle size again (e8a244bfc)
- Use
asyncDataDefaults.value(91568c5da)
🤖 CI
❤️ Contributors
- Daniel Roe (@danielroe)
- Alex Liu (@Mini-ghost)
- Martins Zeltins (@martinszeltins)
- Ivan Martianov (@ivansky)
- Lorenzo Fiamingo (@lorenzofiamingo)
- James (@Koshux)
- nuxt: Tree-shake router's
- 3.17.129 Apr 2025
Release notes
Open source →3.17.1 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🩹 Fixes
- nuxt: Check if match exists with new unplugin filter (#31929)
- nuxt: Reinitialise stale async data (#31940)
- nuxt: Skip view transition if user agent is providing one (#31938)
- nuxt: Trigger
executewhen non-immediate fetch key changes (#31941) - nuxt: Don't redirect when route has trailing slash (#31902)
- ui-templates: Use
escapeHTMLfrom vue (8e4b8d62f) - schema: Add
@vue/shareddependency (7d445c963)
📦 Build
- Copy README/LICENSE from repo root (8e287d556)
🏡 Chore
✅ Tests
- Update snapshots (a197d1087)
❤️ Contributors
- Daniel Roe (@danielroe)
- Pooya Parsa (@pi0)
- Kyohei Sonokawa (@kyohei-23)
- Lorenzo Fiamingo (@lorenzofiamingo)
- 3.17.027 Apr 2025
Release notes
Open source →👀 Highlights
This release brings a major reworking of the async data layer, a new built-in component, better warnings, and performance improvements!
📊 Data Fetching Improvements
A major reorganization of Nuxt's data fetching layer brings significant improvements to
useAsyncDataanduseFetch.Although we have aimed to maintain backward compatibility and put breaking changes behind the
experimental.granularCachedDataflag (disabled by default), we recommend testing your application thoroughly after upgrading. You can also disableexperimental.purgeCachedDatato revert to the previous behavior if you are relying on cached data being available indefinitely after components usinguseAsyncDataare unmounted.👉 Read the the original PR for full details (#31373), but here are a few highlights.
Consistent Data Across Components
All calls to
useAsyncDataoruseFetchwith the same key now share the underlying refs, ensuring consistency across your application:<!-- ComponentA.vue --> <script setup> const { data: users, pending } = useAsyncData('users', fetchUsers) </script> <!-- ComponentB.vue --> <script setup> // This will reference the same data state as ComponentA const { data: users, status } = useAsyncData('users', fetchUsers) // When either component refreshes the data, both will update consistently </script>This solves various issues where components could have inconsistent data states.
Reactive Keys
You can now use computed refs, plain refs, or getter functions as keys:
const userId = ref('123') const { data: user } = useAsyncData( computed(() => `user-${userId.value}`), () => fetchUser(userId.value) ) // Changing the userId will automatically trigger a new data fetch // and clean up the old data if no other components are using it userId.value = '456'Optimized Data Refetching
Multiple components watching the same data source will now trigger only a single data fetch when dependencies change:
// In multiple components: const { data } = useAsyncData( 'users', () => $fetch(`/api/users?page=${route.query.page}`), { watch: [() => route.query.page] } ) // When route.query.page changes, only one fetch operation will occur // All components using this key will update simultaneously🎭 Built-In Nuxt Components
<NuxtTime>- A new component for safe time displayWe've added a new
<NuxtTime>component for SSR-safe time display, which resolves hydration mismatches when working with dates (#31876):<template> <NuxtTime :datetime="Date.now()" /> </template>The component accepts multiple time formats and gracefully handles both client and server rendering.
Enhanced
<NuxtErrorBoundary>The
<NuxtErrorBoundary>component has been converted to a Single File Component and now exposeserrorandclearErrorfrom the component - as well as in the error slot types, giving you greater ability to handle errors in your templates and viauseTemplateRef(#31847):<NuxtErrorBoundary @error="handleError"> <template #error="{ error, clearError }"> <div> <p>{{ error.message }}</p> <button @click="clearError">Try again</button> </div> </template> <!-- Content that might error --> <MyComponent /> </NuxtErrorBoundary>🔗 Router Improvements
<NuxtLink>now accepts atrailingSlashprop, giving you more control over URL formatting (#31820):<NuxtLink to="/about" trailing-slash>About</NuxtLink> <!-- Will render <a href="/about/"> -->🔄 Loading Indicator Customization
You can now customize the loading indicator with new props directly on the component (#31532):
hideDelay: Controls how long to wait before hiding the loading barresetDelay: Controls how long to wait before resetting loading indicator state
<template> <NuxtLoadingIndicator :hide-delay="500" :reset-delay="300" /> </template>📚 Documentation as a Package
The Nuxt documentation is now available as an npm package! You can install
@nuxt/docsto access the raw markdown and YAML content used to build the documentation website (#31353).💻 Developer Experience Improvements
We've added several warnings to help catch common mistakes:
- Warning when server components don't have a root element #31365
- Warning when using the reserved
runtimeConfig.appnamespace #31774 - Warning when core auto-import presets are overridden #29971
- Error when
definePageMetais used more than once in a file #31634
🔌 Enhanced Module Development
Module authors will be happy to know:
- A new
experimental.enforceModuleCompatibilityallows Nuxt to throw an error when a module is loaded that isn't compatible with it (#31657). It will be enabled by default in Nuxt v4. - You can now automatically register every component exported via named exports from a file with
addComponentExports#27155
🔥 Performance Improvements
Several performance improvements have been made:
- Switched to
tinyglobbyfor faster file globbing #31668 - Excluded
.datadirectory from type-checking for faster builds #31738 - Improved tree-shaking by hoisting the
purgeCachedDatacheck #31785
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis refreshes your lockfile and pulls in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- nuxt: Accept
hideDelayandresetDelayprops for loading indicator (#31532) - nuxt: Warn server components need root element (#31365)
- docs: Publish raw markdown/yaml docs as
@nuxt/docs(#31353) - kit,nuxt: Pass dotenv values from
loadNuxtConfigto nitro (#31680) - nuxt,vite: Support disabling scripts in dev mode (#31724)
- nuxt: Warn if user uses reserved
runtimeConfig.appnamespace (#31774) - kit,schema: Allow throwing error if modules aren't compatible (#31657)
- nuxt: Extract
middlewarewhen scanning page metadata (#30708) - nuxt: Warn if core auto-import presets are overridden (#29971)
- nuxt: Scan named exports with
addComponentExports(#27155) - nuxt: Convert
<NuxtErrorBoundary>to SFC + exposeerror/clearError(#31847) - nuxt: Add
<NuxtTime>component for ssr-safe time display (#31876) - nuxt: Add
trailingSlashprop to<NuxtLink>(#31820)
🔥 Performance
- kit,rspack,webpack: Switch to
tinyglobby(#31668) - kit: Exclude
.datadirectory from type-checking (#31738) - nuxt: Hoist
purgeCachedDatacheck to improve tree-shaking (#31785) - nuxt: Remove
oxc-parsermanual wasm fallback logic (#31484) - nuxt: Remove unecessary type check for useFetch (#31910)
🩹 Fixes
- kit,vite: Ensure all
modulesDirpaths are added tofs.allow(#31540) - nuxt: Pass slots through to lazy hydrated components (#31649)
- vite: Do not return 404 for dev server handlers which shadow
/_nuxt/(#31646) - nuxt: Sync error types for
useLazyAsyncData(#31676) - nuxt: Strip base url from
error.url(#31679) - nuxt: Render inline styles before
app:renderedis called (#31686) - nuxt: Update nitro imports (0bec0bd26)
- nuxt: Check for
fallbackattribute when stripping<DevOnly>(c1d735c27) - vite: Invalidate files not present in module graph (ecae2cd54)
- nuxt: Do not add manifest preload when
noScripts(c9572e953) - nuxt: Do not prompt to update
compatibilityDate(#31725) - nuxt: Show brotli size by default when analyzing bundle (#31784)
- nuxt: Always pass
statusMessagewhen rendering html error (#31761) - nuxt: Error when
definePageMetais used more than once (#31634) - nuxt: Parse
error.databefore renderingerror.vue(#31571) - nuxt: Use single synced asyncdata instance per key (#31373)
- nuxt: Use
useAsyncDatain console log (#31801) - nuxt: Wait for suspense to resolve before handling
NuxtErrorBoundaryerror (#31791) - vite: Disable
preserveModules(#31839) - nuxt: Align
pendingwithstatusvalue for v4 (#25864) - nuxt: Consider full path when de-duplicating routes (#31849)
- nuxt: Augment
nuxt/appin generated middleware and layouts declarations (#31808) - nuxt: Correct order of args passed to
withoutBase(f956407bb) - vite: Dedupe
vuein vite-node dev server (f3882e004) - ui-templates: Pass pointer events through spotlight div in error dev template (#31887)
- kit: Include user-defined types before internal ones in
tsconfig.json(#31882) - nuxt: Do not purge nuxt data if active
useNuxtData(#31893) - nuxt: Do not include components of key in
useFetchwatch sources (#31903) - nuxt: Use first existing
modulesDirto store build cache files (#31907)
💅 Refactors
- nuxt: Use
shallowReffor primitives as well (#31662) - nuxt: Move island renderer into its own event handler (#31386)
- nuxt: Remove unneeded import (#31750)
- nuxt: Use
_replaceAppConfigwhen applying hmr (#31786) - nuxt: Use new unplugin filter options (#31868)
- schema: Do not generate types for
ConfigSchema(#31894)
📖 Documentation
- Add note on extending auto-imports (#31640)
- Improve description of
app.vue(#31645) - Use video-accordion video and add more videos (#31655)
- Add description of
templateParamsto seo docs (#31583) - Refine auto-imports documentation (#31700)
- Fix nuxt logo on website badge (#31704)
- Update tailwindcss link (b5741cb5a)
- Adjust description of
useHydration(#31712) - Remove trailing slash (#31751)
- Remove comment about
callOncereturning value (#31747) - Use
vs.consistently (#31760) - Update nitro
addServerHandlerexample (#31769) - Add supporting shared folder video (#31651)
- Update example for component auto-import in nuxt modules (#31757)
- Refine nuxt kit components documentation (#31714)
- Use trailing slash for vitest link (82de8bcf8)
- Fix casing (#31805)
- Add discord and nuxters links (#31888)
- Fix typos (#31898)
📦 Build
- nuxt: Use
vue-sfc-transformerto process sfcs (#31691)
🏡 Chore
- Update renovate config (565c0b98e)
- Upgrade webpack separately (e1f5db34f)
- Update internal ui-templates licence to MIT (f8059fb8b)
- Sort package.json (a6cbd71f8)
✅ Tests
- nuxt: Add customizable test api for pages tests (#31619)
- kit: Fix tests when running on Windows (#31694)
- Update page metadata snapshot (89a596075)
- Add basic runtime tests for
<NuxtErrorBoundary>(4df92c45f) - Add version to mock nuxt (915fae2fd)
- Update assertion for
pendingWhenIdle(08f2224c8) - Remove incorrect assertions (fdc4b5343)
- Update tests for purgeCachedData (c6411eb17)
🤖 CI
- Add notify-nuxt-website workflow (#31726)
❤️ Contributors
- @beer (@iiio2)
- Julien Huang (@huang-julien)
- Daniel Roe (@danielroe)
- Saeid Zareie (@Saeid-Za)
- Bobbie Goede (@BobbieGoede)
- Damian Głowala (@DamianGlowala)
- Maxime Pauvert (@maximepvrt)
- Leonid (@john-psina)
- Wind (@productdevbook)
- Arkadiusz Sygulski (@Aareksio)
- Rohan Dhimal (@drowhannn)
- xjccc (@xjccc)
- Robin (@OrbisK)
- Alex Liu (@Mini-ghost)
- Daniel Kelly (@danielkellyio)
- Jeffrey van den Hondel (@jeffreyvdhondel)
- Alexander Lichter (@TheAlexLichter)
- Sébastien Chopin (@atinux)
- Yizack Rangel (@Yizack)
- Joaquín Sánchez (@userquin)
- IlyaL (@ilyaliao)
- Ben McCann (@benmccann)
- Anthony Fu (@antfu)
- Alexandru Ungureanu (@unguul)
- 3.16.21 Apr 2025
Release notes
Open source →3.16.2 is the next patch release.
✅ Upgrading
Our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis will deduplicate your lockfile as well, and help ensure that you pull in updates from other dependencies that Nuxt relies on, particularly in the unjs ecosystem.
👉 Changelog
🔥 Performance
- nuxt: Improve tree-shaking of
useRequestEventon client (#31586)
🩹 Fixes
- nuxt: Pass down attrs to
<Body>and<Html>(#31513) - nuxt: Use greedy catchall when
/indexis the last segment (#31528) - nuxt: Reset
page:loading:endhook before navigation (#31504) - nuxt: Write initial cookie value if different from
document.cookie(#31517) - nuxt: Support template string quotes in
resolveComponent(#31526) - nuxt: Show fatal errors thrown in middleware (#31518)
- nuxt: Use name to index route providers in dev (#31544)
- nuxt: Improve default scroll behaviour (#31545)
- vite: Return 404 for non-existent
_nuxt/paths in development (#31543) - nuxt: Pass error data to
error.vue(#31573) - nuxt: Use
unheadv2 api in default welcome + error pages (#31584) - nuxt: Improve consistency of page metadata extraction (#31306)
- nuxt: Do not remove meta when
scanPageMetais disabled (0ba454b21)
💅 Refactors
- nuxt: Simplify conditional branches of
<NuxtPage>(#31561) - Replace
useServerHeadinonPrehydratewithuseHead(#31585)
📖 Documentation
- Move custom directories note to the correct place (#29100)
- Update example to
useTemplateRef(#31458) - Provide async function for
$fetch(#31459) - Mention the possibility to scan pages based on a pattern (#31462)
- Add
dedupeflag (#31467) - Improve
refreshNuxtDatadocs (#31448) - Add missing
--before--template(#31469) - Migrate to @nuxt/content v3 (#31150)
- Fix icon for main docs (e7828d9c6)
- Save selected package manager (#31520)
- Improve refresh nuxt data example (#31487)
- Note that middleware runs on error pages as well (df14c0263)
- Replace all 'Nuxt 3' with 'Nuxt' in documentation (#31519)
resolveComponentonly auto-imports components with literal strings (#31511)- Add ticks around
tsconfig.json(#31473) - Capitalize heading (#31523)
- Update links to unhead.unjs.io (1913febbb)
- Document that props are passed via server components via query (db7688219)
- Improve description of
page:startandpage:finishhooks (#31570)
🏡 Chore
- Ignore builds (e34ae380d)
✅ Tests
- Avoid invalid nested font face (#31524)
- Add test for loading indicator with custom key (25ca9b819)
- Add test for custom prop + loading indicator (94bfed031)
- Update snapshot (55134fc2a)
❤️ Contributors
- Daniel Roe (@danielroe)
- Julien Huang (@huang-julien)
- Bobbie Goede (@BobbieGoede)
- Alex Liu (@Mini-ghost)
- Dennis Adriaansen (@dennisadriaans)
- Guillaume Chau (@Akryum)
- @beer (@iiio2)
- 翠 / green (@sapphi-red)
- xjccc (@xjccc)
- Hugo Richard (@HugoRCD)
- Sébastien Chopin (@atinux)
- Johannes Buchholz (@jhony1104)
- Alexander Lichter (@TheAlexLichter)
- Matej Černý (@cernymatej)
- Claudiu (@sofuxro)
- nuxt: Improve tree-shaking of
- 3.16.119 Mar 2025
Release notes
Open source →🔥 Performance
- nuxt: Use browser cache for payloads (#31379)
🩹 Fixes
- nuxt: Restore nuxt aliases to nitro compilerOptions.paths (#31278)
- nuxt: Use new
mocked-exports(#31295) - nuxt: Check resolved options for polyfills (#31307)
- nuxt: Render style component html (#31337)
- nuxt: Add missing lazy hydration prop in regex (#31359)
- nuxt: Fully resolve nuxt dependencies (#31436)
- vite: Don't show interim vite build output files (#31439)
- nuxt: Ignore prerendering unprefixed public assets (151912ec3)
- nuxt: Use more performant router catchall pattern (#31450)
- nuxt: Prevent param duplication in
typedPagesimplementation (#31331) - nuxt: Sort route paths before creating route tree (#31454)
📖 Documentation
- Update link to vercel edge network (ec20802a5)
- Improve HMR performance note for Windows users (#31301)
- Correct WSL note phrasing (#31322)
- Fix typo (#31341)
- Adjust
app.headexample (#31350) - Include package manager options in update script (#31346)
- Add missing comma (#31362)
- Add mention of
addServerTemplateto modules guide (#31369) - Add
rspackand removetest-utilsfor monorepo guide (#31371) - Adjust example (#31372)
- Update experimental docs (#31388)
- Use
inisyntax block highlighting for.envfiles (f79fabe46) - Improve
useHydrationdocs (#31427) - Update broken docs links (#31430)
- Mention possibility of prerendering api routes (#31234)
🏡 Chore
- Fix gitignore (6fe9dff7e)
- Bump axios dependency in lockfile (c3352e80b)
- Lint repo (2ab20bfdc)
- Add scorecard badge (#31302)
- Dedupe (be5d85f2b)
✅ Tests
- Migrate runtime compiler test to playwright (+ add test cases) (#31405)
- Migrate spa preloader tests to playwright (#31273)
- Use
srvxand random port for remote provider (#31432)
🤖 CI
❤️ Contributors
- Daniel Roe (@danielroe)
- Anoesj Sadraee (@Anoesj)
- Peter Radko (@Gwynerva)
- Adam DeHaven (@adamdehaven)
- Alex Liu (@Mini-ghost)
- Julien Huang (@huang-julien)
- Francesco Agnoletto (@Kornil)
- Guillaume Chau (@Akryum)
- imreegall (@imreegall)
- xjccc (@xjccc)
- Sam Blowes (@blowsie)
- Nimit012 (@Nimit012)
- Camille Coutens (@Kamsou)
- 3.16.07 Mar 2025
Release notes
Open source →👀 Highlights
There's a lot in this one!
⚡️ A New New Nuxt
Say hello to
create-nuxt, a new tool for starting Nuxt projects (big thanks to @devgar for donating the package name)!It's a streamlined version of
nuxi init- just a sixth of the size and bundled as a single file with all dependencies inlined, to get you going as fast as possible.Starting a new project is as simple as:
npm create nuxtSpecial thanks to @cmang for the beautiful ASCII-art. ❤️
Want to learn more about where we're headed with the Nuxt CLI? Check out our roadmap here, including our plans for an interactive modules selector.
🚀 Unhead v2
We've upgraded to
unheadv2, the engine behind Nuxt's<head>management. This major version removes deprecations and improves how context works:- For Nuxt 3 users, we're shipping a legacy compatibility build so nothing breaks
- The context implementation is now more direct via Nuxt itself
// Nuxt now re-exports composables while properly resolving the context export function useHead(input, options = {}) { const unhead = injectHead(options.nuxt) return head(input, { head: unhead, ...options }) }If you're using Unhead directly in your app, keep in mind:
- Import from Nuxt's auto-imports or
#app/composables/headinstead of@unhead/vue - Importing directly from
@unhead/vuemight lose async context
Don't worry though - we've maintained backward compatibility in Nuxt 3, so most users won't need to change anything!
If you've opted into
compatibilityVersion: 4, check out our upgrade guide for additional changes.🔧 Devtools v2 Upgrade
Nuxt Devtools has leveled up to v2 (#30889)!
You'll love the new features like custom editor selection, Discovery.js for inspecting resolved configs (perfect for debugging), the return of the schema generator, and slimmer dependencies.
One of our favorite improvements is the ability to track how modules modify your Nuxt configuration - giving you X-ray vision into what's happening under the hood.
👉 Discover all the details in the Nuxt DevTools release notes.
⚡️ Performance Improvements
We're continuing to make Nuxt faster, and there are a number of improvements in v3.16:
- Using
exsolvefor module resolution (#31124) along with the rest of the unjs ecosystem (nitro, c12, pkg-types, and more) - which dramatically speeds up module resolution - Smarter module resolution paths (#31037) - prioritizes direct imports for better efficiency
- Eliminated duplicated Nitro alias resolution (#31088) - leaner file handling
- Streamlined
loadNuxtby skipping unnecessary resolution steps (#31176) - faster startups - Adopt
oxc-parserfor parsing in Nuxt plugins (#30066)
All these speed boosts happen automatically - no configuration needed!
Shout out to CodSpeed with Vitest benchmarking to measure these improvements in CI - it has been really helpful.
To add some anecdotal evidence, my personal site at roe.dev loads 32% faster with v3.16, and nuxt.com is 28% faster. I hope you see similar results! ⚡️
🕰️ Delayed Hydration Support
We're very pleased to bring you native delayed/lazy hydration support (#26468)! This lets you control exactly when components hydrate, which can improve initial load performance and time-to-interactive. We're leveraging Vue's built-in hydration strategies - check them out in the Vue docs.
<template> <!-- Hydrate when component becomes visible in viewport --> <LazyExpensiveComponent hydrate-on-visible /> <!-- Hydrate when browser is idle --> <LazyHeavyComponent hydrate-on-idle /> <!-- Hydrate on interaction (mouseover in this case) --> <LazyDropdown hydrate-on-interaction="mouseover" /> <!-- Hydrate when media query matches --> <LazyMobileMenu hydrate-on-media-query="(max-width: 768px)" /> <!-- Hydrate after a specific delay in milliseconds --> <LazyFooter :hydrate-after="2000" /> </template>You can also listen for when hydration happens with the
@hydratedevent:<LazyComponent hydrate-on-visible @hydrated="onComponentHydrated" />Learn more about lazy hydration in our components documentation.
🧩 Advanced Pages Configuration
You can now fine-tune which files Nuxt scans for pages (#31090), giving you more control over your project structure:
export default defineNuxtConfig({ pages: { // Filter specific files or directories pattern: ['**/*.vue'], } })🔍 Enhanced Debugging
We've made debugging with the
debugoption more flexible! Now you can enable just the debug logs you need (#30578):export default defineNuxtConfig({ debug: { // Enable specific debugging features templates: true, modules: true, watchers: true, hooks: { client: true, server: true, }, nitro: true, router: true, hydration: true, } })Or keep it simple with
debug: trueto enable all these debugging features.🎨 Decorators Support
For the decorator fans out there (whoever you are!), we've added experimental support (#27672). As with all experimental features, feedback is much appreciated.
export default defineNuxtConfig({ experimental: { decorators: true } })function something (_method: () => unknown) { return () => 'decorated' } class SomeClass { @something public someMethod () { return 'initial' } } const value = new SomeClass().someMethod() // returns 'decorated'📛 Named Layer Aliases
It's been much requested, and it's here! Auto-scanned local layers (from your
~~/layersdirectory) now automatically create aliases. You can access your~~/layers/testlayer via#layers/test(#30948) - no configuration needed.If you want named aliases for other layers, you can add a name to your layer configuration:
export default defineNuxtConfig({ $meta: { name: 'example-layer', }, })This creates the alias
#layers/example-layerpointing to your layer - making imports cleaner and more intuitive.🧪 Error Handling Improvements
We've greatly improved error messages and source tracking (#31144):
- Better warnings for undefined
useAsyncDatacalls with precise file location information - Error pages now appear correctly on island page errors (#31081)
Plus, we're now using Nitro's beautiful error handling (powered by youch) to provide more helpful error messages in the terminal, complete with stacktrace support.
Nitro now also automatically applies source maps without requiring extra Node options, and we set appropriate security headers when rendering error pages.
📦 Module Development Improvements
For module authors, we've added the ability to augment Nitro types with
addTypeTemplate(#31079):// Inside your Nuxt module export default defineNuxtModule({ setup(options, nuxt) { addTypeTemplate({ filename: 'types/my-module.d.ts', getContents: () => ` declare module 'nitropack' { interface NitroRouteConfig { myCustomOption?: boolean } } ` }, { nitro: true }) } })⚙️ Nitro v2.11 Upgrade
We've upgraded to Nitro v2.11. There are so many improvements - more than I can cover in these brief release notes.
👉 Check out all the details in the Nitro v2.11.0 release notes.
📦 New
unjsMajor VersionsThis release includes several major version upgrades from the unjs ecosystem, focused on performance and smaller bundle sizes through ESM-only distributions:
- unenv upgraded to v2 (full rewrite)
- db0 upgraded to v0.3 (ESM-only, native node:sql, improvements)
- ohash upgraded to v2 (ESM-only, native node:crypto support, much faster)
- untyped upgraded to v2 (ESM-only, smaller install size)
- unimport upgraded to v4 (improvements)
- c12 upgraded to v3 (ESM-only)
- pathe upgraded to v2 (ESM-only)
- cookie-es upgraded to v2 (ESM-only)
- esbuild upgraded to v0.25
- chokidar upgraded to v4
✅ Upgrading
As usual, our recommendation for upgrading is to run:
npx nuxi@latest upgrade --dedupeThis refreshes your lockfile and pulls in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.
👉 Changelog
🚀 Enhancements
- nuxt: Upgrade
@nuxt/devtoolsto v2 (#30889) - nuxt: Granular debug options (#30578)
- nuxt: Add type hints for
NuxtPage(#30704) - nuxt: Support tracking changes to nuxt options by modules (#30555)
- nuxt: Allow disabling auto-imported polyfills (#30332)
- schema: Add runtime + internal type validation (#30844)
- kit,nuxt,schema: Support experimental decorators syntax (#27672)
- kit,nuxt: Allow multiple nuxts to run in one process (#30510)
- kit: Add named layer aliases (#30948)
- kit,nuxt,vite:
directoryToURLto normalise paths (#30986) - nuxt: Allow forcing
start/setin loading indicator (#30989) - nuxt: Allow specifying glob patterns for scanning
pages/(#31090) - nuxt: Add types for default
NuxtLinkslot (#31104) - nuxt: Delayed/lazy hydration support (#26468)
- vite: Add vite's modulepreload polyfill (#31164)
- nuxt: Show source file when warning about undefined useAsyncData (#31144)
- kit,nuxt: Augment nitro types with
addTypeTemplate(#31079) - kit,nuxt: Resolve template imports from originating module (#31175)
- nuxt: Use
oxc-parserinstead of esbuild + acorn (#30066) - nuxt: Upgrade to unhead v2 (#31169)
- nuxt: Align nuxt error handling with nitro (#31230)
🔥 Performance
- nuxt: Remove duplicated nitro alias resolution (#31088)
- kit: Try non-subpath routes first to resolve nuxt modules (#31037)
- nuxt: Migrate to use
exsolvefor module resolution (#31124) - kit: Skip extra module resolution step in
loadNuxt(#31176)
🩹 Fixes
- nuxt: Ensure
<NuxtLayout>fallbackprop is typed (#30832) - nuxt: Assign slot to be rendered for client components (#30768)
- nuxt,vite: Do not override vite import conditions (#30887)
- nuxt: Prevent
keepalivecache reset (#30807) - nuxt: Remove
divwrapper in client-only pages (#30425) - schema: Update type import to
nitropack(aba75bd5a) - vite: Use resolveId from vite-node to resolve deps (#30922)
- schema: Normalise additional experimental options (63e0c342c)
- nuxt: Delete existing properties in app config HMR (#30918)
- schema: Return
nullfrom resolve functions (d68e8ce57) - schema: Check if
app.head.metavalues are undefined (#30959) - nuxt: Make
shared/directories available within layers (#30843) - kit: Ensure nuxt is loaded from cwd rather than parent dir (#30910)
- ui-templates: Remove extra
<pre>when rendering dev errors (9aab69ec4) - nuxt: Use tsx loader for jsx blocks as well (#31014)
- Remove unimplemented
page:transition:starttype (#31040) - kit: Expose module dependency errors (#31035)
- nuxt: Deprioritise layer css imports (#31020)
- nuxt: Ensure
provide/injectwork insetupofdefineNuxtComponent(#30982) - nuxt: Decode URI components in cache driver methods (#30973)
- nuxt: Use
_for NuxtIsland name on server pages (#31072) - nuxt: Use
ohashto calculate legacy async data key without hash (#31087) - nuxt,schema: Resolve
shareddir from config (#31091) - kit,schema: Set esbuild target for experimental decorators (#31089)
- nuxt: Set
nuxt.options.pagesto detected configuration (#31101) - nuxt: Warn when
definePageMetadoes not receive an object (#31156) - nuxt: Fix nitro import statements for v2 (151cf7d49)
- nuxt: Update path to
no-ssrmiddleware handler (a99c59fbd) - nuxt: Align type of custom
navigatewithvue-router(7a1934509) - nuxt: Show error page on island page error (#31081)
- nuxt: Do not render payloads if disabled, and correct regexp (#31167)
- nuxt: Add backwards-compatible serialisation for
nuxt.options.pages(fa480e0a0) - ui-templates: Escape inline scripts correctly in ui templates (39c2b0a2c)
- nuxt: Add back fallback nuxtlink type signature (a8856de59)
- kit: Provide default extensions in
resolveModule(6fb5c9c15) - nuxt: Provide default extensions in
resolveTypePath(a0f9ddfe2) - nuxt: Strip query before generating payload url (34ddc2d2f)
- schema: Resolve workspaceDir to closest git config (7a2fbce01)
- kit: Include declaration files when resolving
compilerOptions.paths(835e89404) - nuxt: Consolidate head component context (#31209)
- nuxt: Resolve shared externals to absolute paths (#31227)
- nuxt: Skip deep merge in dev mode for prototype keys (#31205)
- schema: Use
RawVueCompilerOptionsfor unresolvedtsconfig(#31202) - nuxt: Ensure externals are resolved first (#31235)
- nuxt: Ensure we strip all chars in payload url (4f067f601)
- nuxt: Exempt nitro from import protections (#31246)
- nuxt: Normalise error url to pathname (87b69c9ae)
- nuxt: Ensure head components are reactive (#31248)
- nuxt: Preserve query/hash when calling
navigateTowith replace (#31244) - nuxt: Apply ignore rules to nitro
devStorage(#31233) - nuxt: Fall back to wasm if oxc native bindings are missing (#31190)
- nuxt: Pass
useFetchfunction name on server for warning (#31213) - vite: Prevent overriding server build chunks (89a29e760)
- nuxt: Strip query in
x-nitro-prerenderheader (2476cab9a)
💅 Refactors
- nuxt: Prefer logical assignment operators (#31004)
- nuxt: Use
isEqualfromohash/utils(2e27cd30c) - nuxt: Update to
noScriptsroute rule (#31083) - nuxt: Re-organize internal
runtime/nitrofiles (#31131) - nuxt: Explicitly type internal request fetch (54cb80319)
- nuxt: Use relative imports (1bce3dc3b)
- nuxt: Early return island response (#31094)
📖 Documentation
- Tiny typo (#30799)
- Fix typo (#30817)
- Remove backslashes in
spaLoadingTemplateexample (#30830) - Update path to nuxt binary (8992c4ea0)
- Add nuxt lifecycle (#30726)
- Add additional information about
NuxtPage(#30781) - Improve
navigateTodocs with clearer structure and examples (#30876) - Add auto import info about shared utils (#30858)
- Fix typo and improve data fetching examples (#30935)
- Clarify that local layers are scanned from
rootDir(27e356fe6) - Fix typo (#30963)
- Update links to unhead sources (6c520ef74)
- Fix typo (#30971)
- Add tips on how to override layers aliases (#30970)
- Add description for
vue:setupandapp:data:refreshhooks (#31001) - Mention requirement to wrap middleware in
defineNuxtRouteMiddleware(#31005) - Add
portoption to preview command (#30999) - Remove link to deleted nuxt 2 section (#31077)
- Link to the scripts releases page (#31095)
- Add
.nuxtrcdocumentation (#31093) - Fix typo in example command (#31112)
- Explain why headers not forwarded when using
$fetchon the server (#31114) - Fix links to nitro directory structure (5a696176d)
- Update to use
create nuxtcommand (fe82af4c9) - Update getCachedData types (#31208)
- Update code example for nightly release to default to
3x(a243f8fcf) - Clarify lifecycle behavior of
<NuxtPage>during page changes (#31116) - Mention workaround for
typedPagesin unhoisted pnpm setups (#31262)
📦 Build
- nuxt: Add subpath imports for type support (8ef3fcc4d)
🏡 Chore
- Remove second version of vitest (bc9ac7349)
- Bump bundle size (c5e191165)
- Add basic copilot instructions (d47b830d3)
- Handle undefined author (0161985c0)
- Use logical or assignment (#30992)
- Reorder options object (11e6b8398)
- Lint (86c960c6f)
- Fix broken lockfile (05501d2c8)
- Add
errxdependency (566418177) - Add additional dummy url to ignore (bc101e4ae)
- Ignore internal resolution errors in nuxt types (0d54dc3f4)
- Bump octokit patch versions (a477065b4)
- Bump
@nuxtjs/mdctypechecking dep (f23683b26) - Ignore
nitro/renderertemplates (b29c0e86b)
✅ Tests
- Add benchmarks for dev server initial build (#30742)
- Exclude urls from lychee crawler used in test suite (8e2d9a640)
- Prepare environment to ensure more reproducible dev tests (bc89ef867)
- Update unit test (5a71ef8ac)
- Add major version to unit test (676447239)
- Slightly improve coverage (d992c0da9)
- Bump timeout for route hmr (cbe38cf52)
- Update unit test snapshot for jsx (4910959b9)
- Disable codspeed outside of ci (71de708a0)
- Add some more stability in hmr tests (9a9fcdab5)
- Skip testing spa-preloader in dev (6cf97bfe5)
- Fix time-based hydration test (da3b39d67)
- Simplify further (ad306f472)
- Filter out dev server logs 🙈 (ee040eea3)
- Update unit test snapshot (97ec3143a)
- Provide nuxt extensions in unit test (358729e96)
- Add benchmark for vite client build (#31118)
- Update build benchmark (82ca08f93)
- Ensure dev tests have separate buildDirs (d7623f884)
- Update nitro type import (8f61d0090)
- Update import to
#internal/nitro/app(a1b855cc5) - Try to improve dev test stability (#31218)
- Migrate hmr test to use playwright runner (#31241)
❤️ Contributors
- Anoesj Sadraee (@Anoesj)
- Daniel Roe (@danielroe)
- John Tanzer (@moshetanzer)
- Connor Pearson (@cjpearson)
- Connor Roberts (@murshex)
- Harlan Wilton (@harlan-zw)
- Alex Liu (@Mini-ghost)
- Kevin Deng 三咲智子 (@sxzz)
- xjccc (@xjccc)
- Julien Huang (@huang-julien)
- Michael Brevard (@GalacticHypernova)
- Maik Kowol (@94726)
- Anthony Fu (@antfu)
- Bobbie Goede (@BobbieGoede)
- Clayton Chew (@claytonchew)
- awfulness (@awfulness)
- Sébastien Chopin (@atinux)
- Saeid Zareie (@Saeid-Za)
- Vahagn Zaqaryan (@Vahagn-Zaqaryan)
- Idorenyin Udoh (@idorenyinudoh)
- Jonas Thelemann (@dargmuesli)
- Ryota Watanabe (@wattanx)
- Horu (@HigherOrderLogic)
- Nolhan (@Nonolanlan1007)
- Typed SIGTERM (@typed-sigterm)
- Hans Tu (@ChiaHanTu)
- Damian Głowala (@DamianGlowala)
- David Marr (@marr)
- Camille Coutens (@Kamsou)
- Charlie ✨ (@CharleeWa)
- Hussain Panahy (@HP8585)
- @beer (@iiio2)