Nuxt docs, chapter by chapter

Going further

The Going Further chapters — Experimental Features and their flags, Features and the future namespace, How Nuxt Works, Runtime Config, the Nightly Release Channel, Lifecycle Hooks, Layers, NuxtApp, Debugging, Custom Events, Server Imports, Kit and Builders.

Going Further is the part of the guide that senior interviews draw from when they want to know whether you have configured Nuxt beyond the defaults: which experimental flags exist, what future.compatibilityVersion does, what is on the NuxtApp object, how to attach a debugger.

Know — Experimental Features

  • All under experimental in nuxt.config. Notable flags: asyncContext (AsyncLocalStorage-backed Nuxt context, survives await), asyncEntry, externalVue, emitRouteChunkError ('automatic' default), restoreState (with reloadNuxtApp), inlineRouteRules (enables defineRouteRules), renderJsonPayloads, noVueServer, payloadExtraction, clientFallback (<NuxtClientFallback>), crossOriginPrefetch (Speculation Rules), viewTransition, writeEarlyHints, componentIslands, localLayerAliases, typedPages, watcher (chokidar | parcel | chokidar-granular), sharedPrerenderData, clientNodeCompat, scanPageMeta, cookieStore, buildCache, checkOutdatedBuildInterval, navigationRepaint, normalizeComponentNames, spaLoadingTemplateLocation, browserDevtoolsTiming, debugModuleMutation, lazyHydration, templateImportResolution, decorators, purgeCachedData, granularCachedData, pendingWhenIdle, entryImportMap, typescriptPlugin, viteEnvironmentApi, ssrStreaming, headNext, routeTypedFetch, strictRouteTypes, alwaysRunFetchOnKeyChange, appManifest, extractAsyncDataHandlers, enforceModuleCompatibility, parseErrorData, early404, prefetchPreloadTags, stripNeverHydratedData, templateRouteInjection, and defaults (per-component defaults such as NuxtLink prefetch behaviour). Several are "enabled when compatibilityVersion: 5" and form the practical Nuxt 5 checklist.

Know — Features and future

  • features.devLogs streams server logs to the browser console in development (true | 'silent'); features.inlineStyles inlines component CSS into the HTML (boolean or a function per component id); features.noScripts renders a page with no client JavaScript (also per route via routeRules).
  • future.compatibilityVersion opts into the next major's behaviour (5 today); future.multiApp prepares multiple Nuxt apps on one page; future.typescriptBundlerResolution uses moduleResolution: 'bundler'.

Know — How Nuxt Works, NuxtApp, Runtime Config

  • Build context: the Nuxt interface (nuxt.options, nuxt.hooks, nuxt.hook, nuxt.callHook) available to modules. Runtime context: the NuxtApp interface with vueApp, versions, hook/callHook/hooks, payload (serverRendered, data, state, error, path), isHydrating, ssrContext (server; event, url, payload), runWithContext, provide, and injected $helpers. Access it with useNuxtApp() (throws outside the context) or tryUseNuxtApp(); the Nuxt context is the set of places where composables work (setup, plugins, middleware, and anything wrapped in runWithContext).
  • Runtime Config: define under runtimeConfig, expose the public half, override with NUXT_ environment variables at runtime (the environment is read when the server starts), read with useRuntimeConfig(); type it by augmenting RuntimeConfig and PublicRuntimeConfig in nuxt/schema.

Know — Nightly, Hooks, Events, Debugging

  • Nightly release channel: npx nuxt upgrade --channel nightly (or the nuxt-nightly package); opt out with --channel stable; @nuxt/cli has a nightly too.
  • Lifecycle hooks in three families: app hooks (runtime, both sides: app:created, app:mounted, page:start, page:finish, vue:error, link:prefetch, …), Nuxt hooks (build time, in modules: ready, modules:done, pages:extend, components:extend, build:before, nitro:config, prerender:routes, …), Nitro app hooks (server runtime: request, beforeResponse, afterResponse, render:html, render:response, error, close). useRuntimeHook registers an app hook scoped to a component.
  • Custom events: declare your own hooks by augmenting RuntimeNuxtHooks (app) or NuxtHooks (build) and call them with callHook.
  • Debugging: sourcemap: { server: true, client: true }; Node inspector with nuxt dev --inspect; IDE debug configurations for VS Code ("command": "npm run dev" with serverReadyAction) and JetBrains.

Know — Server Imports, Kit, Builders

  • nuxt/server (arriving in 4.6): a runtime-agnostic import surface for server code (defineEventHandler, getQuery, …) that works under Nitro 2, Nitro 3 and future server builders, so one file runs across majors.
  • Kit (@nuxt/kit): the module author's API (defineNuxtModule, addPlugin, addComponentsDir, addImports, addServerHandler, addTemplate, extendPages, installModule/moduleDependencies, useLogger, …), covered in Module authoring.
  • Builders: Nuxt separates what to build from how; official builders are Vite (default), webpack and Rspack, selected with builder; the deployable server comes from Nitro through @nuxt/nitro-server. A custom builder implements NuxtBuilder with a bundle(nuxt) method.

How it works

nuxt.config.ts
export default defineNuxtConfig({
  future: { compatibilityVersion: 5 }, // try tomorrow's defaults today
  features: { devLogs: true, inlineStyles: false },
  experimental: {
    asyncContext: true,
    typedPages: true,
    viewTransition: true,
    defaults: { nuxtLink: { prefetchOn: { visibility: false, interaction: true } } },
  },
  sourcemap: { server: true, client: false },
  runtimeConfig: { apiSecret: '', public: { apiBase: '/api' } },
})
types/runtime-config.d.ts
declare module 'nuxt/schema' {
  interface RuntimeConfig { apiSecret: string }
  interface PublicRuntimeConfig { apiBase: string }
}
export {}
app/plugins/telemetry.ts
declare module '#app' {
  interface RuntimeNuxtHooks {
    'telemetry:event': (name: string, data?: Record<string, unknown>) => void
  }
}

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('telemetry:event', (name, data) => console.info('[telemetry]', name, data))
  nuxtApp.hook('page:finish', () => nuxtApp.callHook('telemetry:event', 'pageview', { path: nuxtApp.$router.currentRoute.value.fullPath }))
})
Gotcha· Experimental means it can change in a minor

The docs say so explicitly: experimental options may change or disappear between minor releases. Enable them for a measured reason, write it in the config comment, and re-read the experimental features page when upgrading; the compatibilityVersion: 5 group is the one that will flip by default.

Verify before the interview:

The current flag list and which entries are marked "enabled when compatibilityVersion: 5"; also whether nuxt/server has shipped in a 4.6 release yet.

docs ↗

Exercise

Exercise
  • Set future.compatibilityVersion: 5 on a playground and list every warning and breakage.
  • Add a custom runtime hook with type augmentation, call it from a page and confirm the typed callback.
  • Attach the VS Code debugger with nuxt dev --inspect, set a breakpoint in a server route and in a page's setup, and hit both.

Be able to say

Be able to say· What is on the NuxtApp object and when do you use it?

"useNuxtApp() returns the per-request runtime context: the vueApp, the hook system with hook and callHook, the payload with data, state, serverRendered and error, isHydrating, the ssrContext on the server with the request event, runWithContext for calling composables outside setup, provide and the injected $helpers from plugins. I reach for it in plugins to register hooks and helpers, in error reporting to read payload.error, and when I need runWithContext to call a composable from a callback that has lost the Nuxt context; tryUseNuxtApp() is the safe variant when the context might be missing."

Your notes

Open in Notes

Nothing yet. Notes filed here show up on this page and the section overview.