Changelog

Discover the latest releases from Nuxt and the official modules.
@nuxt/content

v3.8.2

fix: downgrade @sqlite.org/sqlite-wasm (5438131643)

@nuxt/content

v3.8.1

🔥 Performance

  • Use moduleDependencies to install mdc module (#3597)
  • Replace internal object records with maps (#3591)

🩹 Fixes

  • docs: Docs collection prefix (72cc17d5)
  • deps: Nuxt 4.2 patch (91a1de73)
  • Make sure last char of column is not special char (#3610)

📖 Documentation

  • studio: New module alpha release (#3601)
  • studio: Change installation to alpha version (#3602)
  • studio: Working with staging (2aa18b6b)
  • studio: Move back to main (87a2530e)
  • markdown: Add info to the complete MDC docs (#3605)
  • deps: Studio latest (c4a1d4e7)

❤️ Contributors

nuxt

v4.2.1

4.2.1 is the next patch release.

✅ Upgrading

Our recommendation for upgrading is to run:

npx nuxt upgrade --dedupe

This 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

compare changes

🩹 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 optimizeDeps config 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 pending as alias of status === 'pending' (#33221)
  • Note that cookieStore is true by 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

🤖 CI

❤️ 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)
nuxt

v3.20.1

3.20.1 is the next patch release.

✅ Upgrading

Our recommendation for upgrading is to run:

npx nuxt upgrade --dedupe --channel=v3

This 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

compare changes

🩹 Fixes

  • vite: Unset optimizeDeps.include for 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 optimizeDeps config 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 cookieStore is true by default (#33572)
  • Document pending as alias of status === 'pending' (#33221)
  • Clarify route middleware doesn't affect API routes (#33643)
  • Improve docs for useHead/useHydration/useLazy* (#33626)
  • Typo (#33655)

🏡 Chore

🤖 CI

❤️ 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)
@nuxt/fonts

v0.12.0

0.12.0 is the next major release.

👀 Highlights

There are a few breaking changes here, including major upgrades in unifont, fontaine + moving to a new fontless abstraction, setting default font weight, and more.

A visual check on upgrade is important - and let me know if you encounter any issues.

👉 Changelog

compare changes

🔥 Performance

  • Implement plugin hook filter (#683)
  • Use code filter when processCSSVariables is disabled (509adfd)
  • Initialise providers in parallel with nuxt setup (#688)

🩹 Fixes

  • deps: ⚠️ Upgrade unifont (f0584d0)
  • ⚠️ Set default font weight to 400 700 (#658)

💅 Refactors

  • Extract core utilities in preparation for fontless (#627)
  • Use new fontless package (#645)
  • Use extendViteConfig to set up devtools (05212ff)

📖 Documentation

  • Add callout for variable font weight (#635)
  • Add Installation section (#677)
  • Refactor using docus (#679)
  • Add warning note about font-family in template (78bbb42)
  • Upgrade to docus v5 (#697)

🏡 Chore

  • Prefer nuxt over nuxi (#643)
  • Update tailwind separately (4bbca61)
  • Pin @types/node (cbc4215)
  • Prefer nuxt to nuxi (68f0ea9)
  • Prefer nuxt over nuxi (dea205c)
  • deps-dev: Bump vite from 7.1.9 to 7.1.11 in the npm_and_yarn group across 1 directory (#710)

✅ Tests

  • Allow for global font to be inlined in v4+ (934c71c)
  • Inline global styles for test suite (56d8f51)
  • Add test for css variable processing (#719)

🤖 CI

  • Remove forced corepack installation (6b1c7bf)
  • Bump to lts node versions (5a43a2d)
  • Do not fail fast in matrix (ff92f48)
  • Run tests on node 20 (873beb4)
  • Use npm trusted publishing (db9e7d7)
  • Always publish via pkg-pr-new (6f07c42)
  • Add provenance action to check for downgrades in provenance (22dce94)

⚠️ Breaking Changes

  • deps: ⚠️ Upgrade unifont (f0584d0)
  • ⚠️ Set default font weight to 400 700 (#658)

❤️ Contributors

  • Daniel Roe (@danielroe)
  • Alexandru Teodor (@alexieremia)
  • dependabotbot (@dependabotbot)
  • Baptiste Leproux (@larbish)
  • Tom Tang (@qwerzl)
  • Chad Adams (@cadamsdev)
@nuxt/image

v2.0.0

We're excited to announce Nuxt Image v2! 🎉 This release focuses on TypeScript support, performance improvements, and better developer experience.

👀 Highlights

!NOTE Nuxt Image v2 requires Nuxt 3.1+. If you're on Nuxt 3.0.x, you'll need to upgrade to at least 3.1 first.

🎯 TypeScript support

The biggest change in v2 is full TypeScript support throughout the module (#1802).

Typed providers

Image providers now use defineProvider for type-safe configuration:

// Before (v1)
export const getImage = (src, { modifiers, baseURL }) => {
  // ...
  return { url }
}

// After (v2)
import { defineProvider } from '@nuxt/image/runtime'

export default defineProvider({
  getImage(src, { modifiers, baseURL }) {
    // Fully typed modifiers
    // ...
    return { url }
  }
})

Type-safe configuration

Module options are now fully typed. For example, providers that require a baseURL will enforce it at the type level in your nuxt.config.ts:

export default defineNuxtConfig({
  image: {
    provider: 'cloudinary',
    cloudinary: {
      baseURL: 'https://res.cloudinary.com/...' // TypeScript error if missing!
    }
  }
})

Typed composables

The $img helper and useImage() composable have full type inference (#1844):

const img = useImage()

// Full autocomplete for modifiers
const url = img('/image.jpg', { 
  width: 300,
  height: 200,
  fit: 'cover' // TypeScript knows the valid values!
})

🚀 IPX v3

We've upgraded to IPX v3 (#1799) for better performance and better sharp binary handling. The upgrade includes automatic detection of the correct sharp binaries for your deployment architecture.

🔌 Server-side utilities

You can now use image helpers directly in Nitro server endpoints (#1473).

// server/api/og-image.ts
export default defineEventHandler((event) => {
  const img = useImage()
  
  return {
    url: img('/hero.jpg', { 
      width: 1200, 
      height: 630,
      fit: 'cover' 
    })
  }
})

🎨 Component improvements

Template refs

<NuxtImg> now exposes the underlying <img> element via template refs:

<template>
  <NuxtImg ref="imgEl" src="/image.jpg" />
</template>

<script setup>
const imgEl = ref()

onMounted(() => {
  // Direct access to the native img element
  console.log(imgEl.value)
})
</script>

Typed slots

Both <NuxtImg> and <NuxtPicture> now have properly typed default slots.

🌐 New providers

We've added two new providers:

  • Shopify (#1890) - for Shopify store images
  • GitHub (#1990) - for GitHub avatars and user content
export default defineNuxtConfig({
  image: {
    provider: 'shopify',
    shopify: {
      baseURL: 'https://your-store.myshopify.com'
    }
  }
})

⚡ Performance

We've made several optimizations to reduce bundle size and improve runtime performance:

  • Better URL encoding (#1813) - Switched to URLSearchParams for more reliable parameter handling
  • Reduced runtime utilities (#1816) - Removed unused code and simplified implementations
  • Streamlined screen sizes (#1931) - Aligned default breakpoints with Tailwind CSS

🎯 Better layer support

Nuxt Image now properly supports custom image directories within Nuxt layers (#1880), making it easier to organize images in modular projects.

⚠️ Breaking changes

Provider API

The biggest breaking change is how providers are defined. All providers now use a default export with the defineProvider wrapper:

- export const getImage = (src, { modifiers }) => { ... }
+ export default defineProvider({
+   name: 'my-provider',
+   getImage(src, { modifiers }) { ... }
+ })

If you maintain a custom provider, you'll need to update it. But you get full TypeScript support in return!

Removed providers

The deprecated layer0 and edgio providers have been removed.

URL formatters

If you have custom providers using joinWith for parameter formatting, you'll need to update them to use the formatter function with createOperationsGenerator. See the migration guide for details.


#### Screen sizes

Default screen sizes now match Tailwind CSS. We've removed `xs` (320px) and `xxl` (2560px). See the [migration guide](https://image.nuxt.com/getting-started/migration#screen-size-changes) for how to add them back if needed.

Removed utilities

We've removed several unused runtime utilities. If you were importing internal utilities directly, check if they still exist.

✅ Upgrading

Check out our comprehensive migration guide for step-by-step upgrade instructions.

The quick version:

npm install @nuxt/image@latest

Most apps can upgrade with no code changes. If you have custom providers, you'll need to update them to use defineProvider - see the migration guide for examples.

🐛 Bug fixes

This release includes several fixes:

  • Preload links: Fixed preload for multiple densities with single size (#1851)
  • Crossorigin attributes: Correct crossorigin on preload links (#1836)
  • Provider-specific formats: AWS Amplify and Vercel providers now have proper format allow lists (#1996)
  • Hygraph: Prevented broken image URLs (#1999)
  • Preset sizes: Fixed preset size application when component sizes prop is undefined (#1919)
  • Cloudflare: Don't add baseURL if there are no operations (#1790)
  • IPX: Always use IPX provider if external baseURL is provided (#1800)

🙏 Thank you

Thank you to all the contributors who made this release possible! This includes contributions from dozens of community members who helped with features, bug fixes, documentation improvements, and feedback.

👉 Changelog

compare changes

🚀 Enhancements

  • Add support for image helpers in nitro endpoints (#1473)
  • deps: Upgrade to ipx v3 (#1799)
  • ipx: Log the architecture of the build (#1808)
  • ⚠️ Typed providers + modifiers (#1802)
  • Add type for default nuxt-picture slots (0e4f174)
  • nuxt-img: Add types for default slot (c4bba1b)
  • Add shopify provider (#1890)
  • Add support for image helpers in nitro endpoints (#1473)
  • ipx: Log the architecture of the build (#1808)
  • cloudimage: Make baseURL optional with cdn (#1951)
  • github: Add provider for github avatars (#1990)
  • nuxt-img: Expose element (#1834)
  • Support custom image dirs within layers (#1880)
  • Strongly type $Img/useImage methods (#1844)
  • Add type hints for provider option (64c76ee)

🔥 Performance

  • nuxt-img: Call decode before swapping from placeholder (#2008)

🩹 Fixes

  • Remove layer0 and edgio providers (#1763)
  • Add back layer0 and edgio providers (without) tests (fee826c)
  • cloudflare: Don't add baseURL if there are no operations (#1790)
  • ipx: Always use ipx provider if external baseURL is provided (#1800)
  • ipxStatic: Strip repeated slashes from image path (#1801)
  • edgio,layer0: ⚠️ Remove providers (#1809)
  • ⚠️ Use URLSearchParams as default formatter (#1813)
  • nuxt-picture: Export DefaultSlotProps (891d79a)
  • aliyun: Explicitly import useRuntimeConfig (268eb9c)
  • Remove layer0 and edgio providers (#1763)
  • Add back layer0 and edgio providers (without) tests (a99ce09)
  • cloudflare: Don't add baseURL if there are no operations (#1790)
  • ipx: Always use ipx provider if external baseURL is provided (#1800)
  • ipxStatic: Strip repeated slashes from image path (#1801)
  • Avoid deep type instantiation (12b37a2)
  • Add types to new node + shared contexts (#1907)
  • nuxt-img: Correct preload link for multiple densities + single size (#1851)
  • nuxt-img: Add appropriate crossorigin attribute to preload link (#1836)
  • awsAmplify,vercel: Set allow list of formats for providers (#1996)
  • hygraph: Prevent broken image urls (#1999)
  • nuxt-img: Apply preset sizes when component sizes prop is undefined (#1919)

💅 Refactors

  • ⚠️ Remove unused runtime utilities and simplify code (#1816)
  • ⚠️ Remove xs and xxl screen sizes (#1931)

📖 Documentation

  • Fix typo (#1762)
  • Fix link to runtime/providers (#1819)
  • Refactor to use docus v3 (#1868)
  • Put back social card (#1870)
  • Fix typo (#1762)
  • Fix link to runtime/providers (#1819)
  • Add back plausible for stats (42cbf6f)
  • deps: Upgrade to docus v4 (#1916)
  • Update README, add section for how to install (#1929)
  • Use nuxt rather than nuxi (809e726)
  • Fix getImage in the example of custom provider (#1949)
  • Fix components source file link (#1955)
  • Upgrade to docus v5 (#1975)
  • Add example for densities prop usage (#1937)
  • Adjust grammar and improve clarity in providers page (#1945)
  • Explain how to configure ipx at runtime (#1738)
  • Add none provider documentation (#2002)
  • Fix link to css file (f87793f)
  • Add baseURL to bunny example (3654b3e)

📦 Build

🏡 Chore

  • Disable shamefully-hoist (#1795)
  • Do not ignore typescript upgrades (9421fa5)
  • Switch to using typesVersions field (aa39ef4)
  • Allow major bumps in changelog (3989629)
  • Prefer nuxt over nuxi (#1857)
  • Test against node 20 (5507c0d)
  • Disable shamefully-hoist (#1795)
  • Do not ignore typescript upgrades (0809991)
  • Switch to using typesVersions field (b4af05a)
  • Allow major bumps in changelog (d486587)
  • Enable oxc-resolver build (4be31c7)
  • Release v1.11.0 (3123997)
  • config: Migrate renovate config (#1906)
  • Add plausible to knip (a988f40)
  • Add verifyDepsBeforeRun: install (#2000)
  • Remove .npmrc (578c04b)
  • Update redirected URL (#2006)

✅ Tests

  • Exclude layer0 + edgio from unit tests (ffe2177)
  • Add size snapshot (#1815)
  • Bump timeout (6fe8401)
  • Skip bundle size tests in ecosystem ci (301c504)
  • Explicitly import runtime utils (0c729e2)
  • Migrate to vitest projects (0fc2980)
  • Exclude layer0 + edgio from unit tests (3682a90)
  • Add 3x retries for e2e tests (cfdf83a)
  • Add snapshots for image/picture rendering without sizes (b4b8b0e)

🤖 CI

  • Add release workflow and add pkg.pr.new (#1791)
  • Set fetch-depth (ec565cd)
  • Remove forced corepack installation (86dc4a6)
  • Run tests against 1.x branch (0c83646)
  • Add release workflow and add pkg.pr.new (#1791)
  • Set fetch-depth (18ae6c7)
  • Test vs node 20 (e6babef)
  • Run tests on last node LTS (fa391c5)
  • Use npm trusted publishing (49ad2b7)
  • Add provenance action to check for downgrades in provenance (7edc44a)
  • Always release on pkg.pr.new (30eb4a3)
  • Use push of tag as release trigger (195cec0)

⚠️ Breaking Changes

  • ⚠️ Typed providers + modifiers (#1802)
  • edgio,layer0: ⚠️ Remove providers (#1809)
  • ⚠️ Use URLSearchParams as default formatter (#1813)
  • ⚠️ Remove unused runtime utilities and simplify code (#1816)
  • ⚠️ Remove xs and xxl screen sizes (#1931)

❤️ Contributors

  • Abeer0 (@iiio2)
  • Daniel Roe (@danielroe)
  • Tomer Danan (@Dananz)
  • Nathan Chase (@nathanchase)
  • Maxim Tyminko (@tyminko)
  • Damian Głowala (@DamianGlowala)
  • Sebastian Langer (@screeny05)
  • Haruaki OTAKE (@aaharu)
  • MHG (@Iran-110)
  • wuiyang (@wuiyang)
  • Sōta (@sotasan)
  • Leonardo Rick (@LeonardoRick)
  • Luke Nelson (@luc122c)
  • Mike Repeć (@Flexicon)
  • Amr Mohamed (@s8n11c)
  • Amir Afshar (@Afshar07)
  • Baptiste Leproux (@larbish)
  • Julien Huang (@huang-julien)
  • Chad Adams (@cadamsdev)
  • Paulo Queiroz (@raggesilver)
  • Sébastien Chopin (@atinux)
  • Matis (@matisbag)
  • Nicolas Großmann (@grossmann94)
  • Frederik Bußmann (@freb97)
@nuxt/content

v3.8.0

🎉 Highlights

• Schema extension: Allow extending inherited schemas with additional properties. • Faster hot reload: Use Vite dev server to handle Content Hot Reload.

🚀 Enhancements

  • Use Vite server for content hot reload (#3546)
  • Client utils (#3506)
  • Add support for nuxthub v1 (#3576)

🔥 Performance

  • git: Use modern-tar over tar (#3569)

🩹 Fixes

  • Stops props.data rerendering ContentRenderer (#3544)
  • Extend inherited schema (dd054ea9)

📖 Documentation

🏡 Chore

  • Remove ui pro occurences (#3557)
  • Upgrade deps (77ccf914)
  • Cleanup deprecated z re-export and editor usage (#3561)
  • Upgrade deps (19e52328)

✅ Tests

❤️ Contributors

nuxt

v3.20.0

3.20.0 is the next minor release.

✅ Upgrading

Our recommendation for upgrading is to run:

npx nuxt upgrade --dedupe --channel=v3

This 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

compare changes

🚀 Enhancements

  • nuxt: Allow specifying component declarationPath (#33419)
  • kit: Add extensions option for resolveModule (#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 setGlobalHead utility (#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 loadNuxtConfig in concurrent calls (#33420)
  • nuxt: Allow object-format href in <NuxtLink> (b97ae2f70)
  • nuxt: Remove mergeModels from auto imports (#33344)
  • nuxt: Add back shortPath property (#33384)
  • nuxt: Do not allow native attrs to shadow nuxt link props (0981990a7)
  • nuxt: Remove declarationPath from component dirs (e384ba3cb)
  • nuxt: Preserve root route in isPrerendered check (#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 NuxtTime relative time numeric prop (#33552)
  • nuxt: Add NuxtTime relative time relativeStyle prop (#33557)
  • nuxt: Handle arrays in app config correctly during HMR (#33555)

💅 Refactors

  • Remove obsolete shortPath property (#33384)
  • kit: Extract trace utilities (ddaedfa51)
  • nuxt,vite,webpack: Allow builders to augment types (#33427)
  • schema: Deprecate extend, extendConfig, and configResolved hooks (932a80dc6)
  • nitro,nuxt: Extract @nuxt/nitro-server package (#33462)
  • nuxt: Use RouteLocationNormalizedLoadedGeneric internally (aa211fb4f)
  • vite: Make vite plugins environment-compatible (#33445)

📖 Documentation

  • Add nuxt module addServerPlugin note (#33409)
  • Remove deprecated node version (#33411)
  • Update declarationPath in addComponent (#33380)
  • Add some notes/deprecations for vite hooks (2c6912d2f)
  • Fix incorrect ESM module field info (#33451)
  • Recommend getLayerDirectories() instead of nuxt.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-demi from ignoredBuiltDependencies (#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-server on 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

v4.2.0

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 AbortController signals directly within useAsyncData, giving you fine-grained control over request cancellation (#32531).

This works by passing an internal signal to your useAsyncData handler to 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 AbortController signal directly to refresh/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.

nuxt.config.ts
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 compatibilityVersion to 5:

nuxt.config.ts
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-server Package

We'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 useAsyncData and useLazyAsyncData are 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.

pages/blog/[slug].vue
<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:

nuxt.config.ts
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/nuxt module.

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/unimport plugin for better navigation with auto-imported composables and utilities

!NOTE Read more in the documentation.

To enable this feature, set experimental.typescriptPlugin to true in your Nuxt configuration:

nuxt.config.ts
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 resolveModule now accepts an extensions option (#33328)
  • Global head utility – New setGlobalHead utility in kit for easier head management (#33512)

🩹 Important Fixes

  • Route hash is now preserved when redirecting based on routeRules (#33222)
  • Fixed concurrent calls to loadNuxtConfig with proper cleanup (#33420)
  • Object-format href now 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 --dedupe

This will refresh your lockfile and pull in all the latest dependencies that Nuxt relies on, especially from the unjs ecosystem.

👉 Changelog

compare changes

🚀 Enhancements

  • nuxt: Allow specifying component declarationPath (#33419)
  • kit: Add extensions option for resolveModule (#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.compatibilityVersion to 5 (22f4693a1)
  • kit,vite: Allow enabling vite environment api (#33492)
  • kit: Add setGlobalHead utility (#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 loadNuxtConfig in concurrent calls (#33420)
  • nuxt: Allow object-format href in <NuxtLink> (c69e4c30d)
  • nuxt: Remove mergeModels from auto imports (#33344)
  • nuxt: Add back shortPath property (#33384)
  • nuxt: Do not allow native attrs to shadow nuxt link props (4751a6aca)
  • nuxt: Remove declarationPath from component dirs (191bcb7e9)
  • nuxt: Preserve root route in isPrerendered check (#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 NuxtTime relative time numeric prop (#33552)
  • nuxt: Add NuxtTime relative time relativeStyle prop (#33557)
  • nuxt: Handle arrays in app config correctly during HMR (#33555)
  • vite: Unset optimizeDeps.include for server environment (#33550)

💅 Refactors

  • Remove obsolete shortPath property (#33384)
  • kit: Extract trace utilities (9687505ac)
  • nuxt,vite,webpack: Allow builders to augment types (#33427)
  • schema: Deprecate extend, extendConfig, and configResolved hooks (e060b9695)
  • vite: Make vite plugins environment-compatible (#33445)
  • nitro,nuxt: Extract @nuxt/nitro-server package (#33462)
  • nuxt: Use RouteLocationNormalizedLoadedGeneric internally (b51cb3067)

📖 Documentation

  • Update link to localisation issue (d32859da2)
  • Add nuxt module addServerPlugin note (#33409)
  • Remove deprecated node version (#33411)
  • Update declarationPath in addComponent (#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 of nuxt.options._layers (#33484)
  • Add 4.x prefix (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-demi from ignoredBuiltDependencies (#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 since in nightly releases (74ca73ca1)
  • Ignore @rollup/plugin-commonjs (cd12980ce)

✅ Tests

  • Refactor suite to use common matrix utils (#33483)

🤖 CI

  • Publish @nuxt/nitro-server on 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)
@nuxt/test-utils

v3.20.0

3.20.0 is the next minor release.

👉 Changelog

compare changes

🚀 Enhancements

  • runtime-utils: Automatic ref unwrapping for wrapper.vm (#1405)
  • runtime: Allow registerEndpoint to work with native fetch (#1415)
  • runtime: Add scoped option to cleanup components (#1389)

🩹 Fixes

  • runtime-utils: Capture events emitted before the first render (#1353)
  • runtime-utils: Add missing import (#1372)
  • e2e: Detect nuxt config files in .config folder (#1381)
  • e2e: Bump windows teardown timeout to 60s (9f1f712da)
  • runtime: Allow registerEndpoint to work with $fetch.create (#1403)
  • Handle optional chaining for imports in setupImportMocking function (#1433)
  • vitest: Support virtualConsole.forwardTo in jsdom (6b4076a04)
  • vitest: Call window.close on jsdom teardown (25b87eef3)
  • vitest: Stub IntersectionObserver in teardown (230dd240a)

📖 Documentation

  • Use jsdoc standard @default formatting (#1379)
  • Fix typo in setup hook deprecation text (#1380)

🏡 Chore

  • Switch to npm trusted publishing (3a1f194fb)
  • deps-dev: Bump happy-dom from 19.0.2 to 20.0.0 (#1441)
  • Relax upper peerDependency ranges (4676f4bf3)
  • Add test script (3126fa243)

✅ Tests

  • Add example tests for nuxt ui (#1396)

🤖 CI

  • Do not fail matrix if one os fails (7d2969e29)
  • Add read contents permission (782119685)
  • Run release tasks on latest node version (fb2007b33)
  • Add provenance action to check for downgrades in provenance (10288633c)

❤️ Contributors

  • Daniel Roe (@danielroe)
  • Mike Laumann Bellika (@MikeBellika)
  • yamachi4416 (@yamachi4416)
  • Vasily Kuzin (@ExEr7um)
  • dependabotbot (@dependabotbot)
  • Toshiki Yoshioka (@ytoshiki)
  • Jess (@JessicaSachs)
  • Yizack Rangel (@Yizack)
  • Ingo Renner (@irnnr)
  • Tomina (@Thomaash)
@nuxt/ui

v4.1.0

✨ Highlights

📦 New Empty Component

A new Empty component is now available to display empty states when there's no content to show (#5200).

⚡️ Component Virtualization

Use the virtualize prop to enable virtualization for large datasets on CommandPalette, InputMenu, SelectMenu, Table and Tree components (#5162).

<template>
  <UTable :data="data" :columns="columns" virtualize />
</template>

🎯 Experimental Component Detection

Enable the new experimental.componentDetection option in your nuxt.config.ts to automatically detect which components are actually used and only generate the necessary CSS for those components including their dependencies (#5222).

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  css: ['~/assets/css/main.css'],
  ui: {
    experimental: {
      componentDetection: true
    }
  }
})

🚨 Breaking Changes

We apologize for these small breaking changes. With 110+ components in the library, we occasionally need to make corrections to maintain consistency and quality. We aim to minimize breaking changes, but sometimes they're necessary to improve the developer experience in the long run.

  • CommandPalette: add children-icon prop to use trailing-icon in input (#4397) (edda8a6)

The trailing-icon prop is now used for the Input, and a new children-icon prop has been added to customize the icon for child items:

<template>
- <UCommandPalette :trailing-icon="i-lucide-arrow-right" />
+ <UCommandPalette :children-icon="i-lucide-arrow-right" />
</template>
  • Table: consistent args order in select event (9526a1b)

The @select event now passes arguments in a consistent order: (event, row) instead of (row, event):

<template>
- <UTable @select="(row, e) => {}" />
+ <UTable @select="(e, row) => {}" />
</template>

🚀 Features

🐛 Bug Fixes

  • BlogPost/ChangelogVersion: allow any attrs inimage prop (9632f99), closes #5276
  • Breadcrumb: handle active in items (cc8cbf3), closes #4771
  • ChatMessage: ensure left side takes full width (af8c023)
  • ChatMessage: only apply max-width on right side (a85b0e1)
  • ChatMessage: reset top and bottom margin (8f9176c)
  • ChatMessages: allow user scroll with should-auto-scroll (#5252) (db73765)
  • ChatMessages: define user & assistant ui prop type (#5234) (240bc1a)
  • CodeTree/Tree: restore item wrapper with presentation role (70aaf4a), closes #4945
  • components: add missing ui prop in prose proxy components (#5205) (d1afe90)
  • ContextMenu/DropdownMenu: allow item content class override (ab5032d), closes #5277
  • Drawer/Modal/Slideover: remove close autofocus prevent (#5191) (8099440)
  • Error/Main: render as div instead of main (2a09ac0), closes #4955
  • FileUpload: handle disabling file delete button (08c30cf), closes #5249
  • FileUpload: stuck focus while tabbing (#5128) (2477d44)
  • FileUpload: use native img element for blob URLs preview (69906bc), closes #5121 #4824
  • InputMenu/SelectMenu: enrich reusable template item prop (63074d6)
  • InputMenu: ensure tag can be removed when number (028538a)
  • Kbd: return original value and use uppercase class (#5238) (4095c9a)
  • NavigationMenu: display trailing slot when badge not undefined (f24204f), closes #4670
  • Table: consistent args order in select event (9526a1b)
  • Table: expose $el instead of rootRef (c019f8f), closes #5230 #5162

🌐 Locales

👋 New Contributors

Full Changelog: https://github.com/nuxt/ui/compare/v4.0.1...v4.1.0