This section documents version-specific API changes in Nuxt v4, prioritizing recent minor releases and breaking changes.
-
NEW: createUseFetch() factory — create custom useFetch instances with default options and custom merge logic source
-
NEW: createUseAsyncData() factory — create custom useAsyncData instances with preconfigured defaults source
-
NEW: useAnnouncer() composable — announce dynamic in-page changes to screen readers via polite() and assertive() methods; use with <NuxtAnnouncer> component source
-
NEW: <NuxtAnnouncer> component — render live region for dynamic announcements alongside <NuxtRouteAnnouncer> source
-
BREAKING: useState reset behavior — clearNuxtState() now resets to initial value instead of undefined source
-
BREAKING: clearNuxtState reset behavior — resets state to default value, aligning with useAsyncData source
-
NEW: useCookie refresh option — extend cookie expiration without changing value via refresh: true source
-
BREAKING: Vue Router v5 — upgraded from v4; removes dependency on unplugin-vue-router source
-
NEW: definePageMeta layout object — pass { name, props } to set typed layout props per-page source
-
NEW: normalizeComponentNames experimental option — normalise page component names to match route names source
-
NEW: View Transitions Types support — define view transition types for different navigation patterns source
-
NEW: payloadExtraction: 'client' mode — inline full payload in HTML response while generating _payload.json for client navigation source
-
NEW: routeRules appLayout property — set layout centrally via route rules without scattering definePageMeta calls source
-
NEW: useRoute().meta.groups — route groups (parentheses-wrapped folders) now exposed in route meta source
-
NEW: setPageLayout() with props — second parameter to pass typed props to layout source
-
NEW: #server alias — clean imports from server directory (import { helper } from '#server/utils/helper') with import protection source
-
NEW: ISR/SWR payload extraction — routeRules isr, swr, and cache now generate _payload.json for cached pages source
-
NEW: Dev mode payload extraction — payload extraction now works in dev mode with nitro.static: true or per-route rule source
-
NEW: Module disabling — disable layer modules by passing false to options (image: false) source
-
DEPRECATED: statusCode → status, statusMessage → statusText — prepare for Nitro v3 and H3 v2 Web API naming source
-
NEW: useAsyncData AbortController signal — pass { signal } from handler or to refresh()/execute() for fine-grained request cancellation source
-
NEW: Better error pages in dev — technical error overlay appears alongside custom error page source
-
NEW: Vite Environment API (experimental) — opt in via experimental.viteEnvironmentApi: true for Vite 6 multi-environment support source
-
NEW: extractAsyncDataHandlers (experimental) — extract async data handler functions into separate chunks for smaller client bundles on static sites source
-
NEW: component.declarationPath — specify custom declaration path for components source
-
NEW: setGlobalHead() utility — new kit utility for easier global head management source
-
NEW: resolveModule extensions option — resolve modules with custom file extensions source
-
NEW: moduleDependencies — specify module dependencies with version constraints and configuration merging source
-
NEW: onInstall hook — module lifecycle hook called on first installation source
-
NEW: onUpgrade hook — module lifecycle hook called when upgraded to new version source
-
NEW: resolveFiles ignore option — exclude specific files via glob patterns source
-
NEW: getLayerDirectories() utility — clean interface for accessing layer directories without private API access source
-
NEW: addServerImports single import — support single import object alongside array format source
-
NEW: entryImportMap (experimental) — use import maps for stable chunk hashing; auto-enabled, can be disabled source
-
NEW: Rolldown support (experimental) — Rust-powered bundling available via rolldown-vite override source
-
NEW: defineLazyHydrationComponent() without auto-imports — lazy hydration macros work with components: false source
-
NEW: NuxtPage rules property — route rules now exposed on dedicated property source
-
Avoid browser-only APIs during SSR by using SSR-friendly composables — direct access to localStorage or window in the setup phase causes hydration mismatches. Use useCookie, useState, or wrap browser code in onMounted or <ClientOnly> source
-
Lazy-load components with the Lazy prefix to reduce initial bundle size — import as <LazyComponentName> to dynamically load component code only when needed, useful for components not required on first render source
-
Use hydrate-on-visible attribute on components to defer hydration until viewport visibility — delays JavaScript initialisation for components below the fold, improving time-to-interactive for the critical path source
-
Set parallel: true for asynchronous plugins to enable concurrent loading — by default, plugins load sequentially blocking the hydration phase; concurrent loading improves performance when you have multiple independent async plugins source
-
Use lifecycle hooks (onInstall, onUpgrade) for one-time module setup tasks — defer expensive operations like database schema generation or config file creation from the module's setup function to avoid running them on every build source
-
Minimise payload size with the pick option on data fetching — only extract fields you actually use in your template to reduce the amount of data serialized from server to client during hydration source
-
Always create explicit keys with useAsyncData to avoid unreliable auto-generated ones — auto-generated keys based on file and line number can cause data misses when using the composable inside custom wrappers or loops; provide a unique string key instead source
-
Use $fetch for client-only interactions and useFetch for SSR-safe initial data — $fetch makes direct network calls suitable for event handlers; useFetch prevents double-fetching by forwarding server data to the client in the payload source
-
Wrap shared state in composables using useState instead of top-level refs — exporting const state = ref() directly causes state to leak across requests on the server; always wrap in a composable like export const useState = () => useState('key') source
-
Use useSeoMeta for type-safe SEO meta tags instead of useHead — provides full IDE autocomplete and typo prevention for common SEO properties like ogTitle, twitterCard, and description source
-
Avoid expensive plugin computations during hydration — large plugin setup blocks rendering and degrades UX; inspect and migrate plugin logic to composables or utilities whenever possible source
-
Prefix module exports (components, composables, server routes) with your module name — prevents naming conflicts with other modules, Nuxt internals, or user code; use /api/_moduleName/ for routes and <ModuleNameButton> for components source
-
Use computed or ref-based keys with useAsyncData for reactive data fetching — when combined with reactive dependencies, the data refetches automatically and old cached data is cleaned up if no other components reference it source
-
Favour composables over plugins for shared logic — plugins run globally during hydration and reduce performance; most utilities and helper functions can be used directly as composables without the overhead source