CommonJS default export interop
A CommonJS module using `module.exports = { test: 123 }` or `exports.test = 123` provides a default export. When required in CJS it works as-is. In ESM contexts with interop support, `import pkg from 'cjs-pkg'` works, but there is always a chance interop fails and returns `{ default: { test: 123 } }`. Dynamic imports always return this shape: `import('cjs-pkg').then(console.log)` returns `[Module: null prototype] { default: { test: '123' } }`.
Alias libraries to CJS version in Nuxt config
In some cases, manually alias a library to its CJS version in Nuxt config: `export default defineNuxtConfig({ alias: { 'sample-library': 'sample-library/dist/sample-library.cjs.js' } })`.
Transpile libraries in Nuxt config for ESM issues
To handle libraries with ESM compatibility issues, add them to `build.transpile` in the Nuxt config. Example: `export default defineNuxtConfig({ build: { transpile: ['sample-library'] } })`. You may need to also add other packages imported by these libraries.
Manually interop default export from CJS in ESM
To manually handle default export interop from CJS in ESM: use `import { default as pkg } from 'cjs-pkg'` for static imports, or `import('cjs-pkg').then(m => m.default || m).then(console.log)` for dynamic imports.
ESLint legacy config migration recommended
If you are using the legacy .eslintrc config format, you need to configure manually with @nuxt/eslint-config. Nuxt recommends migrating to the flat config format to be future-proof, as the flat config is now the standard since ESLint v9.
@nuxt/eslint module setup
Nuxt supports ESLint out of the box through the @nuxt/eslint module, which provides project-aware ESLint configuration. The module uses the new ESLint flat config format, which is the default since ESLint v9. To set up the module, run 'npx nuxt module add eslint' and a eslint.config.mjs file will be generated in the project root that can be customized as needed.
Dev Containers CLI commands
Install the CLI with npm install -g @devcontainers/cli. Use devcontainer up --workspace-folder . to build and open the project in a container. Use devcontainer build to rebuild the container after making changes to .devcontainer configuration.
Dev container port forwarding configuration
Port 3000 should be forwarded for the Nuxt dev server. In devcontainer.json, set forwardPorts to [3000] and configure portsAttributes with label "Application" and onAutoForward set to "openPreview" to automatically open a preview when the port becomes available.
Persist node_modules in dev container
Add a mount in devcontainer.json with type=volume targeting ${containerWorkspaceFolder}/node_modules to persist dependencies in a Docker volume. This prevents node_modules from being reinstalled every time the container restarts.
Open existing dev container in VS Code
When opening a project with dev container configuration in VS Code, a notification appears in the bottom right corner with "Reopen in Dev Containers". Click it to build and open the project in the dev container. Alternatively, use the Command Palette (Cmd+Shift+P on Mac, Ctrl+Shift+P on Windows/Linux), search for "Dev Containers: Reopen in Container", and select it.
Dockerfile for Nuxt dev container
Use FROM node:lts as the base image. Set WORKDIR to /app. Run npm i -g corepack && corepack enable to enable pnpm. Copy package.json, pnpm-lock.yaml, and pnpm-workspace.yaml from the project. Run pnpm install --frozen-lockfile. Finally, copy the entire project directory.
devcontainer.json configuration for Nuxt
The devcontainer.json file should contain: name ("nuxt-devcontainer"), build configuration pointing to the Dockerfile, forwardPorts set to [3000] to expose the dev server port, portsAttributes defining port 3000 as "Application" with onAutoForward set to "openPreview", mounts volume for node_modules at ${containerWorkspaceFolder}/node_modules, and postStartCommand set to "pnpm install && pnpm dev:prepare".
Dev container configuration file structure
Create a .devcontainer/ folder in the project root containing two files: devcontainer.json and Dockerfile. The devcontainer.json configures the dev container settings and the Dockerfile defines the container image.
@nuxt/a11y module for development
The @nuxt/a11y module surfaces accessibility problems in your components while you develop. It is in alpha, so expect its API to change.
Move focus to main region after navigation
In a client plugin (app/plugins/focus-main.client.ts), use router.afterEach() to move focus to the main region after every navigation by calling document.getElementById('main')?.focus() inside nextTick().
Configure scrollBehaviorType for custom scroll behavior
To configure custom scroll behavior such as smooth scrolling or a different offset, set scrollBehaviorType or write your own scrollBehavior function in router.options.ts.
Nuxt scroll behavior for accessibility
Nuxt scrolls to the top on a new route, restores the previous position when going back, and scrolls to hash targets. Smooth scrolling should respect the user's prefers-reduced-motion setting.
Test keyboard navigation
Navigate around your app with the keyboard alone. Tabbing from the skip link into the main region after a couple of navigations will surface most focus problems quickly.
aria-current attribute on NuxtLink
In menus and breadcrumbs, <NuxtLink> automatically exposes aria-current="page" on the link matching the current route. Use the ariaCurrentValue prop to set a different value when a different token describes the relationship better, such as aria-current-value="step" for a step in a multi-page form.
Implement skip link for focus management
Add a skip link as the first tab stop of your app by placing an <a href="#main">Skip to main content</a> element before the header, and set a <main id="main" tabindex="-1"> element to receive focus. Use tabindex="-1" rather than a positive value to avoid moving the element into the tab order.
Focus management after client-side navigation
After a client-side navigation, focus stays where it was (usually on the link that was activated). Vue Router and Nuxt do not move focus, which can cause keyboard users to tab through the whole header again to reach changed content.
Mark external links in NuxtLink
Links to files in the public/ directory or to another app on the same origin are not routes that Vue Router knows about. Mark them with the external prop so the browser performs a real navigation instead of failing to match a route.
Use NuxtLink for in-app navigation
Use the <NuxtLink> component for in-app navigation instead of divs with click handlers. It renders a real <a href> element, which is focusable, appears in the tab order, and works with middle-click and 'open in new tab'.
Set distinct titles for every route
Give every route a distinct title as the single most valuable accessibility practice. Set a global title template in app.vue using useHead() with titleTemplate, and let each page fill in its own part using useHead() with title.
Page titles and route announcements effectiveness
The route announcer reads the page title rendered by Unhead, so it is only as useful as your titles are. If two routes share the same title, screen reader users hear nothing when navigating between them.
useRouteAnnouncer composable for custom announcements
Use the useRouteAnnouncer composable to announce something other than the page title or to change how urgently it is announced. It provides a set() method to announce custom text.
Route announcements with NuxtRouteAnnouncer
Use the <NuxtRouteAnnouncer> component to announce client-side navigation to screen readers. It renders a hidden live region and writes the new page title into it after every navigation. Place it in app.vue alongside <NuxtPage>.
Nuxt MCP server changelog tool
The Nuxt MCP server provides a get_changelog tool that retrieves the latest releases from Nuxt core and official modules.
Nuxt MCP server blog tools
The Nuxt MCP server provides the following blog tools: list_blog_posts (lists all Nuxt blog posts with metadata including dates, categories, and tags) and get_blog_post (retrieves blog post content and details by path).
Nuxt MCP server URL
The Nuxt MCP server URL is https://nuxt.com/mcp and uses HTTP transport.
Nuxt MCP server prompts available
The Nuxt MCP server provides guided prompts for common workflows: find_documentation_for_topic (find the best Nuxt documentation for a specific topic or feature), deployment_guide (get deployment instructions for a specific hosting provider), and migration_help (get help with migrating between Nuxt versions). These are accessible with tools like Claude Code by using the forward slash (/).
Nuxt MCP server modules tools
The Nuxt MCP server provides the following modules tools: list_modules (lists all available Nuxt modules with optional filtering and sorting by downloads, stars, or date) and get_module (retrieves complete details about a specific module including README, compatibility, maintainers, and stats).
Nuxt MCP server deployment tools
The Nuxt MCP server provides the following deployment tools: list_deploy_providers (lists all deployment providers and hosting platforms for Nuxt applications) and get_deploy_provider (retrieves deployment provider details and instructions by path).
Nuxt MCP server documentation tools
The Nuxt MCP server provides the following documentation tools: list_documentation_pages (lists all available Nuxt documentation pages with their categories and basic information, supports version filtering for 3.x, 4.x, 5.x, or all), get_documentation_page (retrieves documentation page content and details by path), and get_getting_started_guide (gets the getting started guide for a specific Nuxt version).
Nuxt MCP server resources available
The Nuxt MCP server provides three resources for discovery: resource://nuxt-com/documentation-pages (browse all available documentation pages, defaults to v4.x), resource://nuxt-com/blog-posts (browse all Nuxt blog posts including releases and tutorials), and resource://nuxt-com/deploy-providers (browse all deployment providers and hosting platforms).
What is MCP (Model Context Protocol)
MCP (Model Context Protocol) is a standardized protocol that enables AI assistants to access external data sources and tools. Nuxt provides an MCP server that allows AI assistants like Claude Code, Cursor, and Windsurf to access documentation, blog posts, and deployment guides directly. The MCP server provides structured access to Nuxt documentation, making it easy for AI tools to understand and assist with Nuxt development.
Using LLMs.txt with ChatGPT, Claude, and other AI tools
Any AI tool that supports LLMs.txt can use Nuxt routes to better understand the framework. Include the documentation source in your prompt, such as 'Using Nuxt documentation from https://nuxt.com/llms.txt' or 'Follow complete Nuxt guidelines from https://nuxt.com/llms-full.txt'.
Using LLMs.txt with Cursor
To use Nuxt LLMs.txt with Cursor, mention the LLMs.txt URLs directly when asking questions or add these specific URLs to your project context using @docs. Refer to the Cursor Web and Docs Search documentation for more details.
@ symbol must be typed manually in Cursor and Windsurf
When using tools like Cursor or Windsurf, the @ symbol must be typed by hand in the chat interface. Copy-pasting breaks the tool's ability to recognize it as a context reference.
/llms.txt route
The /llms.txt route contains a structured overview of all documentation pages and their links. It is approximately 5K tokens in size. Most users should start with /llms.txt as it contains all essential information and works with standard LLM context windows.
LLMs.txt definition and purpose
LLMs.txt is a structured documentation format specifically designed for large language models (LLMs). Nuxt provides LLMs.txt files that contain comprehensive information about the framework, making it easy for AI tools to understand and assist with Nuxt development. These files are optimized for AI consumption and contain structured information about concepts, APIs, usage patterns, and best practices.
Using LLMs.txt with Windsurf
Windsurf can directly access Nuxt LLMs.txt files to understand framework usage and best practices. Use @docs to reference specific LLMs.txt URLs or create persistent rules referencing these URLs in your workspace.
/llms-full.txt route
The /llms-full.txt route provides comprehensive documentation including getting started guides, API references, blog posts, and deployment guides. It is approximately 1M+ tokens in size. Use /llms-full.txt only if you need comprehensive implementation details and your AI tool supports large contexts (200K+ tokens).
NuxtImg component features
NuxtImg is a drop-in replacement for the native <img> tag that comes with the following enhancements: uses built-in provider to optimize local and remote images, converts src to provider optimized URLs with modern formats such as WebP or Avif, automatically resizes images based on width and height, generates responsive sizes when providing sizes option, and supports native lazy loading as well as other <img> attributes.
useFetch and useAsyncData prevent double fetching
Nuxt provides useFetch and useAsyncData composables that ensure API calls made on the server are not fetched again on the client. Instead, the data is forwarded to the client in the payload, avoiding duplicate requests.
Lazy Hydration in Nuxt
Lazy hydration, added in Nuxt v3.16, allows you to control when components become interactive. Use the hydrate-on-visible attribute on a component to delay its hydration until it becomes visible on the page. This can improve the time-to-interactive metric for the app.
Lazy Loading Components with Lazy prefix
To dynamically import (lazy-load) a component in Nuxt, add the Lazy prefix to the component's name. For example, LazyMountainsList will lazy-load the MountainsList component. This delays loading the component code until needed, which helps optimize JavaScript bundle size.
Unused code and dependencies performance problem
With project development, unused code or dependencies may accumulate without being used, increasing the bundle size. Solution: inspect package.json for unused dependencies and analyze code for unused utils, composables, and functions.
NuxtLink prefetchOn configuration
NuxtLink prefetching behavior can be configured in nuxt.config using experimental.defaults.nuxtLink.prefetchOn with properties: interaction (boolean, default false) and visibility (boolean, default true).
Chrome DevTools Performance panel metrics
Chrome DevTools Performance panel shows Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS) scores immediately. When interacting with the page, it also captures Interaction to Next Paint (INP), providing a full view of Core Web Vitals based on device and network conditions.
Not using Vue Performance tips problem
Vue documentation lists several performance improvements applicable to Nuxt projects but developers often focus only on Nuxt-specific improvements while forgetting that Nuxt applications are still Vue projects. Solution: use Vue concepts such as shallowRef, v-memo, v-once, etc to improve performance.
Loading everything at once performance problem
When a page loads without correct instruction about element loading order, it fetches everything at the same time, resulting in slow loading and poor user experience. Solution: use Progressive Enhancement where core webpage content is set first, then more nuanced and technically rigorous layers of presentation and features are added on top as the browser and internet connection allow.
Nuxt Scripts for third-party scripts
Nuxt Scripts allows loading third-party scripts (analytics, video embeds, maps, social media integrations) with better performance, privacy, security and developer experience. It provides an abstraction layer on top of third-party scripts with SSR support, type-safety, and full low-level control over how a script is loaded.
Nuxt Fonts processing steps
Nuxt Fonts automatically processes CSS and performs the following when encountering a font-family declaration: (1) Resolves fonts from public/ or web providers like Google, Bunny, and Fontshare, (2) Generates @font-face rules to load fonts from correct sources, (3) Proxies & caches fonts by rewriting URLs to /_fonts and downloading/caching locally, (4) Creates fallback metrics to adjust local system fonts matching web fonts reducing layout shift, (5) Includes fonts in build by bundling with project, hashing file names, and setting long-lived cache headers.
nuxi analyze command
The nuxi analyze command analyzes the production bundle of a Nuxt application. It leverages vite-bundle-visualizer to generate a visual representation of the application's bundle, making it easier to identify which components take up the most space and providing opportunities for optimization through splitting, lazy loading, or replacing inefficient alternatives.
NuxtImg optimization example
Images important for Largest Contentful Paint should use format="webp", :preload="{ fetchPriority: 'high' }", and loading="eager". Images that can be loaded later should use loading="lazy" and fetchpriority="low".
Nuxt Fonts automatic optimization
Nuxt Fonts automatically optimizes fonts (including custom fonts) and removes external network requests for improved privacy and performance. It automatically self-hosts font files and reduces layout shift using the fontaine package.
Nuxt DevTools performance features
Nuxt DevTools provides several features to measure Nuxt app performance: (1) Timeline tracks time spent on rendering, updating, and initializing components to identify performance bottlenecks, (2) Assets displays file sizes without transformations, (3) Render Tree shows connections between Vue components, scripts, and styles to optimize dynamic loading, (4) Inspect lists all files used in the Vue app with their size and evaluation time.
Not following patterns performance problem
When multiple developers work on a project, the more difficult it becomes to maintain a stable codebase. Developers tend to introduce new concepts from other projects, causing conflicts and performance problems. Solution: establish rules and patterns in the project such as good practices and design patterns for Vue composables.
$fetch is not globally configurable
The $fetch utility function is intentionally not globally configurable. This design choice ensures that fetching behavior throughout the application remains consistent and allows other integrations like modules to reliably depend on the behavior of core utilities like $fetch.