# Nuxt
> abortNavigation is a helper function that prevents navigation from taking place and throws an error if one is set as a parameter.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/abort-navigation.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/abort-navigation.md
# abortNavigation
> abortNavigation is a helper function that prevents navigation from taking place and throws an error if one is set as a parameter.
`abortNavigation` is only usable inside a [route middleware handler](/docs/4.x/directory-structure/app/middleware).
## Type
```ts [Signature]
export function abortNavigation (err?: Error | string): false
```
## Parameters
### `err`
- **Type**: [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) | `string`
Optional error to be thrown by `abortNavigation`.
## Examples
The example below shows how you can use `abortNavigation` in a route middleware to prevent unauthorized route access:
```ts [app/middleware/auth.ts]
export default defineNuxtRouteMiddleware((to, from) => {
const user = useState('user')
if (!user.value.isAuthorized) {
return abortNavigation()
}
if (to.path !== '/edit-post') {
return navigateTo('/edit-post')
}
})
```
### `err` as a String
You can pass the error as a string:
```ts [app/middleware/auth.ts]
export default defineNuxtRouteMiddleware((to, from) => {
const user = useState('user')
if (!user.value.isAuthorized) {
return abortNavigation('Insufficient permissions.')
}
})
```
### `err` as an Error Object
You can pass the error as an [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) object, e.g. caught by the `catch`-block:
```ts [app/middleware/auth.ts]
export default defineNuxtRouteMiddleware((to, from) => {
try {
/* code that might throw an error */
} catch (err) {
return abortNavigation(err)
}
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/add-route-middleware.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/add-route-middleware.md
# addRouteMiddleware
> addRouteMiddleware() is a helper function to dynamically add middleware in your application.
Route middleware are navigation guards stored in the [`app/middleware/`](/docs/4.x/directory-structure/app/middleware) directory of your Nuxt application (unless [set otherwise](/docs/4.x/api/nuxt-config#middleware)).
## Type
```ts
function addRouteMiddleware (name: string, middleware: RouteMiddleware, options?: AddRouteMiddlewareOptions): void
function addRouteMiddleware (middleware: RouteMiddleware): void
interface AddRouteMiddlewareOptions {
global?: boolean
}
```
## Parameters
### `name`
- **Type:** `string` | `RouteMiddleware`
Can be either a string or a function of type `RouteMiddleware`. Function takes the next route `to` as the first argument and the current route `from` as the second argument, both of which are Vue route objects.
Learn more about available properties of [route objects](/docs/4.x/api/composables/use-route).
### `middleware`
- **Type:** `RouteMiddleware`
The second argument is a function of type `RouteMiddleware`. Same as above, it provides `to` and `from` route objects. It becomes optional if the first argument in `addRouteMiddleware()` is already passed as a function.
### `options`
- **Type:** `AddRouteMiddlewareOptions`
An optional `options` argument lets you set the value of `global` to `true` to indicate whether the router middleware is global or not (set to `false` by default).
## Examples
### Named Route Middleware
Named route middleware is defined by providing a string as the first argument and a function as the second:
```ts [app/plugins/my-plugin.ts]
export default defineNuxtPlugin(() => {
addRouteMiddleware('named-middleware', () => {
console.log('named middleware added in Nuxt plugin')
})
})
```
When defined in a plugin, it overrides any existing middleware of the same name located in the `app/middleware/` directory.
### Global Route Middleware
Global route middleware can be defined in two ways:
- Pass a function directly as the first argument without a name. It will automatically be treated as global middleware and applied on every route change.```ts [app/plugins/my-plugin.ts]
export default defineNuxtPlugin(() => {
addRouteMiddleware((to, from) => {
console.log('anonymous global middleware that runs on every route change')
})
})
```
- Set an optional, third argument `{ global: true }` to indicate whether the route middleware is global.```ts [app/plugins/my-plugin.ts]
export default defineNuxtPlugin(() => {
addRouteMiddleware('global-middleware', (to, from) => {
console.log('global middleware that runs on every route change')
},
{ global: true },
)
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/add.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/add.md
# nuxt add
> Scaffold an entity into your Nuxt application.
```bash [Terminal]
npx nuxt add [--cwd=] [--logLevel=] [--force]
```
## Arguments
Argument
Description
TEMPLATE
Specify which template to generate (options: )
NAME
Specify name of the generated file
## Options
Option
Default
Description
--cwd=
.
Specify the working directory
--logLevel=
Specify build-time log level
--force
false
Force override file if it already exists
**Modifiers:**
Some templates support additional modifier flags to add a suffix (like `.client` or `.get`) to their name.
```bash [Terminal]
# Generates `/plugins/sockets.client.ts`
npx nuxt add plugin sockets --client
```
## `nuxt add component`
- Modifier flags: `--mode client|server` or `--client` or `--server`
```bash [Terminal]
# Generates `app/components/TheHeader.vue`
npx nuxt add component TheHeader
```
## `nuxt add composable`
```bash [Terminal]
# Generates `app/composables/foo.ts`
npx nuxt add composable foo
```
## `nuxt add layout`
```bash [Terminal]
# Generates `app/layouts/custom.vue`
npx nuxt add layout custom
```
## `nuxt add plugin`
- Modifier flags: `--mode client|server` or `--client`or `--server`
```bash [Terminal]
# Generates `app/plugins/analytics.ts`
npx nuxt add plugin analytics
```
## `nuxt add page`
```bash [Terminal]
# Generates `app/pages/about.vue`
npx nuxt add page about
```
```bash [Terminal]
# Generates `app/pages/category/[id].vue`
npx nuxt add page "category/[id]"
```
## `nuxt add middleware`
- Modifier flags: `--global`
```bash [Terminal]
# Generates `app/middleware/auth.ts`
npx nuxt add middleware auth
```
## `nuxt add api`
- Modifier flags: `--method` (can accept `connect`, `delete`, `get`, `head`, `options`, `patch`, `post`, `put` or `trace`) or alternatively you can directly use `--get`, `--post`, etc.
```bash [Terminal]
# Generates `server/api/hello.ts`
npx nuxt add api hello
```
## `nuxt add layer`
```bash [Terminal]
# Generates `layers/subscribe/nuxt.config.ts`
npx nuxt add layer subscribe
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/analyze.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/analyze.md
# nuxt analyze
> Analyze the production bundle or your Nuxt application.
```bash [Terminal]
npx nuxt analyze [ROOTDIR] [--cwd=] [--logLevel=] [--dotenv] [-e, --extends=] [--name=] [--no-serve]
```
The `analyze` command builds Nuxt and analyzes the production bundle (experimental).
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--dotenv
Path to
.env
file to load, relative to the root directory
-e, --extends=
Extend from a Nuxt layer
--name=
default
Name of the analysis
--no-serve
Skip serving the analysis results
This command sets `process.env.NODE_ENV` to `production`.
---
# Source: https://nuxt.com/raw/docs/3.x/api.md
# Source: https://nuxt.com/raw/docs/4.x/api.md
# Nuxt API Reference
> Explore all Nuxt Internals: Components, Composables, Utils, Commands and more.
Explore Nuxt built-in components for pages, layouts, head, and more.
Discover Nuxt composable functions for data-fetching, head management and more.
Learn about Nuxt utility functions for navigation, error handling and more.
List of Nuxt CLI commands to init, analyze, build, and preview your application.
Understand Nuxt Kit utilities to create modules and control Nuxt.
Go deep in Nuxt internals with Nuxt lifecycle hooks.
Explore all Nuxt configuration options to customize your application.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/app-config.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/app-config.md
# app.config.ts
> Expose reactive configuration within your application with the App Config file.
Nuxt provides an `app/app.config.ts` config file to expose reactive configuration within your application with the ability to update it at runtime within lifecycle or using a nuxt plugin and editing it with HMR (hot-module-replacement).
You can easily provide runtime app configuration using `app.config.ts` file. It can have either of `.ts`, `.js`, or `.mjs` extensions.
```ts [app/app.config.ts]twoslash
export default defineAppConfig({
foo: 'bar',
})
```
Do not put any secret values inside `app.config` file. It is exposed to the user client bundle.
When configuring a custom [`srcDir`](/docs/4.x/api/nuxt-config#srcdir), make sure to place the `app.config` file at the root of the new `srcDir` path.
## Usage
To expose config and environment variables to the rest of your app, you will need to define configuration in `app.config` file.
```ts [app/app.config.ts]twoslash
export default defineAppConfig({
theme: {
primaryColor: '#ababab',
},
})
```
We can now universally access `theme` both when server-rendering the page and in the browser using [`useAppConfig`](/docs/4.x/api/composables/use-app-config) composable.
```vue [app/pages/index.vue]
```
The [`updateAppConfig`](/docs/4.x/api/utils/update-app-config) utility can be used to update the `app.config` at runtime.
```vue [app/pages/index.vue]
```
Read more about the `updateAppConfig` utility.
## Typing App Config
Nuxt tries to automatically generate a TypeScript interface from provided app config so you won't have to type it yourself.
However, there are some cases where you might want to type it yourself. There are two possible things you might want to type.
### App Config Input
`AppConfigInput` might be used by module authors who are declaring what valid *input* options are when setting app config. This will not affect the type of `useAppConfig()`.
```ts [index.d.ts]
declare module 'nuxt/schema' {
interface AppConfigInput {
/** Theme configuration */
theme?: {
/** Primary app color */
primaryColor?: string
}
}
}
// It is always important to ensure you import/export something when augmenting a type
export {}
```
### App Config Output
If you want to type the result of calling [`useAppConfig()`](/docs/4.x/api/composables/use-app-config), then you will want to extend `AppConfig`.
Be careful when typing `AppConfig` as you will overwrite the types Nuxt infers from your actually defined app config.
```ts [index.d.ts]
declare module 'nuxt/schema' {
interface AppConfig {
// This will entirely replace the existing inferred `theme` property
theme: {
// You might want to type this value to add more specific types than Nuxt can infer,
// such as string literal types
primaryColor?: 'red' | 'blue'
}
}
}
// It is always important to ensure you import/export something when augmenting a type
export {}
```
## Merging Strategy
Nuxt uses a custom merging strategy for the `AppConfig` within [the layers](/docs/4.x/getting-started/layers) of your application.
This strategy is implemented using a [Function Merger](https://github.com/unjs/defu#function-merger), which allows defining a custom merging strategy for every key in `app.config` that has an array as value.
The function merger can only be used in the extended layers and not the main `app.config` in project.
Here's an example of how you can use:
```ts [layer/app/app.config.ts]twoslash
export default defineAppConfig({
// Default array value
array: ['hello'],
})
```
```ts [app/app.config.ts]twoslash
export default defineAppConfig({
// Overwrite default array value by using a merger function
array: () => ['bonjour'],
})
```
## Known Limitations
As of Nuxt v3.3, the `app.config.ts` file is shared with Nitro, which results in the following limitations:
1. You cannot import Vue components directly in `app.config.ts`.
2. Some auto-imports are not available in the Nitro context.
These limitations occur because Nitro processes the app config without full Vue component support.
While it's possible to use Vite plugins in the Nitro config as a workaround, this approach is not recommended:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
nitro: {
vite: {
plugins: [vue()],
},
},
})
```
Using this workaround may lead to unexpected behavior and bugs. The Vue plugin is one of many that are not available in the Nitro context.
Related issues:
- [Issue #19858](https://github.com/nuxt/nuxt/issues/19858)
- [Issue #19854](https://github.com/nuxt/nuxt/issues/19854)
Nitro v3 will resolve these limitations by removing support for the app config.
You can track the progress in [this pull request](https://github.com/nitrojs/nitro/pull/2521).
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/app.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/app.md
# app.vue
> The app.vue file is the main component of your Nuxt application.
If you have a `app/pages/` directory, the `app.vue` file is optional. Nuxt will automatically include a default `app.vue`, but you can still add your own to customize the structure and content as needed.
## Usage
### Minimal Usage
With Nuxt, the [`app/pages/`](/docs/4.x/directory-structure/app/pages) directory is optional. If it is not present, Nuxt will not include the [vue-router](https://router.vuejs.org) dependency. This is useful when building a landing page or an application that does not require routing.
```vue [app/app.vue]
Hello World!
```
### Usage with Pages
When you have a [`app/pages/`](/docs/4.x/directory-structure/app/pages) directory, you need to use the [``](/docs/4.x/api/components/nuxt-page) component to display the current page:
```vue [app/app.vue]
```
You can also define the common structure of your application directly in `app.vue`. This is useful when you want to include global elements such as a header or footer:
```vue [app/app.vue]
Header content
```
Remember that `app.vue` acts as the main component of your Nuxt application. Anything you add to it (JS and CSS) will be global and included in every page.
Learn more about how to structure your pages using the `app/pages/` directory.
### Usage with Layouts
When your application requires different layouts for different pages, you can use the `app/layouts/` directory with the [``](/docs/4.x/api/components/nuxt-layout) component. This allows you to define multiple layouts and apply them per page.
```vue [app/app.vue]
```
Learn more about how to structure your layouts using the `app/layouts/` directory.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/assets.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/assets.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/assets.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/assets.md
# Assets
> Nuxt offers two options for your assets.
Nuxt uses two directories to handle assets like stylesheets, fonts or images.
- The [`public/`](/docs/4.x/directory-structure/public) directory content is served at the server root as-is.
- The [`app/assets/`](/docs/4.x/directory-structure/app/assets) directory contains by convention every asset that you want the build tool (Vite or webpack) to process.
## Public Directory
The [`public/`](/docs/4.x/directory-structure/public) directory is used as a public server for static assets publicly available at a defined URL of your application.
You can get a file in the [`public/`](/docs/4.x/directory-structure/public) directory from your application's code or from a browser by the root URL `/`.
### Example
For example, referencing an image file in the `public/img/` directory, available at the static URL `/img/nuxt.png`:
```vue [app/app.vue]
```
## Assets Directory
Nuxt uses [Vite](https://vite.dev/guide/assets) (default) or [webpack](https://webpack.js.org/guides/asset-management/) to build and bundle your application. The main function of these build tools is to process JavaScript files, but they can be extended through [plugins](https://vite.dev/plugins/) (for Vite) or [loaders](https://webpack.js.org/loaders/) (for webpack) to process other kinds of assets, like stylesheets, fonts or SVGs. This step transforms the original file, mainly for performance or caching purposes (such as stylesheet minification or browser cache invalidation).
By convention, Nuxt uses the [`app/assets/`](/docs/4.x/directory-structure/app/assets) directory to store these files but there is no auto-scan functionality for this directory, and you can use any other name for it.
In your application's code, you can reference a file located in the [`app/assets/`](/docs/4.x/directory-structure/app/assets) directory by using the `~/assets/` path.
### Example
For example, referencing an image file that will be processed if a build tool is configured to handle this file extension:
```vue [app/app.vue]
```
Nuxt won't serve files in the [`app/assets/`](/docs/4.x/directory-structure/app/assets) directory at a static URL like `/assets/my-file.png`. If you need a static URL, use the [`public/`](/docs/4.x/getting-started/assets#public-directory) directory.
---
# Source: https://nuxt.com/raw/docs/3.x/migration/auto-imports.md
# Source: https://nuxt.com/raw/docs/3.x/examples/features/auto-imports.md
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/auto-imports.md
# Source: https://nuxt.com/raw/docs/4.x/migration/auto-imports.md
# Source: https://nuxt.com/raw/docs/4.x/examples/features/auto-imports.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/auto-imports.md
# Auto-imports
> Nuxt auto-imports components, composables, helper functions and Vue APIs.
Nuxt auto-imports components, composables and [Vue.js APIs](https://vuejs.org/api/) to use across your application without explicitly importing them.
```vue [app/app.vue]twoslash
```
Thanks to its opinionated directory structure, Nuxt can auto-import your [`app/components/`](/docs/4.x/directory-structure/app/components), [`app/composables/`](/docs/4.x/directory-structure/app/composables) and [`app/utils/`](/docs/4.x/directory-structure/app/utils).
Contrary to a classic global declaration, Nuxt preserves typings, IDEs completions and hints, and **only includes what is used in your production code**.
In the docs, every function that is not explicitly imported is auto-imported by Nuxt and can be used as-is in your code. You can find a reference for auto-imported components, composables and utilities in the [API section](/docs/4.x/api).
In the [`server`](/docs/4.x/directory-structure/server) directory, Nuxt auto-imports exported functions and variables from `server/utils/`.
You can also auto-import functions exported from custom folders or third-party packages by configuring the [`imports`](/docs/4.x/api/nuxt-config#imports) section of your `nuxt.config` file.
## Built-in Auto-imports
Nuxt auto-imports functions and composables to perform [data fetching](/docs/4.x/getting-started/data-fetching), get access to the [app context](/docs/4.x/api/composables/use-nuxt-app) and [runtime config](/docs/4.x/guide/going-further/runtime-config), manage [state](/docs/4.x/getting-started/state-management) or define components and plugins.
```vuetwoslash
```
Vue exposes Reactivity APIs like `ref` or `computed`, as well as lifecycle hooks and helpers that are auto-imported by Nuxt.
```vuetwoslash
```
### Vue and Nuxt Composables
When you are using the built-in Composition API composables provided by Vue and Nuxt, be aware that many of them rely on being called in the right *context*.
During a component lifecycle, Vue tracks the temporary instance of the current component (and similarly, Nuxt tracks a temporary instance of `nuxtApp`) via a global variable, and then unsets it in the same tick. This is essential when server rendering, both to avoid cross-request state pollution (leaking a shared reference between two users) and to avoid leakage between different components.
That means that (with very few exceptions) you cannot use them outside a Nuxt plugin, Nuxt route middleware or Vue setup function. On top of that, you must use them synchronously - that is, you cannot use `await` before calling a composable, except within `
```
### Disabling Auto-imports
If you want to disable auto-importing composables and utilities, you can set `imports.autoImport` to `false` in the `nuxt.config` file.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
imports: {
autoImport: false,
},
})
```
This will disable auto-imports completely but it's still possible to use [explicit imports](/docs/4.x/guide/concepts/auto-imports#explicit-imports) from `#imports`.
### Partially Disabling Auto-imports
If you want framework-specific functions like `ref` to remain auto-imported but wish to disable auto-imports for your own code (e.g., custom composables), you can set the `imports.scan` option to `false` in your `nuxt.config.ts` file:
```ts
export default defineNuxtConfig({
imports: {
scan: false,
},
})
```
With this configuration:
- Framework functions like `ref`, `computed`, or `watch` will still work without needing manual imports.
- Custom code, such as composables, will need to be manually imported in your files.
**Caution:** This setup has certain limitations:
- If you structure your project with layers, you will need to explicitly import the composables from each layer, rather than relying on auto-imports.
- This breaks the layer system’s override feature. If you use `imports.scan: false`, ensure you understand this side-effect and adjust your architecture accordingly.
## Auto-imported Components
Nuxt also automatically imports components from your `~/components` directory, although this is configured separately from auto-importing composables and utility functions.
To disable auto-importing components from your own `~/components` directory, you can set `components.dirs` to an empty array (though note that this will not affect components added by modules).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
components: {
dirs: [],
},
})
```
## Auto-import from Third-Party Packages
Nuxt also allows auto-importing from third-party packages.
If you are using the Nuxt module for that package, it is likely that the module has already configured auto-imports for that package.
For example, you could enable the auto-import of the `useI18n` composable from the `vue-i18n` package like this:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
imports: {
presets: [
{
from: 'vue-i18n',
imports: ['useI18n'],
},
],
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/autoimports.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/autoimports.md
# Auto-imports
> Nuxt Kit provides a set of utilities to help you work with auto-imports. These functions allow you to register your own utils, composables and Vue APIs.
Nuxt auto-imports helper functions, composables and Vue APIs to use across your application without explicitly importing them. Based on the directory structure, every Nuxt application can also use auto-imports for its own composables and plugins.
With Nuxt Kit you can also add your own auto-imports. `addImports` and `addImportsDir` allow you to add imports to the Nuxt application. `addImportsSources` allows you to add listed imports from 3rd party packages to the Nuxt application.
These utilities are powered by [`unimport`](https://github.com/unjs/unimport), which provides the underlying auto-import mechanism used in Nuxt.
These functions are designed for registering your own utils, composables and Vue APIs. For pages, components and plugins, please refer to the specific sections: [Pages](/docs/4.x/api/kit/pages), [Components](/docs/4.x/api/kit/components), [Plugins](/docs/4.x/api/kit/plugins).
Watch Vue School video about Auto-imports Nuxt Kit utilities.
## `addImports`
Add imports to the Nuxt application. It makes your imports available in the Nuxt app context without the need to import them manually.
To add imports for the Nitro server context, refer to the [`addServerImports`](/docs/4.x/api/kit/nitro#addserverimports) function.
### Usage
```tstwoslash
import { addImports, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const names = [
'useStoryblok',
'useStoryblokApi',
'useStoryblokBridge',
'renderRichText',
'RichTextSchema',
]
names.forEach(name =>
addImports({ name, as: name, from: '@storyblok/vue' }),
)
},
})
```
### Type
```ts
function addImports (imports: Import | Import[]): void
```
### Parameters
`imports`: An object or an array of objects with the following properties:
Property
Type
Required
Description
name
string
true
Import name to be detected.
from
string
true
Module specifier to import from.
priority
number
false
Priority of the import; if multiple imports have the same name, the one with the highest priority will be used.
disabled
boolean
false
If this import is disabled.
meta
Record
false
Metadata of the import.
type
boolean
false
If this import is a pure type import.
typeFrom
string
false
Use this as the
from
value when generating type declarations.
as
string
false
Import as this name.
## `addImportsDir`
Add imports from a directory to the Nuxt application. It will automatically import all files from the directory and make them available in the Nuxt application without the need to import them manually.
### Usage
```tstwoslash
import { addImportsDir, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: '@vueuse/motion',
configKey: 'motion',
},
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
addImportsDir(resolver.resolve('./runtime/composables'))
},
})
```
### Type
```ts
function addImportsDir (dirs: string | string[], options?: { prepend?: boolean }): void
```
### Parameters
Property
Type
Required
Description
dirs
string
|
string[]
true
A string or an array of strings with the path to the directory to import from.
options
{
prepend
?:
boolean
}
false
Options to pass to the import. If
prepend
is set to
true
, the imports will be prepended to the list of imports.
## `addImportsSources`
Add listed imports to the Nuxt application.
### Usage
```tstwoslash
import { addImportsSources, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
addImportsSources({
from: 'h3',
imports: [
'defineEventHandler',
'getQuery',
'getRouterParams',
'readBody',
'sendRedirect',
],
})
},
})
```
### Type
```ts
function addImportsSources (importSources: ImportSource | ImportSource[]): void
```
### Parameters
**importSources**: An object or an array of objects with the following properties:
Property
Type
Required
Description
from
string
true
Module specifier to import from.
imports
PresetImport
|
ImportSource[]
true
An object or an array of objects, which can be import names, import objects or import sources.
---
# Source: https://nuxt.com/raw/deploy/aws-amplify.md
# AWS Amplify
> Deploy your Nuxt Application to AWS Amplify infrastructure.
**Zero Configuration ✨**
Integration with AWS Amplify is possible with zero configuration, [learn more](https://nitro.unjs.io/deploy#zero-config-providers).
## Setup
1. Login to the [AWS Amplify Hosting Console](https://console.aws.amazon.com/amplify/?trk=01c5a476-5997-4e6a-88b9-fd0a0a5bbe34&sc_channel=el)
2. Click on "Get Started" > Amplify Hosting (Host your web app)
3. Select and authorize access to your Git repository provider and select the main branch
4. Choose a name for your app, make sure build settings are auto-detected and optionally set requirement environment variables under the advanced section
5. Optionally, select Enable SSR logging to enable server-side logging to your Amazon CloudWatch account
6. Confirm configuration and click on "Save and Deploy"
## Learn more
Watch an Amplify Hosting tutorial with Nuxt
Head over **Nitro documentation** to learn more about the aws-amplify deployment preset.
---
# Source: https://nuxt.com/raw/deploy/azure.md
# Azure
> Deploy your Nuxt Application to Azure infrastructure.
## Azure Static Web Apps
**Zero Configuration ✨**
Integration with Azure Static Web Apps provider is possible with zero configuration, [learn more](https://nitro.unjs.io/deploy#zero-config-providers).
Azure Static Web Apps are designed to be deployed continuously in a [GitHub Actions workflow](https://docs.microsoft.com/en-us/azure/static-web-apps/github-actions-workflow). By default, Nuxt will detect this deployment environment to enable the `azure` preset.
### Local preview
Install [Azure Functions Core Tools](https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local) if you want to test locally.
You can invoke a development environment to preview before deploying.
```bash [Terminal]
npx nuxi build --preset=azure
npx @azure/static-web-apps-cli start .output/public --api-location .output/server
```
### Configuration
Azure Static Web Apps are [configured](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration) using the `staticwebapp.config.json` file.
Nuxt automatically generates this configuration file whenever the application is built with the `azure` preset.
It adds the following properties based on the following criteria:
All prerendered routes are added. Additionally, if you do not have an
index.html
file an empty one is created for you for compatibility purposes and also requests to
/index.html
are redirected to the root directory which is handled by
/api/server
.
[]
### Custom Configuration
You can alter the generated configuration using `azure.config` option. For instance, if you wanted to specify a Node runtime for your Azure Functions, edit your `nuxt.config.ts` file to the following:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
// ...
nitro: {
azure: {
config: {
// ...
platform: {
apiRuntime: 'node:18'
}
}
}
}
})
```
Custom routes will be added and matched first. In the case of a conflict (determined if an object has the same route property), custom routes will override generated ones.
### Deploy from CI/CD via GitHub Actions
When you link your GitHub repository to Azure Static Web Apps, a workflow file is added to the repository.
When you are asked to select your framework, select custom and provide the following information:
Input
Value
app_location
'/'
api_location
'.output/server'
output_location
'.output/public'
If you miss this step, you can always find the build configuration section in your workflow and update the build configuration:
```yaml [.github/workflows/azure-static-web-apps-.yml]
###### Repository/Build Configurations ######
app_location: '/'
api_location: '.output/server'
output_location: '.output/public'
###### End of Repository/Build Configurations ######
```
That's it! Now Azure Static Web Apps will automatically deploy your Nitro-powered application on push.
If you are using `runtimeConfig`, you will likely want to configure the corresponding [environment variables on Azure](https://docs.microsoft.com/en-us/azure/static-web-apps/application-settings).
## More options
Learn about the other Azure deployment presets on Nitro documentation.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/modules/best-practices.md
# Source: https://nuxt.com/raw/docs/4.x/guide/modules/best-practices.md
# Follow Best Practices
> Build performant and maintainable Nuxt modules with these guidelines.
With great power comes great responsibility. While modules are powerful, here are some best practices to keep in mind while authoring modules to keep applications performant and developer experience great.
## Handle Async Setup
As we've seen, Nuxt modules can be asynchronous. For example, you may want to develop a module that needs fetching some API or calling an async function.
However, be careful with asynchronous behaviors as Nuxt will wait for your module to setup before going to the next module and starting the development server, build process, etc. Prefer deferring time-consuming logic to Nuxt hooks.
If your module takes more than **1 second** to setup, Nuxt will emit a warning about it.
## Prefix Your Exports
Nuxt modules should provide an explicit prefix for any exposed configuration, plugin, API, composable, component, or server route to avoid conflicts with other modules, Nuxt internals, or user-defined code.
Ideally, prefix them with your module's name. For example, if your module is called `nuxt-foo`:
Type
❌ Avoid
✅ Prefer
Components
,
,
Composables
useData()
,
useModal()
useFooData()
,
useFooModal()
Server routes
/api/track
,
/api/data
/api/_foo/track
,
/api/_foo/data
### Server Routes
This is particularly important for server routes, where common paths like `/api/auth`, `/api/login`, or `/api/user` are very likely already used by the application.
Use a unique prefix based on your module name:
- `/api/_foo/...` (using underscore prefix)
- `/_foo/...` (for non-API routes)
## Use Lifecycle Hooks
When your module needs to perform one-time setup tasks (like generating configuration files, setting up databases, or installing dependencies), use lifecycle hooks instead of running the logic in your main `setup` function.
```ts
import { addServerHandler, defineNuxtModule } from 'nuxt/kit'
import semver from 'semver'
export default defineNuxtModule({
meta: {
name: 'my-database-module',
version: '1.0.0',
},
async onInstall (nuxt) {
// One-time setup: create database schema, generate config files, etc.
await generateDatabaseConfig(nuxt.options.rootDir)
},
async onUpgrade (nuxt, options, previousVersion) {
// Handle version-specific migrations
if (semver.lt(previousVersion, '1.0.0')) {
await migrateLegacyData()
}
},
setup (options, nuxt) {
// Regular setup logic that runs on every build
addServerHandler({ /* ... */ })
},
})
```
This pattern prevents unnecessary work on every build and provides a better developer experience. See the [lifecycle hooks documentation](/docs/4.x/api/kit/modules#using-lifecycle-hooks-for-module-installation-and-upgrade) for more details.
## Be TypeScript Friendly
Nuxt has first-class TypeScript integration for the best developer experience.
Exposing types and using TypeScript to develop modules benefits users even when not using TypeScript directly.
## Use ESM Syntax
Nuxt relies on native ESM. Please read [Native ES Modules](/docs/4.x/guide/concepts/esm) for more information.
## Document Your Module
Consider documenting module usage in the readme file:
- Why use this module?
- How to use this module?
- What does this module do?
Linking to the integration website and documentation is always a good idea.
## Provide a Demo
It's a good practice to make a minimal reproduction with your module and [StackBlitz](https://nuxt.new/s/v4) that you add to your module readme.
This not only provides potential users of your module a quick and easy way to experiment with the module but also an easy way for them to build minimal reproductions they can send you when they encounter issues.
## Stay Version Agnostic
Nuxt, Nuxt Kit, and other new toolings are made to have both forward and backward compatibility in mind.
Please use "X for Nuxt" instead of "X for Nuxt 3" to avoid fragmentation in the ecosystem and prefer using `meta.compatibility` to set Nuxt version constraints.
## Follow Starter Conventions
The module starter comes with a default set of tools and configurations (e.g. ESLint configuration). If you plan on open-sourcing your module, sticking with those defaults ensures your module shares a consistent coding style with other [community modules](/modules) out there, making it easier for others to contribute.
---
# Source: https://nuxt.com/raw/docs/3.x/bridge/bridge-composition-api.md
# Source: https://nuxt.com/raw/docs/4.x/bridge/bridge-composition-api.md
# Legacy Composition API
> Learn how to migrate to Composition API with Nuxt Bridge.
Nuxt Bridge provides access to Composition API syntax. It is specifically designed to be aligned with Nuxt 3. Because of this, there are a few extra steps to take when enabling Nuxt Bridge, if you have been using the Composition API previously.
## Remove Modules
- Remove `@vue/composition-api` from your dependencies.
- Remove `@nuxtjs/composition-api` from your dependencies (and from your modules in `nuxt.config`).
## Using `@vue/composition-api`
If you have been using just `@vue/composition-api` and not `@nuxtjs/composition-api`, then things are very straightforward.
1. First, remove the plugin where you are manually registering the Composition API. Nuxt Bridge will handle this for you.```diff
- import Vue from 'vue'
- import VueCompositionApi from '@vue/composition-api'
-
- Vue.use(VueCompositionApi)
```
2. Otherwise, there is nothing you need to do. However, if you want, you can remove your explicit imports from `@vue/composition-api` and rely on Nuxt Bridge auto-importing them for you.
## Migrating from `@nuxtjs/composition-api`
Nuxt Bridge implements the Composition API slightly differently from `@nuxtjs/composition-api` and provides different composables (designed to be aligned with the composables that Nuxt 3 provides).
Because some composables have been removed and don't yet have a replacement, this will be a slightly more complicated process.
### Remove `@nuxtjs/composition-api/module` from your buildModules
You don't have to immediately update your imports yet - Nuxt Bridge will automatically provide a 'shim' for most imports you currently have, to give you time to migrate to the new, Nuxt 3-compatible composables, with the following exceptions:
- `withContext` has been removed. See [below](/docs/4.x/bridge/nuxt3-compatible-api#usecontext-and-withcontext).
- `useStatic` has been removed. There is no current replacement. Feel free to raise a discussion if you have a use case for this.
- `reqRef` and `reqSsrRef`, which were deprecated, have now been removed entirely. Follow the instructions below regarding [ssrRef](/docs/4.x/bridge/nuxt3-compatible-api#ssrref-and-shallowssrref) to replace this.
### Set `bridge.capi`
```ts
import { defineNuxtConfig } from '@nuxt/bridge'
export default defineNuxtConfig({
bridge: {
capi: true,
nitro: false, // If migration to Nitro is complete, set to true
},
})
```
For each other composable you are using from `@nuxtjs/composition-api`, follow the steps below.
### useFetch
`$fetchState` and `$fetch` have been removed.
```diff
const {
- $fetch,
- $fetchState,
+ fetch,
+ fetchState,
} = useFetch(() => { posts.value = await $fetch('/api/posts') })
```
### `defineNuxtMiddleware`
This was a type-helper stub function that is now removed.
Remove the `defineNuxtMiddleware` wrapper:
```diff
- import { defineNuxtMiddleware } from '@nuxtjs/composition-api`
- export default defineNuxtMiddleware((ctx) => {})
+ export default (ctx) => {}
```
For typescript support, you can use `@nuxt/types`:
```ts
import type { Middleware } from '@nuxt/types'
export default function (ctx) { }
```
### `defineNuxtPlugin`
This was a type-helper stub function that is now removed.
You may also keep using Nuxt 2-style plugins, by removing the function (as with [defineNuxtMiddleware](/docs/4.x/bridge/bridge-composition-api#definenuxtmiddleware)).
Remove the `defineNuxtPlugin` wrapper:
```diff
- import { defineNuxtPlugin } from '@nuxtjs/composition-api'
- export default defineNuxtPlugin((ctx, inject) => {})
+ export default (ctx, inject) => {}
```
For typescript support, you can use `@nuxt/types`:
```ts
import type { Plugin } from '@nuxt/types'
export default function (ctx, inject) {}
```
While this example is valid, Nuxt 3 introduces a new defineNuxtPlugin function that has a slightly different signature.
### `useRouter` and `useRoute`
Nuxt Bridge provides direct replacements for these composables via [`useRouter`](/docs/4.x/api/composables/use-router) and `useRoute`.
The only key difference is that [`useRoute`](/docs/4.x/api/composables/use-route) no longer returns a computed property.
```diff
- import { useRouter, useRoute } from '@nuxtjs/composition-api'
const router = useRouter()
const route = useRoute()
- console.log(route.value.path)
+ console.log(route.path)
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/build-module.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/build-module.md
# nuxt build-module
> Nuxt command to build your Nuxt module before publishing.
```bash [Terminal]
npx nuxt build-module [ROOTDIR] [--cwd=] [--logLevel=] [--build] [--stub] [--sourcemap] [--prepare]
```
The `build-module` command runs `@nuxt/module-builder` to generate `dist` directory within your `rootDir` that contains the full build for your **nuxt-module**.
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--build
false
Build module for distribution
--stub
false
Stub dist instead of actually building it for development
--sourcemap
false
Generate sourcemaps
--prepare
false
Prepare module for local development
Read more about `@nuxt/module-builder`.
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/build.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/build.md
# nuxt build
> Build your Nuxt application.
```bash [Terminal]
npx nuxt build [ROOTDIR] [--cwd=] [--logLevel=] [--prerender] [--preset] [--dotenv] [--envName] [-e, --extends=]
```
The `build` command creates a `.output` directory with all your application, server and dependencies ready for production.
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--prerender
Build Nuxt and prerender static routes
--preset
Nitro server preset
--dotenv
Path to
.env
file to load, relative to the root directory
--envName
The environment to use when resolving configuration overrides (default is
production
when building, and
development
when running the dev server)
-e, --extends=
Extend from a Nuxt layer
This command sets `process.env.NODE_ENV` to `production`.
`--prerender` will always set the `preset` to `static`
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/builder.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/builder.md
# Builder
> Nuxt Kit provides a set of utilities to help you work with the builder. These functions allow you to extend the Vite and webpack configurations.
Nuxt have builders based on [Vite](https://github.com/nuxt/nuxt/tree/main/packages/vite) and [webpack](https://github.com/nuxt/nuxt/tree/main/packages/webpack). You can extend the config passed to each one using `extendViteConfig` and `extendWebpackConfig` functions. You can also add additional plugins via `addVitePlugin`, `addWebpackPlugin` and `addBuildPlugin`.
## `extendViteConfig`
Extends the Vite configuration. Callback function can be called multiple times, when applying to both client and server builds.
This hook is now deprecated, and we recommend using a Vite plugin instead with a `config` hook, or — for environment-specific configuration — the `applyToEnvironment` hook.
### Usage
```tstwoslash
import { defineNuxtModule, extendViteConfig } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
extendViteConfig((config) => {
config.optimizeDeps ||= {}
config.optimizeDeps.include ||= []
config.optimizeDeps.include.push('cross-fetch')
})
},
})
```
For environment-specific configuration in Nuxt 5+, use `addVitePlugin()` instead:
```tstwoslash
import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
// For global configuration (affects all environments)
addVitePlugin(() => ({
name: 'my-global-plugin',
config (config) {
// This runs before environment setup
config.optimizeDeps ||= {}
config.optimizeDeps.include ||= []
config.optimizeDeps.include.push('cross-fetch')
},
}))
// For environment-specific configuration
addVitePlugin(() => ({
name: 'my-client-plugin',
applyToEnvironment (environment) {
return environment.name === 'client'
},
configEnvironment (name, config) {
// This only affects the client environment
config.optimizeDeps ||= {}
config.optimizeDeps.include ||= []
config.optimizeDeps.include.push('client-only-package')
},
}))
},
})
```
**Important:** The `config` hook runs before `applyToEnvironment` and modifies the global configuration. Use `configEnvironment` for environment-specific configuration changes.
### Type
```tstwoslash
// @errors: 2391
import type { UserConfig as ViteConfig } from 'vite'
import type { ExtendViteConfigOptions } from '@nuxt/kit'
// ---cut---
function extendViteConfig (callback: ((config: ViteConfig) => void), options?: ExtendViteConfigOptions): void
```
Check out the Vite website for more information about its configuration.
### Parameters
**callback**: A callback function that will be called with the Vite configuration object.
**options**: Options to pass to the callback function. This object can have the following properties:
Property
Type
Required
Description
dev
boolean
false
If set to
true
, the callback function will be called when building in development mode.
build
boolean
false
If set to
true
, the callback function will be called when building in production mode.
server
boolean
false
If set to
true
, the callback function will be called when building the server bundle.
Deprecated in Nuxt 5+.
Use
addVitePlugin()
with
applyToEnvironment()
instead.
client
boolean
false
If set to
true
, the callback function will be called when building the client bundle.
Deprecated in Nuxt 5+.
Use
addVitePlugin()
with
applyToEnvironment()
instead.
prepend
boolean
false
If set to
true
, the callback function will be prepended to the array with
unshift()
instead of
push()
.
## `extendWebpackConfig`
Extends the webpack configuration. Callback function can be called multiple times, when applying to both client and server builds.
### Usage
```tstwoslash
import { defineNuxtModule, extendWebpackConfig } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
extendWebpackConfig((config) => {
config.module!.rules!.push({
test: /\.txt$/,
use: 'raw-loader',
})
})
},
})
```
### Type
```tstwoslash
// @errors: 2391
import type { Configuration as WebpackConfig } from 'webpack'
import type { ExtendWebpackConfigOptions } from '@nuxt/kit'
// ---cut---
function extendWebpackConfig (callback: ((config: WebpackConfig) => void), options?: ExtendWebpackConfigOptions): void
```
Check out webpack website for more information about its configuration.
### Parameters
**callback**: A callback function that will be called with the webpack configuration object.
**options**: Options to pass to the callback function. This object can have the following properties:
Property
Type
Required
Description
dev
boolean
false
If set to
true
, the callback function will be called when building in development mode.
build
boolean
false
If set to
true
, the callback function will be called when building in production mode.
server
boolean
false
If set to
true
, the callback function will be called when building the server bundle.
client
boolean
false
If set to
true
, the callback function will be called when building the client bundle.
prepend
boolean
false
If set to
true
, the callback function will be prepended to the array with
unshift()
instead of
push()
.
## `addVitePlugin`
Append Vite plugin to the config.
In Nuxt 5+, plugins registered with `server: false` or `client: false` options will not have their `config` or `configResolved` hooks called. Instead, use the `applyToEnvironment()` method instead for environment-specific plugins.
### Usage
```tstwoslash
// @errors: 2307
// ---cut---
import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
import { svg4VuePlugin } from 'vite-plugin-svg4vue'
export default defineNuxtModule({
meta: {
name: 'nuxt-svg-icons',
configKey: 'nuxtSvgIcons',
},
defaults: {
svg4vue: {
assetsDirName: 'assets/icons',
},
},
setup (options) {
addVitePlugin(svg4VuePlugin(options.svg4vue))
// or, to add a vite plugin to only one environment
addVitePlugin(() => ({
name: 'my-client-plugin',
applyToEnvironment (environment) {
return environment.name === 'client'
},
// ... rest of your client-only plugin
}))
},
})
```
### Type
```tstwoslash
// @errors: 2391
import type { Plugin as VitePlugin } from 'vite'
import type { ExtendViteConfigOptions } from '@nuxt/kit'
// ---cut---
function addVitePlugin (pluginOrGetter: VitePlugin | VitePlugin[] | (() => VitePlugin | VitePlugin[]), options?: ExtendViteConfigOptions): void
```
See [Vite website](https://vite.dev/guide/api-plugin) for more information about Vite plugins. You can also use [this repository](https://github.com/vitejs/awesome-vite#plugins) to find a plugin that suits your needs.
### Parameters
**pluginOrGetter**: A Vite plugin instance or an array of Vite plugin instances. If a function is provided, it must return a Vite plugin instance or an array of Vite plugin instances. The function can also be async or return a Promise, which is useful for lazy-loading plugins:
```tstwoslash
// @errors: 2307
import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
// Lazy load the plugin - only imported when the build actually runs
addVitePlugin(() => import('my-vite-plugin').then(r => r.default()))
},
})
```
**options**: Options to pass to the callback function. This object can have the following properties:
Property
Type
Required
Description
dev
boolean
false
If set to
true
, the callback function will be called when building in development mode.
build
boolean
false
If set to
true
, the callback function will be called when building in production mode.
server
boolean
false
If set to
true
, the callback function will be called when building the server bundle.
Deprecated in Nuxt 5+.
Use
applyToEnvironment()
instead.
client
boolean
false
If set to
true
, the callback function will be called when building the client bundle.
Deprecated in Nuxt 5+.
Use
applyToEnvironment()
instead.
prepend
boolean
false
If set to
true
, the callback function will be prepended to the array with
unshift()
instead of
push()
.
## `addWebpackPlugin`
Append webpack plugin to the config.
### Usage
```ts
import EslintWebpackPlugin from 'eslint-webpack-plugin'
import { addWebpackPlugin, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'nuxt-eslint',
configKey: 'eslint',
},
defaults: nuxt => ({
include: [`${nuxt.options.srcDir}/**/*.{js,jsx,ts,tsx,vue}`],
lintOnStart: true,
}),
setup (options, nuxt) {
const webpackOptions = {
...options,
context: nuxt.options.srcDir,
files: options.include,
lintDirtyModulesOnly: !options.lintOnStart,
}
addWebpackPlugin(new EslintWebpackPlugin(webpackOptions), { server: false })
},
})
```
### Type
```tstwoslash
// @errors: 2391
import type { WebpackPluginInstance } from 'webpack'
import type { ExtendWebpackConfigOptions } from '@nuxt/kit'
// ---cut---
function addWebpackPlugin (pluginOrGetter: WebpackPluginInstance | WebpackPluginInstance[] | (() => WebpackPluginInstance | WebpackPluginInstance[]), options?: ExtendWebpackConfigOptions): void
```
See [webpack website](https://webpack.js.org/concepts/plugins/) for more information about webpack plugins. You can also use [this collection](https://webpack.js.org/awesome-webpack/#webpack-plugins) to find a plugin that suits your needs.
### Parameters
**pluginOrGetter**: A webpack plugin instance or an array of webpack plugin instances. If a function is provided, it must return a webpack plugin instance or an array of webpack plugin instances. The function can also be async or return a Promise, enabling lazy-loading of plugins.
**options**: Options to pass to the callback function. This object can have the following properties:
Property
Type
Required
Description
dev
boolean
false
If set to
true
, the callback function will be called when building in development mode.
build
boolean
false
If set to
true
, the callback function will be called when building in production mode.
server
boolean
false
If set to
true
, the callback function will be called when building the server bundle.
client
boolean
false
If set to
true
, the callback function will be called when building the client bundle.
prepend
boolean
false
If set to
true
, the callback function will be prepended to the array with
unshift()
instead of
push()
.
## `addBuildPlugin`
Builder-agnostic version of `addVitePlugin` and `addWebpackPlugin`. It will add the plugin to both Vite and webpack configurations if they are present.
### Type
```tstwoslash
// @errors: 2391
import type { ExtendConfigOptions } from '@nuxt/kit'
import type { Plugin as VitePlugin } from 'vite'
import type { WebpackPluginInstance } from 'webpack'
import type { RspackPluginInstance } from '@rspack/core'
interface AddBuildPluginFactory {
vite?: () => VitePlugin | VitePlugin[]
webpack?: () => WebpackPluginInstance | WebpackPluginInstance[]
rspack?: () => RspackPluginInstance | RspackPluginInstance[]
}
// ---cut---
function addBuildPlugin (pluginFactory: AddBuildPluginFactory, options?: ExtendConfigOptions): void
```
### Parameters
**pluginFactory**: A factory function that returns an object with `vite` and/or `webpack` properties. These properties must be functions that return a Vite plugin instance or an array of Vite plugin instances and/or a webpack plugin instance or an array of webpack plugin instances.
**options**: Options to pass to the callback function. This object can have the following properties:
Property
Type
Required
Description
dev
boolean
false
If set to
true
, the callback function will be called when building in development mode.
build
boolean
false
If set to
true
, the callback function will be called when building in production mode.
server
boolean
false
If set to
true
, the callback function will be called when building the server bundle.
client
boolean
false
If set to
true
, the callback function will be called when building the client bundle.
prepend
boolean
false
If set to
true
, the callback function will be prepended to the array with
unshift()
instead of
push()
.
---
# Source: https://nuxt.com/raw/blog/building-a-feedback-widget.md
# Building a Privacy-First Feedback Widget
> A lightweight, privacy-focused widget to gather your feedback on Nuxt documentation, built with Drizzle, NuxtHub database and Motion Vue.
Documentation is at the heart of the Nuxt developer experience. To continuously improve it, we needed a simple and effective way to collect user feedback directly on each page. Here's how we designed and implemented our feedback widget, drawing inspiration from Plausible's privacy-first approach.
## Why a feedback widget?
Currently, users can provide feedback on our documentation by creating GitHub issues or contacting us directly. While these channels are valuable and remain important, they require users to leave their current context and take several steps to share their thoughts.
We wanted something different:
- **Contextual**: Directly integrated into each documentation page
- **Frictionless**: Maximum 2 clicks to provide feedback
- **Privacy-respecting**: No personal tracking, GDPR compliant by design
## Technical architecture
Our solution consists of three main components:
### 1. Frontend with Motion animations
The interface combines Vue 3's Composition API with [Motion for Vue](https://motion.dev/docs/vue) to create an engaging user experience. The widget uses layout animations for smooth state transitions and spring physics for natural feedback. The `useFeedback` composable handles all state management and automatically resets when users navigate between pages.
Here's the success state animation, for example:
```vue
✨
Thank you for your feedback!
Your input helps us improve the documentation.
```
You can find the source code of the feedback widget [here](https://github.com/nuxt/nuxt.com/tree/main/app/components/Feedback.vue).
### 2. Plausible-inspired anonymization
The challenge was detecting duplicates (a user changing their mind) while preserving privacy. We took inspiration from [Plausible](https://plausible.io/)'s approach to [counting unique visitors without cookies](https://plausible.io/data-policy).
```typescript
export async function generateHash(
today: string,
ip: string,
domain: string,
userAgent: string
): Promise {
const data = `${today}+${domain}+${ip}+${userAgent}`
const buffer = await crypto.subtle.digest(
'SHA-1',
new TextEncoder().encode(data)
)
return [...new Uint8Array(buffer)]
.map(b => b.toString(16).padStart(2, '0'))
.join('')
}
```
This method generates a unique daily identifier by combining:
- **IP + User-Agent**: Naturally sent with every HTTP request
- **Domain**: Enables environment isolation
- **Current date**: Forces daily rotation of identifiers
**Why is this secure?**
- IP and User-Agent are never stored in the database
- The hash changes daily, preventing long-term tracking
- Very difficult to reverse engineer original data from the hash
- GDPR compliant by design (no persistent personal data)
### 3. Database persistence with conflict handling
First, we define the schema for the feedback table and add a unique constraint on the `path` and `fingerprint` columns.
```typescript
export const feedback = sqliteTable('feedback', {
id: integer('id').primaryKey({ autoIncrement: true }),
rating: text('rating').notNull(),
feedback: text('feedback'),
path: text('path').notNull(),
title: text('title').notNull(),
stem: text('stem').notNull(),
country: text('country').notNull(),
fingerprint: text('fingerprint').notNull(),
createdAt: integer({ mode: 'timestamp' }).notNull(),
updatedAt: integer({ mode: 'timestamp' }).notNull()
}, table => [uniqueIndex('path_fingerprint_idx').on(table.path, table.fingerprint)])
```
Then, in the server, we use [Drizzle](https://orm.drizzle.team/docs/get-started) with an `UPSERT` strategy:
```typescript
await drizzle.insert(tables.feedback).values({
rating: data.rating,
feedback: data.feedback || null,
path: data.path,
title: data.title,
stem: data.stem,
country: event.context.cf?.country || 'unknown',
fingerprint,
createdAt: new Date(),
updatedAt: new Date()
}).onConflictDoUpdate({
target: [tables.feedback.path, tables.feedback.fingerprint],
set: {
rating: data.rating,
feedback: data.feedback || null,
country,
updatedAt: new Date()
}
})
```
This approach enables updates if the user changes their mind within the day, creation for new feedback, and automatic deduplication per page and user.
You can find the source code of the server side [here](https://github.com/nuxt/nuxt.com/tree/main/server).
## Shared types for consistency
We use Zod for runtime validation and type generation:
```typescript
export const FEEDBACK_RATINGS = [
'very-helpful',
'helpful',
'not-helpful',
'confusing'
] as const
export const feedbackSchema = z.object({
rating: z.enum(FEEDBACK_RATINGS),
feedback: z.string().optional(),
path: z.string(),
title: z.string(),
stem: z.string()
})
export type FeedbackInput = z.infer
```
This approach ensures consistency across frontend, API, and database.
## What's next
The widget is now live across all documentation pages. Our next step is building an admin interface within nuxt.com to analyze feedback patterns and identify pages that need improvement. This will help us continuously enhance the documentation quality based on real user feedback.
The complete source code is available on [GitHub](https://github.com/nuxt/nuxt.com) for inspiration and contributions!
---
# Source: https://nuxt.com/raw/blog/building-nuxt-mcp.md
# Building an MCP Server for Nuxt
> How we built the Nuxt MCP server to enable AI assistants to access our documentation through structured data and composable tools.
AI assistants are becoming an increasingly important part of the developer experience. To help them provide accurate, up-to-date information about Nuxt, we built an MCP server that exposes our documentation, blog posts, and deployment guides in a structured way. Here's how we did it with the [Nuxt MCP Toolkit](https://mcp-toolkit.nuxt.dev), and how you can build your own.
Want to test the Nuxt MCP server? Jump to the [Nuxt MCP Server Documentation](/docs/4.x/guide/ai/mcp).
## What is MCP and why did we build it?
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open standard that enables AI assistants to securely access data and tools. Think of it as an API specifically designed for AI assistants: rather than returning HTML or generic JSON, it provides structured, semantic data that LLMs can easily understand and use.
MCP defines three main primitives:
- **Resources**: Allow servers to share data that provides context to language models, such as files, database schemas, or application-specific information. Each resource is uniquely identified by a URI.
- **Tools**: Enable AI models to interact with external systems and perform operations (like searching or API calls)
- **Prompts**: Reusable prompt templates with arguments that can be invoked by users
### Why MCP over RAG?
We've observed that AI assistants using MCP servers provide **significantly better responses** than traditional RAG (Retrieval-Augmented Generation) approaches:
- **Structured data in, structured data out**: Tools accept well-defined parameters and return typed data that prevents hallucinations
- **Composable tools**: AI assistants can chain tools together, using the output of one tool as input for another (e.g., search for a topic, then fetch the full content)
- **Faster and more accurate**: No need to process and chunk large documents at query time
- **Always up-to-date**: Direct access to your content layer without reindexing
- **Context-aware navigation**: The AI can intelligently navigate relationships between content
Both [Nuxt](https://nuxt.com/mcp) and [Nuxt UI](https://ui.nuxt.com/mcp) now have MCP servers with similar architectures, making it easier for AI assistants to help developers with these frameworks.
## Technical architecture
Our MCP server is built directly into nuxt.com using the [Nuxt MCP Toolkit](https://mcp-toolkit.nuxt.dev) module. The module provides automatic discovery of tools, resources, and prompts from your server directory:
```text
nuxt.com/
├── server/
│ └── mcp/
│ ├── tools/
│ │ ├── list-documentation-pages.ts
│ │ ├── get-documentation-page.ts
│ │ └── ...
│ ├── resources/
│ │ ├── nuxt-documentation-pages.ts
│ │ └── ...
│ └── prompts/
│ ├── find-documentation-for-topic.ts
│ └── ...
└── nuxt.config.ts
```
The architecture is straightforward: you define your tools, resources, and prompts as individual files, and the module automatically registers them and exposes an HTTP endpoint for MCP clients to connect. No manual server setup, no transport configuration, just create files in the right directories and they're ready to use.
## Implementation deep dive
### Module setup
Getting started is as simple as adding the module to your Nuxt config:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxtjs/mcp-toolkit'],
mcp: {
name: 'Nuxt',
}
})
```
That's it. The module will automatically scan your `server/mcp/` directory and register everything it finds.
### Tools: Operations for AI models
Tools enable language models to interact with external systems by accepting parameters and performing operations. Here's how we implemented our `list_documentation_pages` tool:
```ts [server/mcp/tools/list-documentation-pages.ts]
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'
export default defineMcpTool({
description: `Lists all available Nuxt documentation pages with their categories and basic information.
WHEN TO USE: Use this tool when you need to EXPLORE or SEARCH for documentation about a topic but don't know the exact page path.
WHEN NOT TO USE: If you already know the specific page path, use get_documentation_page directly instead.`,
inputSchema: {
version: z.enum(['3.x', '4.x', 'all']).optional().default('4.x').describe('Documentation version to fetch')
},
cache: '1h',
async handler({ version }) {
const event = useEvent()
const allDocs = await queryCollection(event, 'docsv4')
.select('title', 'path', 'description')
.all()
return jsonResult(allDocs.map(doc => ({
title: doc.title,
path: doc.path,
description: doc.description,
url: `https://nuxt.com${doc.path}`
})))
}
})
```
Notice a few key things:
- **defineMcpTool** is auto-imported, no need to import it manually
- **inputSchema** uses Zod for parameter validation
- **cache: '1h'** enables built-in response caching
- **jsonResult()** is a helper that formats the response correctly
The tool name is automatically derived from the filename (`list-documentation-pages.ts` becomes `list_documentation_pages`).
### Resources: Context for language models
Resources allow servers to share data that provides context to language models, such as files, database schemas, or application-specific information. Each resource is uniquely identified by a URI.
The simplest way to expose a file is using the `file` property, which automatically handles URI generation, MIME type detection, and file reading:
```ts [server/mcp/resources/readme.ts]
export default defineMcpResource({
name: 'readme',
description: 'Project README file',
file: 'README.md' // Relative to project root
})
```
For dynamic resources, you can use a custom handler:
```ts [server/mcp/resources/nuxt-documentation-pages.ts]
import { queryCollection } from '@nuxt/content/server'
export default defineMcpResource({
uri: 'resource://nuxt-com/documentation-pages',
description: 'Complete list of available Nuxt documentation pages (defaults to v4.x)',
cache: '1h',
async handler(uri: URL) {
const event = useEvent()
const allDocs = await queryCollection(event, 'docsv4')
.select('title', 'path', 'description')
.all()
const result = allDocs.map(doc => ({
title: doc.title,
path: doc.path,
description: doc.description,
version: '4.x',
url: `https://nuxt.com${doc.path}`
}))
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(result, null, 2)
}]
}
}
})
```
Unlike tools which are model-controlled, resources are application-driven, the host application determines how to incorporate them based on user needs, such as through UI elements for explicit selection or automatic context inclusion.
### Prompts: Reusable templates
Prompts are reusable templates with arguments that users can invoke. They return a conversation format that guides the AI through specific workflows:
```ts [server/mcp/prompts/find-documentation-for-topic.ts]
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'
export default defineMcpPrompt({
description: 'Find the best Nuxt documentation for a specific topic or feature',
inputSchema: {
topic: z.string().describe('Describe what you want to learn about'),
version: z.enum(['3.x', '4.x']).optional().describe('Documentation version to search')
},
async handler({ topic, version = '4.x' }) {
const event = useEvent()
const docsVersion = version === '4.x' ? 'docsv4' : 'docsv3'
const allDocs = await queryCollection(event, docsVersion)
.select('title', 'path', 'description')
.all()
const allPages = allDocs?.map(doc => ({
title: doc.title,
path: doc.path,
description: doc.description,
url: `https://nuxt.com${doc.path}`
})) || []
return {
messages: [{
role: 'user' as const,
content: {
type: 'text' as const,
text: `Help me find the best Nuxt documentation for this topic: "${topic}". Here are all available documentation pages: ${JSON.stringify(allPages, null, 2)}`
}
}]
}
}
})
```
Prompts differ from tools in that they are user-invoked and return conversation messages, while tools are model-controlled and return structured data.
### Built-in helpers
The module provides several auto-imported helpers to simplify common patterns:
- **defineMcpTool**, **defineMcpResource**, **defineMcpPrompt**: Define your MCP primitives
- **jsonResult(data)**: Format a JSON response for tools
- **errorResult(message)**: Return an error response from tools
### Using Nuxt server utilities
To use Nuxt server utilities like `useEvent()` in your handlers, enable `asyncContext` in your Nuxt config:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
experimental: {
asyncContext: true
}
})
```
Then you can access the H3 event and use Nuxt server composables like `queryCollection` from [Nuxt Content](https://content.nuxt.com).
## Building your own MCP server
Ready to build an MCP server for your own application? With the Nuxt MCP Toolkit, it takes just a few minutes.
### 1. Install the module
```bash [Terminal]
npx nuxi module add mcp-toolkit
```
### 2. Configure the module
Add basic configuration to your Nuxt config:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxtjs/mcp-toolkit'],
mcp: {
name: 'my-app'
}
})
```
### 3. Create your first tool
Create a file in `server/mcp/tools/`:
```ts [server/mcp/tools/search.ts]
import { z } from 'zod'
export default defineMcpTool({
description: 'Search through my content',
inputSchema: {
query: z.string().describe('Search query')
},
async handler({ query }) {
// Your search logic here
const results = await searchContent(query)
return jsonResult(results)
}
})
```
That's it! Your MCP server is now accessible at `https://your-domain.com/mcp`.
### 4. Add resources and prompts (optional)
You can also add resources and prompts following the same pattern:
```ts [server/mcp/resources/readme.ts]
export default defineMcpResource({
name: 'readme',
description: 'Project README file',
file: 'README.md'
})
```
For more advanced configuration options, check out the [Nuxt MCP Toolkit documentation](https://mcp-toolkit.nuxt.dev).
## Get started with the Nuxt MCP server
Ready to experience the power of MCP with Nuxt? Our server is already live and provides access to all Nuxt documentation, blog posts, and deployment guides.
### Quick install for Cursor
The easiest way to get started is with Cursor's one-click installation:
### Other AI assistants
The Nuxt MCP server works with Claude Desktop, Windsurf, Visual Studio Code, ChatGPT, and many other MCP-compatible AI assistants. For complete setup instructions for all platforms, check out our [MCP documentation](/docs/4.x/guide/ai/mcp).
We encourage you to build MCP servers for your own applications. Whether it's documentation, API references, or domain-specific knowledge, MCP makes it easy for AI assistants to provide accurate, helpful information to your users.
The complete source code for our MCP server is available on [GitHub](https://github.com/nuxt/nuxt.com) in the [`server/mcp/`](https://github.com/nuxt/nuxt.com/tree/main/server/mcp) directory. Feel free to use it as inspiration for your own implementation!
---
# Source: https://nuxt.com/raw/docs/3.x/migration/bundling.md
# Source: https://nuxt.com/raw/docs/4.x/migration/bundling.md
# Build Tooling
> Learn how to migrate from Nuxt 2 to Nuxt 3 build tooling.
We use the following build tools by default:
- [Vite](https://vite.dev) or [webpack](https://webpack.js.org)
- [Rollup](https://rollupjs.org)
- [PostCSS](https://postcss.org)
- [esbuild](https://esbuild.github.io)
For this reason, most of your previous `build` configuration in `nuxt.config` will now be ignored, including any custom babel configuration.
If you need to configure any of Nuxt's build tools, you can do so in your `nuxt.config`, using the new top-level `vite`, `webpack` and `postcss` keys.
In addition, Nuxt ships with TypeScript support.
## Steps
1. Remove `@nuxt/typescript-build` and `@nuxt/typescript-runtime` from your dependencies and modules.
2. Remove any unused babel dependencies from your project.
3. Remove any explicit core-js dependencies.
4. Migrate `require` to `import`.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/call-once.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/call-once.md
# callOnce
> Run a given function or block of code once during SSR or CSR.
This utility is available since [Nuxt v3.9](/blog/v3-9).
## Purpose
The `callOnce` function is designed to execute a given function or block of code only once during:
- server-side rendering but not hydration
- client-side navigation
This is useful for code that should be executed only once, such as logging an event or setting up a global state.
## Usage
The default mode of `callOnce` is to run code only once. For example, if the code runs on the server it won't run again on the client. It also won't run again if you `callOnce` more than once on the client, for example by navigating back to this page.
```vue [app/app.vue]
```
It is also possible to run on every navigation while still avoiding the initial server/client double load. For this, it is possible to use the `navigation` mode:
```vue [app/app.vue]
```
`navigation` mode is available since [Nuxt v3.15](/blog/v3-15).
`callOnce` is useful in combination with the [Pinia module](/modules/pinia) to call store actions.
Note that `callOnce` doesn't return anything. You should use [`useAsyncData`](/docs/4.x/api/composables/use-async-data) or [`useFetch`](/docs/4.x/api/composables/use-fetch) if you want to do data fetching during SSR.
`callOnce` is a composable meant to be called directly in a setup function, plugin, or route middleware, because it needs to add data to the Nuxt payload to avoid re-calling the function on the client when the page hydrates.
## Type
```ts [Signature]
export function callOnce (key?: string, fn?: (() => any | Promise), options?: CallOnceOptions): Promise
export function callOnce (fn?: (() => any | Promise), options?: CallOnceOptions): Promise
type CallOnceOptions = {
/**
* Execution mode for the callOnce function
* @default 'render'
*/
mode?: 'navigation' | 'render'
}
```
## Parameters
- `key`: A unique key ensuring that the code is run once. If you do not provide a key, then a key that is unique to the file and line number of the instance of `callOnce` will be generated for you.
- `fn`: The function to run once. It can be asynchronous.
- `options`: Setup the mode, either to re-execute on navigation (`navigation`) or just once for the lifetime of the app (`render`). Defaults to `render`.
- `render`: Executes once during initial render (either SSR or CSR) - Default mode
- `navigation`: Executes once during initial render and once per subsequent client-side navigation
---
# Source: https://nuxt.com/raw/docs/3.x/community/changelog.md
# Source: https://nuxt.com/raw/docs/4.x/community/changelog.md
# Releases
> Discover the latest releases of Nuxt & Nuxt official modules.
Nuxt framework releases.
Nuxt CLI (`@nuxt/cli`) releases.
Nuxt A11y releases.
Nuxt Content releases.
Nuxt DevTools releases.
Nuxt Fonts releases.
Nuxt Hints releases.
Nuxt Image releases.
Nuxt Scripts releases.
Nuxt UI releases.
Discover the `nuxt` organization on GitHub
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/cleanup.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/cleanup.md
# nuxt cleanup
> Remove common generated Nuxt files and caches.
```bash [Terminal]
npx nuxt cleanup [ROOTDIR] [--cwd=]
```
The `cleanup` command removes common generated Nuxt files and caches, including:
- `.nuxt`
- `.output`
- `node_modules/.vite`
- `node_modules/.cache`
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/clear-error.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/clear-error.md
# clearError
> The clearError composable clears all handled errors.
Within your pages, components, and plugins, you can use `clearError` to clear all errors and redirect the user.
**Parameters:**
- `options?: { redirect?: string }`
You can provide an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
```ts
// Without redirect
clearError()
// With redirect
clearError({ redirect: '/homepage' })
```
Errors are set in state using [`useError()`](/docs/4.x/api/composables/use-error). The `clearError` composable will reset this state and calls the `app:error:cleared` hook with the provided options.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/clear-nuxt-data.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/clear-nuxt-data.md
# clearNuxtData
> Delete cached data, error status and pending promises of useAsyncData and useFetch.
This method is useful if you want to invalidate the data fetching for another page.
## Type
```ts [Signature]
export function clearNuxtData (keys?: string | string[] | ((key: string) => boolean)): void
```
## Parameters
- `keys`: One or an array of keys that are used in [`useAsyncData`](/docs/4.x/api/composables/use-async-data) to delete their cached data. If no keys are provided, **all data** will be invalidated.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/clear-nuxt-state.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/clear-nuxt-state.md
# clearNuxtState
> Delete the cached state of useState.
This method is useful if you want to invalidate the state of `useState`.
## Type
```ts [Signature]
export function clearNuxtState (keys?: string | string[] | ((key: string) => boolean)): void
```
## Parameters
- `keys`: One or an array of keys that are used in [`useState`](/docs/4.x/api/composables/use-state) to delete their cached state. If no keys are provided, **all state** will be invalidated.
---
# Source: https://nuxt.com/raw/deploy/cleavr.md
# Cleavr
> Deploy your Nuxt Application to Cleavr infrastructure.
**Zero Configuration ✨**
Integration with this provider is possible with zero configuration, [learn more](https://nitro.unjs.io/deploy#zero-config-providers).
## Setup
**In your Cleavr.io panel:**
1. Provision a new server
2. Add a website, selecting **Nuxt 3** as the app type
3. In web app > settings > Code Repo, point to your project's code repository
4. In web app > settings > Environment variables, set `SERVER_PRESET=cleavr`
You're now all set to deploy your project!
## Learn more
Head over **Nitro documentation** to learn more about the cleavr deployment preset.
---
# Source: https://nuxt.com/raw/deploy/clever-cloud.md
# Clever Cloud
> Deploy your Nuxt Application to Clever Cloud infrastructure.
Nuxt supports deploying on [Clever Cloud](https://www.clever-cloud.com/) with minimal configuration.
## Deploy Clever Cloud from the Console
To deploy your Nuxt project to Clever Cloud, you will need to create a **new application**. The application wizard will walk you through the necessary configuration steps.
1. From the lateral menubar, click **Create > An application**
2. Choose how to deploy: **Create an application from a local repository** or **Create an application from a GitHub repository**
3. Select a **Node.js** application, or a **static one**.
4. Set up the minimal size for your instance and scalability options. Nuxt app must be deployed with a minimum size of **XS** instance for **Node.js** application and **nano** instance for **static one**. The build process, however, will need to be configured later with at least an M instance size to ensure it can handle the resource requirements. Depending on your project’s specifications and dependencies, you may need to adjust further as you monitor the metrics from the **Overview** page.
5. Select a **region** to deploy your instance.
6. Skip connecting **Add-ons** to your Clever application unless you’re using a database.
7. Inject **environment variables**:
- For **Node.js**
```ini [npm]
CC_POST_BUILD_HOOK="npm run build"
CC_RUN_COMMAND="node .output/server/index.mjs"
```
```ini [yarn]
CC_POST_BUILD_HOOK="yarn build"
CC_RUN_COMMAND="node .output/server/index.mjs"
```
```ini [pnpm]
CC_POST_BUILD_HOOK="pnpm build"
CC_RUN_COMMAND="node .output/server/index.mjs"
```
```ini [bun]
CC_POST_BUILD_HOOK="bun build"
CC_RUN_COMMAND="node .output/server/index.mjs"
```
- For a **static application**
If [`ssr: false` is set in `nuxt.config.ts`](https://nuxt.com/docs/4.x/getting-started/deployment#static-hosting) **or** if your project contains dynamic routes that cannot be pre-rendered, you should :
1. Use a **Static Apache** application
2. Create a [`.htaccess`](https://www.clever.cloud/developers/doc/applications/static-apache/#serving-indexhtml-for-spa-single-page-application-routers) file that redirects all routes to `index.html` to ensure proper routing for your SPA.
Otherwise, you can use the default **Static HTML** application.
```ini [npm]
CC_WEBROOT=/.output/public
CC_OVERRIDE_BUILDCACHE=/.output/public
CC_PRE_BUILD_HOOK=npm install
CC_POST_BUILD_HOOK=npm run generate
```
```ini [yarn]
CC_WEBROOT=/.output/public
CC_OVERRIDE_BUILDCACHE=/.output/public
CC_PRE_BUILD_HOOK=yarn install
CC_POST_BUILD_HOOK=yarn generate
```
```ini [pnpm]
CC_WEBROOT=/.output/public
CC_OVERRIDE_BUILDCACHE=/.output/public
CC_PRE_BUILD_HOOK=pnpm install
CC_POST_BUILD_HOOK=pnpm generate
```
```ini [bun]
CC_WEBROOT=/.output/public
CC_OVERRIDE_BUILDCACHE=/.output/public
CC_PRE_BUILD_HOOK=bun install
CC_POST_BUILD_HOOK=bun generate
```
1. Navigate to the application **Information** menu and enable the **enable dedicated build instance** option on a minimal instance of type **M**.
2. **Deploy!** If you’re deploying from **GitHub**, your deployment should start automatically. If you’re using **Git**, show [this docs](https://www.clever-cloud.com/developers/doc/quickstart/#choose-how-to-deploy).
## Learn more
Clever Cloud documentation for deploying Nuxt
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/client-only.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/client-only.md
#
> Render components only in client-side with the component.
The `` component is used for purposely rendering a component only on client side.
The content of the default slot will be tree-shaken out of the server build. (This does mean that any CSS used by components within it may not be inlined when rendering the initial HTML.)
## Props
- `placeholderTag` | `fallbackTag`: specify a tag to be rendered server-side.
- `placeholder` | `fallback`: specify a content to be rendered server-side.
```vue
```
## Slots
- `#fallback`: specify a content to be rendered on the server and displayed until `` is mounted in the browser.
```vue [app/pages/example.vue]
Loading comments...
```
## Examples
### Accessing HTML Elements
Components inside `` are rendered only after being mounted. To access the rendered elements in the DOM, you can watch a template ref:
```vue [app/pages/example.vue]
```
---
# Source: https://nuxt.com/raw/deploy/cloudflare.md
# Cloudflare
> Deploy your Nuxt Application to Cloudflare infrastructure.
## Cloudflare Pages
**Zero Configuration ✨**
Integration with Cloudflare Pages is possible with zero configuration, [learn more](https://nitro.unjs.io/deploy#zero-config-providers).
Checkout the [@nuxthub/core](/modules/hub) module to build full-stack Nuxt applications with Cloudflare, learn more on [hub.nuxt.com](https://hub.nuxt.com).
### Git Integration
If you use the GitHub/GitLab integration with Cloudflare Pages, **no configuration is required**. Pushing to your repository will automatically build your project and deploy it.
Nuxt will detect the environment to set the correct [Server/Nitro preset](https://nitro.unjs.io/deploy/providers/cloudflare).
To leverage server-side rendering on the edge, set the build command to: `nuxt build`
To statically generate your website, set the build command to: `nuxt generate`
### Route matching
On CloudFlare Pages, if an HTML file is found with a matching path to the current route requested, it will serve it. It will also redirect HTML pages to their extension-less counterparts: for instance, `/contact.html` will be redirected to `/contact`, and `/about/index.html` will be redirected to `/about/`.
To match Cloudflare [route matching](https://developers.cloudflare.com/pages/configuration/serving-pages/#route-matching) rules, set the nitro option `autoSubfolderIndex` to `false`.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
nitro: {
prerender: {
autoSubfolderIndex: false
}
}
})
```
### Direct Upload
Alternatively, you can use [wrangler](https://github.com/cloudflare/workers-sdk) to upload your project to Cloudflare.
In this case, you will have to set the preset manually.
1. Build your project for Cloudflare Pages:
```bash [Terminal]
npx nuxi build --preset=cloudflare_pages
```
1. Deploy, it will ask you to create a project for the first time:
```bash [Terminal]
npx wrangler pages deploy dist/
```
## Learn more
Head over **Nitro documentation** to learn more about the Cloudflare deployment preset.
Head over **CloudFlare Pages** documentation to learn more about it.
## Templates
A todos application with user authentication, SSR and Cloudflare D1.
An editable website with universal rendering based on Cloudflare KV.
Web application that lets you to draw and share your drawings with the world, with Cloudflare R2 & AI.
An image gallery to upload, edit and share your images to the world, with Cloudflare R2.
## Learn more
Head over **Nitro documentation** to learn more about the cloudflare deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/code-style.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/code-style.md
# Code Style
> Nuxt supports ESLint out of the box
## ESLint
The recommended approach for Nuxt is to enable ESLint support using the [`@nuxt/eslint`](https://eslint.nuxt.com/packages/module) module, that will setup project-aware ESLint configuration for you.
The module is designed for the [new ESLint flat config format](https://eslint.org/docs/latest/use/configure/configuration-files) which is the [default format since ESLint v9](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/). If you are using the legacy `.eslintrc` config, you will need to [configure manually with `@nuxt/eslint-config`](https://eslint.nuxt.com/packages/config#customizing-the-config). We highly recommend you to migrate over the flat config to be future-proof.
## Quick Setup
```bash
npx nuxt module add eslint
```
Start your Nuxt app, a `eslint.config.mjs` file will be generated under your project root. You can customize it as needed.
You can learn more about the module and customizations in [Nuxt ESLint's documentation](https://eslint.nuxt.com/packages/module).
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/compatibility.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/compatibility.md
# Compatibility
> Nuxt Kit provides a set of utilities to help you check the compatibility of your modules with different Nuxt versions.
Nuxt Kit utilities can be used in Nuxt 3, Nuxt 2 with Bridge and even Nuxt 2 without Bridge. To make sure your module is compatible with all versions, you can use the `checkNuxtCompatibility`, `assertNuxtCompatibility` and `hasNuxtCompatibility` functions. They will check if the current Nuxt version meets the constraints you provide. Also you can use `isNuxt2`, `isNuxt3` and `getNuxtVersion` functions for more granular checks.
## `checkNuxtCompatibility`
Checks if constraints are met for the current Nuxt version. If not, returns an array of messages. Nuxt 2 version also checks for `bridge` support.
### Usage
```tstwoslash
import { checkNuxtCompatibility, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
async setup (_options, nuxt) {
const issues = await checkNuxtCompatibility({ nuxt: '^2.16.0' }, nuxt)
if (issues.length) {
console.warn('Nuxt compatibility issues found:\n' + issues.toString())
} else {
// do something
}
},
})
```
### Type
```ts
function checkNuxtCompatibility (constraints: NuxtCompatibility, nuxt?: Nuxt): Promise
```
### Parameters
**constraints**: Version and builder constraints to check against. It accepts the following properties:
Property
Type
Required
Description
nuxt
string
false
Nuxt version in semver format. Versions may be defined in Node.js way, for example:
>=2.15.0 <3.0.0
.
bridge
Record
<
string
,
string
|
false
>
false
Specifies version constraints or disables compatibility for specific Nuxt builders like
vite
,
webpack
, or
rspack
. Use
false
to disable.
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
## `assertNuxtCompatibility`
Asserts that constraints are met for the current Nuxt version. If not, throws an error with the list of issues as string.
### Type
```tstwoslash
// @errors: 2391
import type { Nuxt, NuxtCompatibility } from '@nuxt/schema'
// ---cut---
function assertNuxtCompatibility (constraints: NuxtCompatibility, nuxt?: Nuxt): Promise
```
### Parameters
**constraints**: Version and builder constraints to check against. Refer to the [constraints table in `checkNuxtCompatibility`](/docs/4.x/api/kit/compatibility#parameters) for details.
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
## `hasNuxtCompatibility`
Checks if constraints are met for the current Nuxt version. Return `true` if all constraints are met, otherwise returns `false`. Nuxt 2 version also checks for `bridge` support.
### Usage
```tstwoslash
import { defineNuxtModule, hasNuxtCompatibility } from '@nuxt/kit'
export default defineNuxtModule({
async setup (_options, nuxt) {
const usingNewPostcss = await hasNuxtCompatibility({ nuxt: '^2.16.0' }, nuxt)
if (usingNewPostcss) {
// do something
} else {
// do something else
}
},
})
```
### Type
```ts
function hasNuxtCompatibility (constraints: NuxtCompatibility, nuxt?: Nuxt): Promise
```
### Parameters
**constraints**: Version and builder constraints to check against. Refer to the [constraints table in `checkNuxtCompatibility`](/docs/4.x/api/kit/compatibility#parameters) for details.
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
## `isNuxtMajorVersion`
Check if current Nuxt instance is of specified major version
### Usage
```tstwoslash
import { defineNuxtModule, isNuxtMajorVersion } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
if (isNuxtMajorVersion(3)) {
// do something for Nuxt 3
} else {
// do something else for other versions
}
},
})
```
### Type
```ts
function isNuxtMajorVersion (major: number, nuxt?: Nuxt): boolean
```
### Parameters
**major**: Major version to check against.
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
## `isNuxt3`
Checks if the current Nuxt version is 3.x.
Use `isNuxtMajorVersion(2, nuxt)` instead. This may be removed in @nuxt/kit v5 or a future major version.
### Type
```ts
function isNuxt3 (nuxt?: Nuxt): boolean
```
### Parameters
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
## `isNuxt2`
Checks if the current Nuxt version is 2.x.
Use `isNuxtMajorVersion(2, nuxt)` instead. This may be removed in @nuxt/kit v5 or a future major version.
### Type
```ts
function isNuxt2 (nuxt?: Nuxt): boolean
```
### Parameters
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
## `getNuxtVersion`
Returns the current Nuxt version.
### Type
```ts
function getNuxtVersion (nuxt?: Nuxt): string
```
### Parameters
**nuxt**: Nuxt instance. If not provided, it will be retrieved from the context via `useNuxt()` call.
---
# Source: https://nuxt.com/raw/docs/3.x/migration/component-options.md
# Source: https://nuxt.com/raw/docs/4.x/migration/component-options.md
# Component Options
> Learn how to migrate from Nuxt 2 components options to Nuxt 3 composables.
## `asyncData` and `fetch`
Nuxt 3 provides new options for [fetching data from an API](/docs/4.x/getting-started/data-fetching).
### Isomorphic Fetch
In Nuxt 2 you might use `@nuxtjs/axios` or `@nuxt/http` to fetch your data - or just the polyfilled global `fetch`.
In Nuxt 3 you can use a globally available `fetch` method that has the same API as [the Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) or [`$fetch`](/docs/4.x/api/utils/dollarfetch) method which is using [unjs/ofetch](https://github.com/unjs/ofetch). It has a number of benefits, including:
1. It will handle 'smartly' making [direct API calls](/docs/4.x/guide/concepts/server-engine#direct-api-calls) if it's running on the server, or making a client-side call to your API if it's running on the client. (It can also handle calling third-party APIs.)
2. Plus, it comes with convenience features including automatically parsing responses and stringifying data.
You can read more [about direct API calls](/docs/4.x/guide/concepts/server-engine#direct-api-calls) or [fetching data](/docs/4.x/getting-started/data-fetching).
### Composables
Nuxt 3 provides new composables for fetching data: [`useAsyncData`](/docs/4.x/api/composables/use-async-data) and `useFetch`. They each have 'lazy' variants (`useLazyAsyncData` and `useLazyFetch`), which do not block client-side navigation.
In Nuxt 2, you'd fetch your data in your component using a syntax similar to:
```ts
export default {
async asyncData ({ params, $http }) {
const post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
},
// or alternatively
fetch () {
this.post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
},
}
```
Within your methods and templates, you could use the `post` variable similar how you'd use any other piece of data provided by your component.
With Nuxt 3, you can perform this data fetching using composables in your `setup()` method or `
```
You can now use `post` inside of your Nuxt 3 template, or call `refresh` to update the data.
Despite the names, [`useFetch`](/docs/4.x/api/composables/use-fetch) is not a direct replacement of the `fetch()` hook. Rather, [`useAsyncData`](/docs/4.x/api/composables/use-async-data) replaces both hooks and is more customizable; it can do more than simply fetching data from an endpoint. [`useFetch`](/docs/4.x/api/composables/use-fetch) is a convenience wrapper around [`useAsyncData`](/docs/4.x/api/composables/use-async-data) for simply fetching data from an endpoint.
### Migration
1. Replace the `asyncData` hook with [`useAsyncData`](/docs/4.x/api/composables/use-async-data) or [`useFetch`](/docs/4.x/api/composables/use-fetch) in your page/component.
2. Replace the `fetch` hook with [`useAsyncData`](/docs/4.x/api/composables/use-async-data) or [`useFetch`](/docs/4.x/api/composables/use-fetch) in your component.
## `head`
## `key`
You can now define a key within the [`definePageMeta`](/docs/4.x/api/utils/define-page-meta) compiler macro.
```diff [app/pages/index.vue]
-
```
## `layout`
## `loading`
This feature is not yet supported in Nuxt 3.
## `middleware`
## `scrollToTop`
This feature is not yet supported in Nuxt 3. If you want to overwrite the default scroll behavior of `vue-router`, you can do so in an `~/router.options.ts` (see [docs](/docs/4.x/guide/recipes/custom-routing#router-options)) for more info.
Similar to `key`, specify it within the [`definePageMeta`](/docs/4.x/api/utils/define-page-meta) compiler macro.
```diff [app/pages/index.vue]
-
```
## `transition`
## `validate`
The validate hook in Nuxt 3 only accepts a single argument, the `route`. Just as in Nuxt 2, you can return a boolean value. If you return false and another match can't be found, this will mean a 404. You can also directly return an object with `status`/`statusText` to respond immediately with an error (other matches will not be checked).
```diff [app/pages/users/[id].vue]
-
```
## `watchQuery`
This is not supported in Nuxt 3. Instead, you can directly use a watcher to trigger refetching data.
```vue [app/pages/users/[id].vue]
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/components.md
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/components.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/components.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/components.md
# components
> The components/ directory is where you put all your Vue components.
Nuxt automatically imports any components in this directory (along with components that are registered by any modules you may be using).
```bash [Directory Structure]
-| components/
---| AppHeader.vue
---| AppFooter.vue
```
```html [app/app.vue]
```
## Component Names
If you have a component in nested directories such as:
```bash [Directory Structure]
-| components/
---| base/
-----| foo/
-------| Button.vue
```
... then the component's name will be based on its own path directory and filename, with duplicate segments being removed. Therefore, the component's name will be:
```html
```
For clarity, we recommend that the component's filename matches its name. So, in the example above, you could rename `Button.vue` to be `BaseFooButton.vue`.
If you want to auto-import components based only on its name, not path, then you need to set `pathPrefix` option to `false` using extended form of the configuration object:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
components: [
{
path: '~/components',
pathPrefix: false, // [!code ++]
},
],
})
```
This registers the components using the same strategy as used in Nuxt 2. For example, `~/components/Some/MyComponent.vue` will be usable as `` and not ``.
## Dynamic Components
If you want to use the Vue `` syntax, you need to use the `resolveComponent` helper provided by Vue or import the component directly from `#components` and pass it into `is` prop.
For example:
```vue [app/pages/index.vue]
```
If you are using `resolveComponent` to handle dynamic components, make sure not to insert anything but the name of the component, which must be a literal string and not be or contain a variable. The string is statically analyzed at the compilation step.
Alternatively, though not recommended, you can register all your components globally, which will create async chunks for all your components and make them available throughout your application.
```diff
export default defineNuxtConfig({
components: {
+ global: true,
+ dirs: ['~/components']
},
})
```
You can also selectively register some components globally by placing them in a `~/components/global` directory, or by using a `.global.vue` suffix in the filename. As noted above, each global component is rendered in a separate chunk, so be careful not to overuse this feature.
The `global` option can also be set per component directory.
## Dynamic Imports
To dynamically import a component (also known as lazy-loading a component) all you need to do is add the `Lazy` prefix to the component's name. This is particularly useful if the component is not always needed.
By using the `Lazy` prefix you can delay loading the component code until the right moment, which can be helpful for optimizing your JavaScript bundle size.
```vue [app/pages/index.vue]
Mountains
```
## Delayed (or Lazy) Hydration
Lazy components are great for controlling the chunk sizes in your app, but they don't always enhance runtime performance, as they still load eagerly unless conditionally rendered. In real-world applications, some pages may include a lot of content and a lot of components, and most of the time not all of them need to be interactive as soon as the page is loaded. Having them all load eagerly can negatively impact performance.
In order to optimize your app, you may want to delay the hydration of some components until they're visible, or until the browser is done with more important tasks.
Nuxt supports this using lazy (or delayed) hydration, allowing you to control when components become interactive.
### Hydration Strategies
Nuxt provides a range of built-in hydration strategies. Only one strategy can be used per lazy component.
Any prop change on a lazily hydrated component will trigger hydration immediately. (e.g., changing a prop on a component with `hydrate-never` will cause it to hydrate)
Currently Nuxt's built-in lazy hydration only works in single-file components (SFCs), and requires you to define the prop in the template (rather than spreading an object of props via `v-bind`). It also does not work with direct imports from `#components`.
#### `hydrate-on-visible`
Hydrates the component when it becomes visible in the viewport.
```vue [app/pages/index.vue]
```
Read more about the options for `hydrate-on-visible`.
Under the hood, this uses Vue's built-in [`hydrateOnVisible` strategy](https://vuejs.org/guide/components/async#hydrate-on-visible).
#### `hydrate-on-idle`
Hydrates the component when the browser is idle. This is suitable if you need the component to load as soon as possible, but not block the critical rendering path.
You can also pass a number which serves as a max timeout.
```vue [app/pages/index.vue]
```
Under the hood, this uses Vue's built-in [`hydrateOnIdle` strategy](https://vuejs.org/guide/components/async#hydrate-on-idle).
#### `hydrate-on-interaction`
Hydrates the component after a specified interaction (e.g., click, mouseover).
```vue [app/pages/index.vue]
```
If you do not pass an event or list of events, it defaults to hydrating on `pointerenter`, `click` and `focus`.
Under the hood, this uses Vue's built-in [`hydrateOnInteraction` strategy](https://vuejs.org/guide/components/async#hydrate-on-interaction).
#### `hydrate-on-media-query`
Hydrates the component when the window matches a media query.
```vue [app/pages/index.vue]
```
Under the hood, this uses Vue's built-in [`hydrateOnMediaQuery` strategy](https://vuejs.org/guide/components/async#hydrate-on-media-query).
#### `hydrate-after`
Hydrates the component after a specified delay (in milliseconds).
```vue [app/pages/index.vue]
```
#### `hydrate-when`
Hydrates the component based on a boolean condition.
```vue [app/pages/index.vue]
```
#### `hydrate-never`
Never hydrates the component.
```vue [app/pages/index.vue]
```
### Listening to Hydration Events
All delayed hydration components emit a `@hydrated` event when they are hydrated.
```vue [app/pages/index.vue]
```
### Caveats and Best Practices
Delayed hydration can offer performance benefits, but it's essential to use it correctly:
1. **Prioritize In-Viewport Content:** Avoid delayed hydration for critical, above-the-fold content. It's best suited for content that isn't immediately needed.
2. **Conditional Rendering:** When using `v-if="false"` on a lazy component, you might not need delayed hydration. You can just use a normal lazy component.
3. **Shared State:** Be mindful of shared state (`v-model`) across multiple components. Updating the model in one component can trigger hydration in all components bound to that model.
4. **Use Each Strategy's Intended Use Case:** Each strategy is optimized for a specific purpose.
- `hydrate-when` is best for components that might not always need to be hydrated.
- `hydrate-after` is for components that can wait a specific amount of time.
- `hydrate-on-idle` is for components that can be hydrated when the browser is idle.
5. **Avoid hydrate-never on interactive components:** If a component requires user interaction, it should not be set to never hydrate.
## Direct Imports
You can also explicitly import components from `#components` if you want or need to bypass Nuxt's auto-importing functionality.
```vue [app/pages/index.vue]
Mountains
Home
```
## Custom Directories
By default, only the `~/components` directory is scanned. If you want to add other directories, or change how the components are scanned within a subfolder of this directory, you can add additional directories to the configuration:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
components: [
// ~/calendar-module/components/event/Update.vue =>
{ path: '~/calendar-module/components' },
// ~/user-module/components/account/UserDeleteDialog.vue =>
{ path: '~/user-module/components', pathPrefix: false },
// ~/components/special-components/Btn.vue =>
{ path: '~/components/special-components', prefix: 'Special' },
// It's important that this comes last if you have overrides you wish to apply
// to sub-directories of `~/components`.
//
// ~/components/Btn.vue =>
// ~/components/base/Btn.vue =>
'~/components',
],
})
```
Any nested directories need to be added first as they are scanned in order.
## npm Packages
If you want to auto-import components from an npm package, you can use [`addComponent`](/docs/4.x/api/kit/components#addcomponent) in a [local module](/docs/4.x/directory-structure/modules) to register them.
```ts [~/modules/register-component.ts]twoslash
import { addComponent, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
// import { MyComponent as MyAutoImportedComponent } from 'my-npm-package'
addComponent({
name: 'MyAutoImportedComponent',
export: 'MyComponent',
filePath: 'my-npm-package',
})
},
})
```
```vue [app/app.vue]
```
## Component Extensions
By default, any file with an extension specified in the [extensions key of `nuxt.config.ts`](/docs/4.x/api/nuxt-config#extensions) is treated as a component.
If you need to restrict the file extensions that should be registered as components, you can use the extended form of the components directory declaration and its `extensions` key:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
components: [
{
path: '~/components',
extensions: ['.vue'], // [!code ++]
},
],
})
```
## Client Components
If a component is meant to be rendered only client-side, you can add the `.client` suffix to your component.
```bash [Directory Structure]
| components/
--| Comments.client.vue
```
```vue [app/pages/example.vue]
```
This feature only works with Nuxt auto-imports and `#components` imports. Explicitly importing these components from their real paths does not convert them into client-only components.
`.client` components are rendered only after being mounted. To access the rendered template using `onMounted()`, add `await nextTick()` in the callback of the `onMounted()` hook.
You can also achieve a similar result with the `` component.
## Server Components
Server components allow server-rendering individual components within your client-side apps. It's possible to use server components within Nuxt, even if you are generating a static site. That makes it possible to build complex sites that mix dynamic components, server-rendered HTML and even static chunks of markup.
Server components can either be used on their own or paired with a [client component](/docs/4.x/directory-structure/app/components#paired-with-a-client-component).
Read Daniel Roe's guide to Nuxt Server Components.
### Standalone server components
Standalone server components will always be rendered on the server, also known as Islands components.
When their props update, this will result in a network request that will update the rendered HTML in-place.
Server components are currently experimental and in order to use them, you need to enable the 'component islands' feature in your nuxt.config:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
componentIslands: true,
},
})
```
Now you can register server-only components with the `.server` suffix and use them anywhere in your application automatically.
```bash [Directory Structure]
-| components/
---| HighlightedMarkdown.server.vue
```
```vue [app/pages/example.vue]
```
Server-only components use [``](/docs/4.x/api/components/nuxt-island) under the hood, meaning that `lazy` prop and `#fallback` slot are both passed down to it.
Server components (and islands) must have a single root element. (HTML comments are considered elements as well.)
Props are passed to server components via URL query parameters, and are therefore limited by the possible length of a URL, so be careful not to pass enormous amounts of data to server components via props.
Be careful when nesting islands within other islands as each island adds some extra overhead.
Most features for server-only components and island components, such as slots and client components, are only available for single file components.
#### Client components within server components
This feature needs `experimental.componentIslands.selectiveClient` within your configuration to be true.
You can partially hydrate a component by setting a `nuxt-client` attribute on the component you wish to be loaded client-side.
```vue [app/components/ServerWithClient.vue]
```
This only works within a server component. Slots for client components are working only with `experimental.componentIsland.selectiveClient` set to `'deep'` and since they are rendered server-side, they are not interactive once client-side.
#### Server Component Context
When rendering a server-only or island component, `` makes a fetch request which comes back with a `NuxtIslandResponse`. (This is an internal request if rendered on the server, or a request that you can see in the network tab if it's rendering on client-side navigation.)
This means:
- A new Vue app will be created server-side to create the `NuxtIslandResponse`.
- A new 'island context' will be created while rendering the component.
- You can't access the 'island context' from the rest of your app and you can't access the context of the rest of your app from the island component. In other words, the server component or island is *isolated* from the rest of your app.
- Your plugins will run again when rendering the island, unless they have `env: { islands: false }` set (which you can do in an object-syntax plugin).
Route middleware does not run when rendering island components. Middleware is a routing concept that applies to pages, not components, and is not designed to control component rendering.
Within an island component, you can access its island context through `nuxtApp.ssrContext.islandContext`. Note that while island components are still marked as experimental, the format of this context may change.
Slots can be interactive and are wrapped within a `
` with `display: contents;`
### Paired with a Client component
In this case, the `.server` + `.client` components are two 'halves' of a component and can be used in advanced use cases for separate implementations of a component on server and client side.
```bash [Directory Structure]
-| components/
---| Comments.client.vue
---| Comments.server.vue
```
```vue [app/pages/example.vue]
```
## Built-In Nuxt Components
There are a number of components that Nuxt provides, including `` and ``. You can read more about them in the API documentation.
## Library Authors
Making Vue component libraries with automatic tree-shaking and component registration is super easy. ✨
You can use the [`addComponentsDir`](/docs/4.x/api/kit/components#addcomponentsdir) method provided from the `@nuxt/kit` to register your components directory in your Nuxt module.
Imagine a directory structure like this:
```bash [Directory Structure]
-| node_modules/
---| awesome-ui/
-----| components/
-------| Alert.vue
-------| Button.vue
-----| nuxt.ts
-| pages/
---| index.vue
-| nuxt.config.ts
```
Then in `awesome-ui/nuxt.ts` you can use the `addComponentsDir` hook:
```tstwoslash
import { addComponentsDir, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
const resolver = createResolver(import.meta.url)
// Add ./components dir to the list
addComponentsDir({
path: resolver.resolve('./components'),
prefix: 'awesome',
})
},
})
```
That's it! Now in your project, you can import your UI library as a Nuxt module in your `nuxt.config` file:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
modules: ['awesome-ui/nuxt'],
})
```
... and directly use the module components (prefixed with `awesome-`) in our `app/pages/index.vue`:
```vue
My UI button!
Here's an alert!
```
It will automatically import the components only if used and also support HMR when updating your components in `node_modules/awesome-ui/components/`.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/composables.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/composables.md
# composables
> Use the composables/ directory to auto-import your Vue composables into your application.
## Usage
**Method 1:** Using named export
```ts [app/composables/useFoo.ts]
export const useFoo = () => {
return useState('foo', () => 'bar')
}
```
**Method 2:** Using default export
```ts [app/composables/use-foo.ts or composables/useFoo.ts]
// It will be available as useFoo() (camelCase of file name without extension)
export default function () {
return useState('foo', () => 'bar')
}
```
**Usage:** You can now use auto imported composable in `.js`, `.ts` and `.vue` files
```vue [app/app.vue]
{{ foo }}
```
The `app/composables/` directory in Nuxt does not provide any additional reactivity capabilities to your code. Instead, any reactivity within composables is achieved using Vue's Composition API mechanisms, such as ref and reactive. Note that reactive code is also not limited to the boundaries of the `app/composables/` directory. You are free to employ reactivity features wherever they're needed in your application.
## Types
Under the hood, Nuxt auto generates the file `.nuxt/imports.d.ts` to declare the types.
Be aware that you have to run [`nuxt prepare`](/docs/4.x/api/commands/prepare), [`nuxt dev`](/docs/4.x/api/commands/dev) or [`nuxt build`](/docs/4.x/api/commands/build) in order to let Nuxt generate the types.
If you create a composable without having the dev server running, TypeScript will throw an error, such as `Cannot find name 'useBar'.`
## Examples
### Nested Composables
You can use a composable within another composable using auto imports:
```ts [app/composables/test.ts]
export const useFoo = () => {
const nuxtApp = useNuxtApp()
const bar = useBar()
}
```
### Access plugin injections
You can access [plugin injections](/docs/4.x/directory-structure/app/plugins#providing-helpers) from composables:
```ts [app/composables/test.ts]
export const useHello = () => {
const nuxtApp = useNuxtApp()
return nuxtApp.$hello
}
```
## How Files Are Scanned
Nuxt only scans files at the top level of the [`app/composables/` directory](/docs/4.x/directory-structure/app/composables), e.g.:
```bash [Directory Structure]
-| composables/
---| index.ts // scanned
---| useFoo.ts // scanned
---| nested/
-----| utils.ts // not scanned
```
Only `app/composables/index.ts` and `app/composables/useFoo.ts` would be searched for imports.
To get auto imports working for nested modules, you could either re-export them (recommended) or configure the scanner to include nested directories:
**Example:** Re-export the composables you need from the `app/composables/index.ts` file:
```ts [app/composables/index.ts]
// Enables auto import for this export
export { utils } from './nested/utils.ts'
```
**Example:** Scan nested directories inside the `app/composables/` folder:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
imports: {
dirs: [
// Scan top-level composables
'~/composables',
// ... or scan composables nested one level deep with a specific name and file extension
'~/composables/*/index.{ts,js,mjs,mts}',
// ... or scan all composables within given directory
'~/composables/**',
],
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/config-extends.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/config-extends.md
# Layers
> This example shows how to use the extends key in `nuxt.config.ts`.
This example shows how to use the `extends` key in `nuxt.config.ts` to use the `base/` directory as a base Nuxt application, and use its components, composables or config and override them if necessary.
---
# Source: https://nuxt.com/raw/docs/3.x/migration/configuration.md
# Source: https://nuxt.com/raw/docs/3.x/bridge/configuration.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/configuration.md
# Source: https://nuxt.com/raw/docs/4.x/migration/configuration.md
# Source: https://nuxt.com/raw/docs/4.x/bridge/configuration.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/configuration.md
# Configuration
> Nuxt is configured with sensible defaults to make you productive.
By default, Nuxt is configured to cover most use cases. The [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file can override or extend this default configuration.
## Nuxt Configuration
The [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file is located at the root of a Nuxt project and can override or extend the application's behavior.
A minimal configuration file exports the `defineNuxtConfig` function containing an object with your configuration. The `defineNuxtConfig` helper is globally available without import.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
// My Nuxt config
})
```
This file will often be mentioned in the documentation, for example to add custom scripts, register modules or change rendering modes.
Every option is described in the **Configuration Reference**.
You don't have to use TypeScript to build an application with Nuxt. However, it is strongly recommended to use the `.ts` extension for the `nuxt.config` file. This way you can benefit from hints in your IDE to avoid typos and mistakes while editing your configuration.
### Environment Overrides
You can configure fully typed, per-environment overrides in your nuxt.config
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
$production: {
routeRules: {
'/**': { isr: true },
},
},
$development: {
//
},
$env: {
staging: {
//
},
},
})
```
To select an environment when running a Nuxt CLI command, simply pass the name to the `--envName` flag, like so: `nuxt build --envName staging`.
To learn more about the mechanism behind these overrides, please refer to the `c12` documentation on [environment-specific configuration](https://github.com/unjs/c12?tab=readme-ov-file#environment-specific-configuration).
If you're authoring layers, you can also use the `$meta` key to provide metadata that you or the consumers of your layer might use.
### Environment Variables and Private Tokens
The `runtimeConfig` API exposes values like environment variables to the rest of your application. By default, these keys are only available server-side. The keys within `runtimeConfig.public` and `runtimeConfig.app` (which is used by Nuxt internally) are also available client-side.
Those values should be defined in `nuxt.config` and can be overridden using environment variables.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
runtimeConfig: {
// The private keys which are only available server-side
apiSecret: '123',
// Keys within public are also exposed client-side
public: {
apiBase: '/api',
},
},
})
```
```ini [.env]
# This will override the value of apiSecret
NUXT_API_SECRET=api_secret_token
```
These variables are exposed to the rest of your application using the [`useRuntimeConfig()`](/docs/4.x/api/composables/use-runtime-config) composable.
```vue [app/pages/index.vue]
```
## App Configuration
The `app.config.ts` file, located in the source directory (by default `app/`), is used to expose public variables that can be determined at build time. Contrary to the `runtimeConfig` option, these cannot be overridden using environment variables.
A minimal configuration file exports the `defineAppConfig` function containing an object with your configuration. The `defineAppConfig` helper is globally available without import.
```ts [app/app.config.ts]
export default defineAppConfig({
title: 'Hello Nuxt',
theme: {
dark: true,
colors: {
primary: '#ff0000',
},
},
})
```
These variables are exposed to the rest of your application using the [`useAppConfig`](/docs/4.x/api/composables/use-app-config) composable.
```vue [app/pages/index.vue]
```
## `runtimeConfig` vs. `app.config`
As stated above, `runtimeConfig` and `app.config` are both used to expose variables to the rest of your application. To determine whether you should use one or the other, here are some guidelines:
- `runtimeConfig`: Private or public tokens that need to be specified after build using environment variables.
- `app.config`: Public tokens that are determined at build time, website configuration such as theme variant, title and any project config that are not sensitive.
Feature
runtimeConfig
app.config
Client-side
Hydrated
Bundled
Environment variables
✅ Yes
❌ No
Reactive
✅ Yes
✅ Yes
Types support
✅ Partial
✅ Yes
Configuration per request
❌ No
✅ Yes
Hot module replacement
❌ No
✅ Yes
Non-primitive JS types
❌ No
✅ Yes
## External Configuration Files
Nuxt uses [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file as the single source of truth for configurations and skips reading external configuration files. During the course of building your project, you may have a need to configure those. The following table highlights common configurations and, where applicable, how they can be configured with Nuxt.
## Vue Configuration
### With Vite
If you need to pass options to `@vitejs/plugin-vue` or `@vitejs/plugin-vue-jsx`, you can do this in your `nuxt.config` file.
- `vite.vue` for `@vitejs/plugin-vue`. Check [available options](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue).
- `vite.vueJsx` for `@vitejs/plugin-vue-jsx`. Check [available options](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
vite: {
vue: {
customElement: true,
},
vueJsx: {
mergeProps: true,
},
},
})
```
### With webpack
If you use webpack and need to configure `vue-loader`, you can do this using `webpack.loaders.vue` key inside your `nuxt.config` file. The available options are [defined here](https://github.com/vuejs/vue-loader/blob/main/src/index.ts#L32-L62).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
webpack: {
loaders: {
vue: {
hotReload: true,
},
},
},
})
```
### Enabling Experimental Vue Features
You may need to enable experimental features in Vue, such as `propsDestructure`. Nuxt provides an easy way to do that in `nuxt.config.ts`, no matter which builder you are using:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
vue: {
propsDestructure: true,
},
})
```
#### experimental `reactivityTransform` migration from Vue 3.4 and Nuxt 3.9
Since Nuxt 3.9 and Vue 3.4, `reactivityTransform` has been moved from Vue to Vue Macros which has a [Nuxt integration](https://vue-macros.dev/guide/nuxt-integration.html).
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/content.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/content.md
# content
> Use the content/ directory to create a file-based CMS for your application.
[Nuxt Content](https://content.nuxt.com) reads the `content/` directory in your project and parses `.md`, `.yml`, `.csv` and `.json` files to create a file-based CMS for your application.
- Render your content with built-in components.
- Query your content with a MongoDB-like API.
- Use your Vue components in Markdown files with the MDC syntax.
- Automatically generate your navigation.
Learn more in **Nuxt Content** documentation.
## Enable Nuxt Content
Install the `@nuxt/content` module in your project as well as adding it to your `nuxt.config.ts` with one command:
```bash [Terminal]
npx nuxt module add content
```
## Create Content
Place your markdown files inside the `content/` directory:
```md [content/index.md]
# Hello Content
```
The module automatically loads and parses them.
## Render Content
To render content pages, add a [catch-all route](/docs/4.x/directory-structure/app/pages/#catch-all-route) using the [``](https://content.nuxt.com/docs/components/content-renderer) component:
```vue [app/pages/[...slug].vue]
```
## Documentation
Head over to [https://content.nuxt.com](https://content.nuxt.com) to learn more about the Content module features, such as how to build queries and use Vue components in your Markdown files with the MDC syntax.
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/context.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/context.md
# Context
> Nuxt Kit provides a set of utilities to help you work with context.
Nuxt modules allow you to enhance Nuxt's capabilities. They offer a structured way to keep your code organized and modular. If you're looking to break down your module into smaller components, Nuxt offers the `useNuxt` and `tryUseNuxt` functions. These functions enable you to conveniently access the Nuxt instance from the context without having to pass it as an argument.
When you're working with the `setup` function in Nuxt modules, Nuxt is already provided as the second argument. This means you can access it directly without needing to call `useNuxt()`.
## `useNuxt`
Get the Nuxt instance from the context. It will throw an error if Nuxt is not available.
### Usage
```ts
import { useNuxt } from '@nuxt/kit'
const setupSomeFeature = () => {
const nuxt = useNuxt()
// You can now use the nuxt instance
console.log(nuxt.options)
}
```
### Type
```tstwoslash
// @errors: 2391
import type { Nuxt } from '@nuxt/schema'
// ---cut---
function useNuxt (): Nuxt
```
### Return Value
The `useNuxt` function returns the Nuxt instance, which contains all the options and methods available in Nuxt.
Property
Type
Description
options
NuxtOptions
The resolved Nuxt configuration.
hooks
Hookable
The Nuxt hook system. Allows registering and listening to lifecycle events.
Shortcut for
nuxt.hooks.hook
. Registers a single callback for a specific lifecycle hook.
callHook
(name: string, ...args: any[]) => Promise
Shortcut for
nuxt.hooks.callHook
. Triggers a lifecycle hook manually and runs all registered callbacks.
addHooks
(configHooks: NestedHooks) => () => void
Shortcut for
nuxt.hooks.addHooks
. Registers multiple hooks at once.
### Examples
```ts [setupTranspilation.ts]twoslash
import { useNuxt } from '@nuxt/kit'
export const setupTranspilation = () => {
const nuxt = useNuxt()
if (nuxt.options.builder === '@nuxt/webpack-builder') {
nuxt.options.build.transpile ||= []
nuxt.options.build.transpile.push('xstate')
}
}
```
```ts [module.ts]twoslash
// @module: esnext
// @filename: setupTranspilation.ts
export const setupTranspilation = () => {}
// @filename: module.ts
import { defineNuxtModule } from '@nuxt/kit'
// ---cut---
import { setupTranspilation } from './setupTranspilation'
export default defineNuxtModule({
setup () {
setupTranspilation()
},
})
```
## `tryUseNuxt`
Get the Nuxt instance from the context. It will return `null` if Nuxt is not available.
### Usage
```tstwoslash
import { tryUseNuxt } from '@nuxt/kit'
function setupSomething () {
const nuxt = tryUseNuxt()
if (nuxt) {
// You can now use the nuxt instance
console.log(nuxt.options)
} else {
console.log('Nuxt is not available')
}
}
```
### Type
```tstwoslash
// @errors: 2391
import type { Nuxt } from '@nuxt/schema'
// ---cut---
function tryUseNuxt (): Nuxt | null
```
### Return Value
The `tryUseNuxt` function returns the Nuxt instance if available, or `null` if Nuxt is not available.
The Nuxt instance as described in the `useNuxt` section.
### Examples
```ts [requireSiteConfig.ts]twoslash
declare module 'nuxt/schema' {
interface NuxtOptions {
siteConfig: SiteConfig
}
}
// ---cut---
import { tryUseNuxt } from '@nuxt/kit'
interface SiteConfig {
title?: string
}
export const requireSiteConfig = (): SiteConfig => {
const nuxt = tryUseNuxt()
if (!nuxt) {
return {}
}
return nuxt.options.siteConfig
}
```
```ts [module.ts]twoslash
// @module: esnext
// @filename: requireSiteConfig.ts
interface SiteConfig {
title?: string
}
export const requireSiteConfig = (): SiteConfig => {
return {}
}
// @filename: module.ts
// ---cut---
import { defineNuxtModule, useNuxt } from '@nuxt/kit'
import { requireSiteConfig } from './requireSiteConfig'
export default defineNuxtModule({
setup (_, nuxt) {
const config = requireSiteConfig()
nuxt.options.app.head.title = config.title
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/community/contribution.md
# Source: https://nuxt.com/raw/docs/4.x/community/contribution.md
# Contribution
> Nuxt is a community project - and so we love contributions of all kinds! ❤️
There is a range of different ways you might be able to contribute to the Nuxt ecosystem.
## Ecosystem
The Nuxt ecosystem includes many different projects and organizations:
- [nuxt/](https://github.com/nuxt) - core repositories for the Nuxt framework itself. [**nuxt/nuxt**](https://github.com/nuxt/nuxt) contains the Nuxt framework (both versions 2 and 3).
- [nuxt-modules/](https://github.com/nuxt-modules) - community-contributed and maintained modules and libraries. There is a [process to migrate a module](/docs/4.x/guide/modules/ecosystem) to `nuxt-modules`. While these modules have individual maintainers, they are not dependent on a single person.
- [unjs/](https://github.com/unjs) - many of these libraries are used throughout the Nuxt ecosystem. They are designed to be universal libraries that are framework- and environment-agnostic. We welcome contributions and usage by other frameworks and projects.
## How To Contribute
### Triage Issues and Help Out in Discussions
Check out the issues and discussions for the project you want to help. For example, here are [the issues board](https://github.com/nuxt/nuxt/issues) and [discussions](https://github.com/nuxt/nuxt/discussions) for Nuxt. Helping other users, sharing workarounds, creating reproductions, or even poking into a bug a little bit and sharing your findings makes a huge difference.
### Creating an Issue
Thank you for taking the time to create an issue! ❤️
- **Reporting bugs**: Check out [our guide](/docs/4.x/community/reporting-bugs) for some things to do before opening an issue.
- **Feature requests**: Check that there is not an existing issue or discussion covering the scope of the feature you have in mind. If the feature is to another part of the Nuxt ecosystem (such as a module), please consider raising a feature request there first. If the feature you have in mind is general or the API is not entirely clear, consider opening a discussion in the **Ideas** section to discuss with the community first.
We'll do our best to follow our [internal issue decision making flowchart](https://mermaid.live/view#pako:eNqFlE1v2zAMhv8K4UuToslhx2Bo0TZt12Edhm7YMCAXWqJtorLk6qOpkfS_j7KdfpyWQ-BQr8mHL6nsCuU0FauiMm6rGvQRfq03FuRzvvvTYIQHthpcBT_ugQNwPHuZjheLxf4i1VDx8x4udrf5EBCOQvSsYg4ffS79KS9pmX9QALTgyid2KYB7Ih-4bmKWbDk2YB0E1gRUVaRi-FDmmjAmT3u4nB3DmoNKIUA1BsGSohA49jnVMQhHbDh_EZQUImyxh-gAtfaiG-KWSJ-N8nt6YtpCdgEeE5rXPOdav5YwWJIJU7zrvNADV9C7JBIyIC07Wxupkx3LFQ5vCkguRno5f9fP2qnUko0Y2dk9rGdvHAa9IIhVGlCp5FFNPN-ce4DKeXBd53xMliOLp9IZtyORQVsnrGm-WJzejtUu5fFqdr5FGQ3bLslYvGthjZbJTLpReZG5_lLYw7XQ_CbPVT92ws9gnEJj-v84dk-PiaXnmF1XGAaPsOsMKywNvYmG80ZohV8k4wDR9_N3KN_dHm5mh1lnkM5FsYzRfNiTvJoT5gnQsl6uxjqXLhkNQ9syHJ0UZZ8ERUIlNShr6N8gZDEliR-ow7QZa0fhY4LoHLRo-8N7ZxPwjRj5ZZYXpvOSNs9v3Jjs8NXB4ets92xan3zydXZHvj64lKMayh4-gZC1bjASW2ipLeWuzIuToiXfImu5rbucclMIc0ubYiWPGv3DptjYF9Fhiu5nb1Wxij7RSZE6jZHWjLXHtlhVaIJESXN0_m68_sO_wMs_oO9gyg) when responding to issues.
### Send a Pull Request
We always welcome pull requests! ❤️
#### Before You Start
Before you fix a bug, we recommend that you check whether **there's an issue that describes it**, as it's possible it's a documentation issue or that there is some context that would be helpful to know.
If you're working on a feature, then we ask that you **open a feature request issue first** to discuss with the maintainers whether the feature is desired - and the design of those features. This helps save time for both the maintainers and the contributors and means that features can be shipped faster. The issue **should be confirmed** by a framework team member before building out a feature in a pull request.
For typo fixes, it's recommended to batch multiple typo fixes into one pull request to maintain a cleaner commit history.
For bigger changes to Nuxt itself, we recommend that you first [create a Nuxt module](/docs/4.x/community/contribution#create-a-module) and implement the feature there. This allows for quick proof-of-concept. You can then [create an RFC](/docs/4.x/community/contribution#make-an-rfc) in the form of a discussion. As users adopt it and you gather feedback, it can then be refined and either added to Nuxt core or continue as a standalone module.
#### Commit Conventions
We use [Conventional Commits](https://www.conventionalcommits.org) for commit messages, which [allows a changelog to be auto-generated](https://github.com/unjs/changelogen) based on the commits. Please read the guide through if you aren't familiar with it already.
Note that `fix:` and `feat:` are for **actual code changes** (that might affect logic). For typo or document changes, use `docs:` or `chore:` instead:
- ~~fix: typo~~ -> `docs: fix typo`
If you are working in a project with a monorepo, like `nuxt/nuxt`, ensure that you specify the main scope of your commit in brackets. For example: `feat(kit): add 'addMagicStuff' utility`.
#### Making the Pull Request
If you don't know how to send a pull request, we recommend reading [the guide](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
When sending a pull request, make sure your PR's title also follows the [Commit Convention](/docs/4.x/community/contribution#commit-conventions).
If your PR fixes or resolves existing issues, please make sure you mention them in the PR description.
It's ok to have multiple commits in a single PR; you don't need to rebase or force push for your changes as we will use `Squash and Merge` to squash the commits into one commit when merging.
We do not add any commit hooks to allow for quick commits. But before you make a pull request, you should ensure that any lint/test scripts are passing.
In general, please also make sure that there are no *unrelated* changes in a PR. For example, if your editor has made any changes to whitespace or formatting elsewhere in a file that you edited, please revert these so it is more obvious what your PR changes. And please avoid including multiple unrelated features or fixes in a single PR. If it is possible to separate them, it is better to have multiple PRs to review and merge separately. In general, a PR should do *one thing only*.
#### Once You've Made a Pull Request
Once you've made a pull request, we'll do our best to review it promptly.
If we assign it to a maintainer, then that means that person will take special care to review it and implement any changes that may be required.
If we request changes on a PR, please ignore the red text! It doesn't mean we think it's a bad PR - it's just a way of easily telling the status of a list of pull requests at a glance.
If we mark a PR as 'pending', that means we likely have another task to do in reviewing the PR - it's an internal note-to-self, and not necessarily a reflection on whether the PR is a good idea or not. We will do our best to explain via a comment the reason for the pending status.
We'll do our best to follow [our PR decision making flowchart](https://mermaid.live/view#pako:eNp9VE1v2kAQ_SsjXzBSEqlALlaUisSh0ACK2l4qcVm8Y9hi7672Iwly-O-ZtYPt5FAOCHbee_PmzdpVlCmOURLlhXrJ9sw4-JNuJNBnWs1UQafIQVjrERyWumAOv58-AJeXt29_0b7BXbWwwL0uRPa1vlZvcB_fF8oiMMmB2QM4BXkt3UoON7Lh3LWaDz2SVkK6QGt7DHvw0CKt5sxCKaQoWQEGtVHcZ04oGdw04LTVngW_LHOeFcURGGz97mw6PSv-iJdsi0UCA4nI7SfNwc3W3JZit3eQ1SZFDlKB15yswQ2MgbOjbYeatY3n8bcr-IWlekYYaJRcyB04I9gOB1CEfkF5dAVTzmFAtnqn4-bUYAiMMmHZgWhNPRhgus5mW2BATxq0NkIZ4Y4NbNjzE2ZchBzcHmGLe_ZMSKCcyRXyLrVFa_5n_PBK2xKy3kk9eOjULUdltk6C8kI-7NFDr8f4EVGDoqlp-wa4sJm3ltIMIuZ_mTQXJyTSkQZtunPqsKxShV9GKdkBYe1fHXjpbcjlvONlO9Kqx_M7YHmOmav_luxfE5zKwVs09hM5DLSupgYDlr5flDkwo7ykixKG-xDsUly1LZ-uY32dgDc7lG7YqwbNp0msJwmIUivjWFtfd-xRrEcJ7Omydz37qFplHOtxEp4GskI2qB5dRCWakglOz3oV8JuITJa4iRL6yZk5bKKNPBGOead-H2UWJc54vIiaW53SPgwrz4fIhVNm1bw76lfI6R2_MW21) when responding and reviewing to pull requests.
### AI-Assisted Contributions
We welcome the thoughtful use of AI tools when contributing to Nuxt, yet ask all contributors to follow [two core principles](https://roe.dev/blog/using-ai-in-open-source).
#### Never let an LLM speak for you
- All comments, issues, and pull request descriptions should be written in your own voice
- We value clear, human communication over perfect grammar or spelling
- Avoid copy-pasting AI-generated summaries that don't reflect your own understanding
#### Never let an LLM think for you
- Feel free to use AI tools to generate code or explore ideas
- Only submit contributions you fully understand and can explain
- Contributions should reflect your own reasoning and problem-solving
Our aim is ensuring quality and maintaining the joy of collaborating and communicating with real people. If you have ideas for improving our policy on AI in the Nuxt community, we'd love to hear them! ❤️
### Create a Module
If you've built something with Nuxt that's cool, why not [extract it into a module](/docs/4.x/guide/modules), so it can be shared with others? We have [many excellent modules already](/modules), but there's always room for more.
If you need help while building it, feel free to [check in with us](/docs/4.x/community/getting-help).
### Make an RFC
We highly recommend [creating a module](/docs/4.x/community/contribution#create-a-module) first to test out big new features and gain community adoption.
If you have done this already, or it's not appropriate to create a new module, then please start by creating a new discussion. Make sure it explains your thinking as clearly as possible. Include code examples or function signatures for new APIs. Reference existing issues or pain points with examples.
If we think this should be an RFC, we'll change the category to RFC and broadcast it more widely for feedback.
An RFC will then move through the following stages:
- `rfc: active` - currently open for comment
- `rfc: approved` - approved by the Nuxt team
- `rfc: ready to implement` - an issue has been created and assigned to implement
- `rfc: shipped` - implemented
- `rfc: archived` - not approved, but archived for future reference
### Conventions Across Ecosystem
The following conventions are *required* within the `nuxt/` organization and recommended for other maintainers in the ecosystem.
#### Module Conventions
Modules should follow the [Nuxt module template](https://github.com/nuxt/starter/tree/module). See [module guide](/docs/4.x/guide/modules) for more information.
#### Use Core `unjs/` Libraries
We recommend the following libraries which are used throughout the ecosystem:
- [pathe](https://github.com/unjs/pathe) - universal path utilities (replacement for node `path`)
- [ufo](https://github.com/unjs/ufo) - URL parsing and joining utilities
- [obuild](https://github.com/unjs/obuild) - rolldown-powered build system
- ... check out the rest of the [unjs/](https://github.com/unjs) organization for many more!
#### Use ESM Syntax and Default to `type: module`
Most of the Nuxt ecosystem can consume ESM directly. In general we advocate that you avoid using CJS-specific code, such as `__dirname` and `require` statements. You can [read more about ESM](/docs/4.x/guide/concepts/esm).
#### What's Corepack
[Corepack](https://github.com/nodejs/corepack) makes sure you are using the correct version for package manager when you run corresponding commands. Projects might have `packageManager` field in their `package.json`.
Under projects with configuration as shown below, Corepack will install `v7.5.0` of `pnpm` (if you don't have it already) and use it to run your commands.
```jsonc [package.json]
{
"packageManager": "pnpm@7.5.0"
}
```
#### Use ESLint
We use [ESLint](https://eslint.org) for both linting and formatting with [`@nuxt/eslint`](https://github.com/nuxt/eslint).
##### IDE Setup
We recommend using [VS Code](https://code.visualstudio.com) along with the [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint). If you would like, you can enable auto-fix and formatting when you save the code you are editing:
```json [settings.json]
{
"editor.codeActionsOnSave": {
"source.fixAll": "never",
"source.fixAll.eslint": "explicit"
}
}
```
#### No Prettier
Since ESLint is already configured to format the code, there is no need to duplicate the functionality with Prettier. To format the code, you can run `yarn lint --fix`, `pnpm lint --fix`, `bun run lint --fix`, or `deno run lint --fix` or referring the [ESLint section](/docs/4.x/community/contribution#use-eslint) for IDE Setup.
If you have Prettier installed in your editor, we recommend you disable it when working on the project to avoid conflict.
#### Package Manager
We recommend `pnpm` as a package manager for modules, libraries and apps.
It is important to enable Corepack to ensure you are on the same version of the package manager as the project. Corepack is built-in to new node versions for seamless package manager integration.
To enable it, run
```bash [Terminal]
corepack enable
```
You only need to do this one time, after Node.js is installed on your computer.
## Documentation Style Guide
Documentation is an essential part of Nuxt. We aim to be an intuitive framework - and a big part of that is making sure that both the developer experience and the docs are perfect across the ecosystem. 👌
Here are some tips that may help improve your documentation:
- Avoid subjective words like *simply*, *just*, *obviously...* when possible.
Keep in mind your readers can have different backgrounds and experiences. Therefore, these words don't convey meaning and can be harmful.
Simply make sure the function returns a promise.
Make sure the function returns a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
- Prefer [active voice](https://developers.google.com/tech-writing/one/active-voice).
An error will be thrown by Nuxt.
Nuxt will throw an error.
Learn how to contribute to the documentation.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/create-error.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/create-error.md
# createError
> Create an error object with additional metadata.
You can use this function to create an error object with additional metadata. It is usable in both the Vue and Nitro portions of your app, and is meant to be thrown.
## Parameters
- `err`: `string | { cause, data, message, name, stack, status, statusText, fatal }`
You can pass either a string or an object to the `createError` function. If you pass a string, it will be used as the error `message`, and the `status` will default to `500`. If you pass an object, you can set multiple properties of the error, such as `status`, `message`, and other error properties.
## In Vue App
If you throw an error created with `createError`:
- on server-side, it will trigger a full-screen error page which you can clear with `clearError`.
- on client-side, it will throw a non-fatal error for you to handle. If you need to trigger a full-screen error page, then you can do this by setting `fatal: true`.
### Example
```vue [app/pages/movies/[slug].vue]
```
## In API Routes
Use `createError` to trigger error handling in server API routes.
### Example
```ts [server/api/error.ts]
export default eventHandler(() => {
throw createError({
status: 404,
statusText: 'Page Not Found',
})
})
```
In API routes, using `createError` by passing an object with a short `statusText` is recommended because it can be accessed on the client side. Otherwise, a `message` passed to `createError` on an API route will not propagate to the client. Alternatively, you can use the `data` property to pass data back to the client. In any case, always consider avoiding to put dynamic user input to the message to avoid potential security issues.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/recipes/custom-routing.md
# Source: https://nuxt.com/raw/docs/4.x/guide/recipes/custom-routing.md
# Custom Routing
> In Nuxt, your routing is defined by the structure of your files inside the pages directory. However, since it uses vue-router under the hood, Nuxt offers you several ways to add custom routes in your project.
## Adding custom routes
In Nuxt, your routing is defined by the structure of your files inside the [app/pages directory](/docs/4.x/directory-structure/app/pages). However, since it uses [vue-router](https://router.vuejs.org) under the hood, Nuxt offers you several ways to add custom routes in your project.
### Router Config
Using [router options](/docs/4.x/guide/recipes/custom-routing#router-options), you can optionally override or extend your routes using a function that accepts the scanned routes and returns customized routes.
If it returns `null` or `undefined`, Nuxt will fall back to the default routes (useful to modify input array).
```ts [router.options.ts]
import type { RouterConfig } from '@nuxt/schema'
export default {
// https://router.vuejs.org/api/interfaces/routeroptions#routes
routes: _routes => [
{
name: 'home',
path: '/',
component: () => import('~/pages/home.vue'),
},
],
} satisfies RouterConfig
```
Nuxt will not augment any new routes you return from the `routes` function with metadata defined in `definePageMeta` of the component you provide. If you want that to happen, you should use the `pages:extend` hook which is [called at build-time](/docs/4.x/api/advanced/hooks#nuxt-hooks-build-time).
### Pages Hook
You can add, change or remove pages from the scanned routes with the `pages:extend` nuxt hook.
For example, to prevent creating routes for any `.ts` files:
```ts [nuxt.config.ts]
import type { NuxtPage } from '@nuxt/schema'
export default defineNuxtConfig({
hooks: {
'pages:extend' (pages) {
// add a route
pages.push({
name: 'profile',
path: '/profile',
file: '~/extra-pages/profile.vue',
})
// remove routes
function removePagesMatching (pattern: RegExp, pages: NuxtPage[] = []) {
const pagesToRemove: NuxtPage[] = []
for (const page of pages) {
if (page.file && pattern.test(page.file)) {
pagesToRemove.push(page)
} else {
removePagesMatching(pattern, page.children)
}
}
for (const page of pagesToRemove) {
pages.splice(pages.indexOf(page), 1)
}
}
removePagesMatching(/\.ts$/, pages)
},
},
})
```
### Nuxt Module
If you plan to add a whole set of pages related with a specific functionality, you might want to use a [Nuxt module](/modules).
The [Nuxt kit](/docs/4.x/guide/going-further/kit) provides a few ways [to add routes](/docs/4.x/api/kit/pages):
- [`extendPages`](/docs/4.x/api/kit/pages#extendpages) (callback: pages => void)
- [`extendRouteRules`](/docs/4.x/api/kit/pages#extendrouterules) (route: string, rule: NitroRouteConfig, options: ExtendRouteRulesOptions)
## Router Options
On top of customizing options for [`vue-router`](https://router.vuejs.org/api/interfaces/routeroptions), Nuxt offers [additional options](/docs/4.x/api/nuxt-config#router) to customize the router.
### Using `router.options`
This is the recommended way to specify [router options](/docs/4.x/api/nuxt-config#router).
```ts [app/router.options.ts]
import type { RouterConfig } from '@nuxt/schema'
export default {
} satisfies RouterConfig
```
It is possible to add more router options files by adding files within the `pages:routerOptions` hook. Later items in the array override earlier ones.
Adding a router options file in this hook will switch on page-based routing, unless `optional` is set, in which case it will only apply when page-based routing is already enabled.
```ts [nuxt.config.ts]
import { createResolver } from '@nuxt/kit'
export default defineNuxtConfig({
hooks: {
'pages:routerOptions' ({ files }) {
const resolver = createResolver(import.meta.url)
// add a route
files.push({
path: resolver.resolve('./runtime/router-options'),
optional: true,
})
},
},
})
```
### Using `nuxt.config`
**Note:** Only JSON serializable [options](/docs/4.x/api/nuxt-config#router) are configurable:
- `linkActiveClass`
- `linkExactActiveClass`
- `end`
- `sensitive`
- `strict`
- `hashMode`
- `scrollBehaviorType`
```ts [nuxt.config]
export default defineNuxtConfig({
router: {
options: {},
},
})
```
### Hash Mode (SPA)
You can enable hash history in SPA mode using the `hashMode` [config](/docs/4.x/api/nuxt-config#router). In this mode, router uses a hash character (#) before the actual URL that is internally passed. When enabled, the **URL is never sent to the server** and **SSR is not supported**.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
ssr: false,
router: {
options: {
hashMode: true,
},
},
})
```
### Scroll Behavior for hash links
You can optionally customize the scroll behavior for hash links. When you set the [config](/docs/4.x/api/nuxt-config#router) to be `smooth` and you load a page with a hash link (e.g. `https://example.com/blog/my-article#comments`), you will see that the browser smoothly scrolls to this anchor.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
router: {
options: {
scrollBehaviorType: 'smooth',
},
},
})
```
#### Custom History (advanced)
You can optionally override history mode using a function that accepts the base URL and returns the history mode. If it returns `null` or `undefined`, Nuxt will fallback to the default history.
```ts [router.options.ts]
import type { RouterConfig } from '@nuxt/schema'
import { createMemoryHistory } from 'vue-router'
export default {
// https://router.vuejs.org/api/interfaces/routeroptions
history: base => import.meta.client ? createMemoryHistory(base) : null, /* default */
} satisfies RouterConfig
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/recipes/custom-usefetch.md
# Source: https://nuxt.com/raw/docs/4.x/guide/recipes/custom-usefetch.md
# Custom useFetch in Nuxt
> How to create a custom fetcher for calling your external API in Nuxt.
When working with Nuxt, you might be making the frontend and fetching an external API, and you might want to set some default options for fetching from your API.
The [`$fetch`](/docs/4.x/api/utils/dollarfetch) utility function (used by the [`useFetch`](/docs/4.x/api/composables/use-fetch) composable) is intentionally not globally configurable. This is important so that fetching behavior throughout your application remains consistent, and other integrations (like modules) can rely on the behavior of core utilities like `$fetch`.
However, Nuxt provides a way to create a custom fetcher for your API (or multiple fetchers if you have multiple APIs to call).
## Custom `$fetch`
Let's create a custom `$fetch` instance with a [Nuxt plugin](/docs/4.x/directory-structure/app/plugins).
`$fetch` is a configured instance of [ofetch](https://github.com/unjs/ofetch) which supports adding the base URL of your Nuxt server as well as direct function calls during SSR (avoiding HTTP roundtrips).
Let's pretend here that:
- The main API is [https://api.nuxt.com](https://api.nuxt.com)
- We are storing the JWT token in a session with [nuxt-auth-utils](https://github.com/atinux/nuxt-auth-utils)
- If the API responds with a `401` status code, we redirect the user to the `/login` page
```ts [app/plugins/api.ts]
export default defineNuxtPlugin((nuxtApp) => {
const { session } = useUserSession()
const api = $fetch.create({
baseURL: 'https://api.nuxt.com',
onRequest ({ request, options, error }) {
if (session.value?.token) {
// note that this relies on ofetch >= 1.4.0 - you may need to refresh your lockfile
options.headers.set('Authorization', `Bearer ${session.value?.token}`)
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await nuxtApp.runWithContext(() => navigateTo('/login'))
}
},
})
// Expose to useNuxtApp().$api
return {
provide: {
api,
},
}
})
```
With this Nuxt plugin, `$api` is exposed from `useNuxtApp()` to make API calls directly from the Vue components:
```vue [app/app.vue]
```
Wrapping with [`useAsyncData`](/docs/4.x/api/composables/use-async-data) **avoid double data fetching when doing server-side rendering** (server & client on hydration).
## Custom `useFetch`/`useAsyncData`
Now that `$api` has the logic we want, let's create a `useAPI` composable to replace the usage of `useAsyncData` + `$api`:
```ts [app/composables/useAPI.ts]
import type { UseFetchOptions } from 'nuxt/app'
export function useAPI (
url: string | (() => string),
options?: UseFetchOptions,
) {
return useFetch(url, {
...options,
$fetch: useNuxtApp().$api as typeof $fetch,
})
}
```
Let's use the new composable and have a nice and clean component:
```vue [app/app.vue]
```
If you want to customize the type of any error returned, you can also do so:
```ts
import type { FetchError } from 'ofetch'
import type { UseFetchOptions } from 'nuxt/app'
interface CustomError {
message: string
status: number
}
export function useAPI (
url: string | (() => string),
options?: UseFetchOptions,
) {
return useFetch>(url, {
...options,
$fetch: useNuxtApp().$api,
})
}
```
This example demonstrates how to use a custom `useFetch`, but the same structure is identical for a custom `useAsyncData`.
We are currently discussing to find a cleaner way to let you create a custom fetcher, see [https://github.com/nuxt/nuxt/issues/14736](https://github.com/nuxt/nuxt/issues/14736).
---
# Source: https://nuxt.com/raw/docs/3.x/examples/features/data-fetching.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/data-fetching.md
# Source: https://nuxt.com/raw/docs/4.x/examples/features/data-fetching.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/data-fetching.md
# Data Fetching
> Nuxt provides composables to handle data fetching within your application.
Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/4.x/api/composables/use-async-data) and `$fetch`.
In a nutshell:
- [`$fetch`](/docs/4.x/api/utils/dollarfetch) is the simplest way to make a network request.
- [`useFetch`](/docs/4.x/api/composables/use-fetch) is a wrapper around `$fetch` that fetches data only once in [universal rendering](/docs/4.x/guide/concepts/rendering#universal-rendering).
- [`useAsyncData`](/docs/4.x/api/composables/use-async-data) is similar to `useFetch` but offers more fine-grained control.
Both `useFetch` and `useAsyncData` share a common set of options and patterns that we will detail in the last sections.
## The need for `useFetch` and `useAsyncData`
Nuxt is a framework which can run isomorphic (or universal) code in both server and client environments. If the [`$fetch` function](/docs/4.x/api/utils/dollarfetch) is used to perform data fetching in the setup function of a Vue component, this may cause data to be fetched twice, once on the server (to render the HTML) and once again on the client (when the HTML is hydrated). This can cause hydration issues, increase the time to interactivity and cause unpredictable behavior.
The [`useFetch`](/docs/4.x/api/composables/use-fetch) and [`useAsyncData`](/docs/4.x/api/composables/use-async-data) composables solve this problem by ensuring that if an API call is made on the server, the data is forwarded to the client in the payload.
The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/4.x/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser [during hydration](/docs/4.x/guide/concepts/rendering#universal-rendering).
Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the **Payload tab**.
```vue [app/app.vue]
No data
```
In the example above, `useFetch` would make sure that the request would occur in the server and is properly forwarded to the browser. `$fetch` has no such mechanism and is a better option to use when the request is solely made from the browser.
### Suspense
Nuxt uses Vue's [``](https://vuejs.org/guide/built-ins/suspense) component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-call basis.
You can add the [``](/docs/4.x/api/components/nuxt-loading-indicator) to add a progress bar between page navigations.
## `$fetch`
Nuxt includes the [ofetch](https://github.com/unjs/ofetch) library, and is auto-imported as the `$fetch` alias globally across your application.
```vue [pages/todos.vue]twoslash
```
Beware that using only `$fetch` will not provide [network calls de-duplication and navigation prevention](/docs/4.x/getting-started/data-fetching#the-need-for-usefetch-and-useasyncdata).
It is recommended to use `$fetch` for client-side interactions (event-based) or combined with [`useAsyncData`](/docs/4.x/getting-started/data-fetching#useasyncdata) when fetching the initial component data.
Read more about `$fetch`.
### Pass Client Headers to the API
When calling `useFetch` on the server, Nuxt will use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy client headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
```vue
```
```ts
// /api/echo.ts
export default defineEventHandler(event => parseCookies(event))
```
Alternatively, the example below shows how to use [`useRequestHeaders`](/docs/4.x/api/composables/use-request-headers) to access and send cookies to the API from a server-side request (originating on the client). Using an isomorphic `$fetch` call, we ensure that the API endpoint has access to the same `cookie` header originally sent by the user's browser. This is only necessary if you aren't using `useFetch`.
```vue
```
You can also use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy headers to the call automatically.
Be very careful before proxying headers to an external API and just include headers that you need. Not all headers are safe to be bypassed and might introduce unwanted behavior. Here is a list of common headers that are NOT to be proxied:
- `host`, `accept`
- `content-length`, `content-md5`, `content-type`
- `x-forwarded-host`, `x-forwarded-port`, `x-forwarded-proto`
- `cf-connecting-ip`, `cf-ray`
## `useFetch`
The [`useFetch`](/docs/4.x/api/composables/use-fetch) composable uses `$fetch` under-the-hood to make SSR-safe network calls in the setup function.
```vue [app/app.vue]twoslash
Page visits: {{ count }}
```
This composable is a wrapper around the [`useAsyncData`](/docs/4.x/api/composables/use-async-data) composable and `$fetch` utility.
## `useAsyncData`
The `useAsyncData` composable is responsible for wrapping async logic and returning the result once it is resolved.
`useFetch(url)` is nearly equivalent to `useAsyncData(url, () => event.$fetch(url))`.
It's developer experience sugar for the most common use case. (You can find out more about `event.fetch` at [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch).)
There are some cases when using the [`useFetch`](/docs/4.x/api/composables/use-fetch) composable is not appropriate, for example when a CMS or a third-party provide their own query layer. In this case, you can use [`useAsyncData`](/docs/4.x/api/composables/use-async-data) to wrap your calls and still keep the benefits provided by the composable.
```vue [app/pages/users.vue]
```
The first argument of [`useAsyncData`](/docs/4.x/api/composables/use-async-data) is a unique key used to cache the response of the second argument, the querying function. This key can be ignored by directly passing the querying function, the key will be auto-generated.
Since the autogenerated key only takes into account the file and line where `useAsyncData` is invoked, it is recommended to always create your own key to avoid unwanted behavior, like when you are creating your own custom composable wrapping `useAsyncData`.
Setting a key can be useful to share the same data between components using [`useNuxtData`](/docs/4.x/api/composables/use-nuxt-data) or to [refresh specific data](/docs/4.x/api/utils/refresh-nuxt-data#refresh-specific-data).
```vue [app/pages/users/[id].vue]
```
The `useAsyncData` composable is a great way to wrap and wait for multiple `$fetch` requests to be completed, and then process the results.
```vue
```
`useAsyncData` is for fetching and caching data, not triggering side effects like calling Pinia actions, as this can cause unintended behavior such as repeated executions with nullish values. If you need to trigger side effects, use the [`callOnce`](/docs/4.x/api/utils/call-once) utility to do so.
```vue
```
Read more about `useAsyncData`.
## Return Values
`useFetch` and `useAsyncData` have the same return values listed below.
- `data`: the result of the asynchronous function that is passed in.
- `refresh`/`execute`: a function that can be used to refresh the data returned by the `handler` function.
- `clear`: a function that can be used to set `data` to `undefined` (or the value of `options.default()` if provided), set `error` to `undefined`, set `status` to `idle`, and mark any currently pending requests as cancelled.
- `error`: an error object if the data fetching failed.
- `status`: a string indicating the status of the data request (`"idle"`, `"pending"`, `"success"`, `"error"`).
`data`, `error` and `status` are Vue refs accessible with `.value` in `
Loading ...
```
You can alternatively use [`useLazyFetch`](/docs/4.x/api/composables/use-lazy-fetch) and `useLazyAsyncData` as convenient methods to perform the same.
```vuetwoslash
```
Read more about `useLazyFetch`.
Read more about `useLazyAsyncData`.
### Client-only fetching
By default, data fetching composables will perform their asynchronous function on both client and server environments. Set the `server` option to `false` to only perform the call on the client-side. On initial load, the data will not be fetched before hydration is complete so you have to handle a pending state, though on subsequent client-side navigation the data will be awaited before loading the page.
Combined with the `lazy` option, this can be useful for data that is not needed on the first render (for example, non-SEO sensitive data).
```tstwoslash
/* This call is performed before hydration */
const articles = await useFetch('/api/article')
/* This call will only be performed on the client */
const { status, data: comments } = useFetch('/api/comments', {
lazy: true,
server: false,
})
```
The `useFetch` composable is meant to be invoked in setup method or called directly at the top level of a function in lifecycle hooks, otherwise you should use [`$fetch` method](/docs/4.x/getting-started/data-fetching#fetch).
### Minimize payload size
The `pick` option helps you to minimize the payload size stored in your HTML document by only selecting the fields that you want returned from the composables.
```vue
{{ mountain.title }}
{{ mountain.description }}
```
If you need more control or map over several objects, you can use the `transform` function to alter the result of the query.
```ts
const { data: mountains } = await useFetch('/api/mountains', {
transform: (mountains) => {
return mountains.map(mountain => ({ title: mountain.title, description: mountain.description }))
},
})
```
Both `pick` and `transform` don't prevent the unwanted data from being fetched initially. But they will prevent unwanted data from being added to the payload transferred from server to client.
### Caching and refetching
#### Keys
[`useFetch`](/docs/4.x/api/composables/use-fetch) and [`useAsyncData`](/docs/4.x/api/composables/use-async-data) use keys to prevent refetching the same data.
- [`useFetch`](/docs/4.x/api/composables/use-fetch) uses the provided URL as a key. Alternatively, a `key` value can be provided in the `options` object passed as a last argument.
- [`useAsyncData`](/docs/4.x/api/composables/use-async-data) uses its first argument as a key if it is a string. If the first argument is the handler function that performs the query, then a key that is unique to the file name and line number of the instance of `useAsyncData` will be generated for you.
To get the cached data by key, you can use [`useNuxtData`](/docs/4.x/api/composables/use-nuxt-data)
#### Shared State and Option Consistency
When multiple components use the same key with `useAsyncData` or `useFetch`, they will share the same `data`, `error` and `status` refs. This ensures consistency across components but requires some options to be consistent.
The following options **must be consistent** across all calls with the same key:
- `handler` function
- `deep` option
- `transform` function
- `pick` array
- `getCachedData` function
- `default` value
```ts
// ❌ This will trigger a development warning
const { data: users1 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { deep: false })
const { data: users2 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { deep: true })
```
The following options **can safely differ** without triggering warnings:
- `server`
- `lazy`
- `immediate`
- `dedupe`
- `watch`
```ts
// ✅ This is allowed
const { data: users1 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { immediate: true })
const { data: users2 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { immediate: false })
```
If you need independent instances, use different keys:
```ts
// These are completely independent instances
const { data: users1 } = useAsyncData('users-1', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }))
const { data: users2 } = useAsyncData('users-2', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }))
```
#### Reactive Keys
You can use computed refs, plain refs or getter functions as keys, allowing for dynamic data fetching that automatically updates when dependencies change:
```ts
// Using a computed property as a key
const userId = ref('123')
const { data: user } = useAsyncData(
computed(() => `user-${userId.value}`),
() => fetchUser(userId.value),
)
// When userId changes, the data will be automatically refetched
// and the old data will be cleaned up if no other components use it
userId.value = '456'
```
#### Refresh and execute
If you want to fetch or refresh data manually, use the `execute` or `refresh` function provided by the composables.
```vuetwoslash
{{ data }}
```
The `execute` function is an alias for `refresh` that works in exactly the same way but is more semantic for cases when the fetch is [not immediate](/docs/4.x/getting-started/data-fetching#not-immediate).
To globally refetch or invalidate cached data, see [`clearNuxtData`](/docs/4.x/api/utils/clear-nuxt-data) and [`refreshNuxtData`](/docs/4.x/api/utils/refresh-nuxt-data).
#### Clear
If you want to clear the data provided, for whatever reason, without needing to know the specific key to pass to `clearNuxtData`, you can use the `clear` function provided by the composables.
```vuetwoslash
```
#### Watch
To re-run your fetching function each time other reactive values in your application change, use the `watch` option. You can use it for one or multiple *watchable* elements.
```vuetwoslash
```
Note that **watching a reactive value won't change the URL fetched**. For example, this will keep fetching the same initial ID of the user because the URL is constructed at the moment the function is invoked.
```vue
```
If you need to change the URL based on a reactive value, you may want to use a [computed URL](/docs/4.x/getting-started/data-fetching#computed-url) instead.
When reactive fetch options are provided, they'll be automatically watched and trigger refetches. In some cases, it can be useful to opt-out of this behavior by specifying `watch: false`.
```ts
const id = ref(1)
// Won't automatically refetch when id changes
const { data, execute } = await useFetch('/api/users', {
query: { id }, // id is watched by default
watch: false, // disables automatic watching of id
})
// doesn't trigger refetch
id.value = 2
```
#### Computed URL
Sometimes you may need to compute a URL from reactive values, and refresh the data each time these change. Instead of juggling your way around, you can attach each param as a reactive value. Nuxt will automatically use the reactive value and re-fetch each time it changes.
```vue
```
In the case of more complex URL construction, you may use a callback as a [computed getter](https://vuejs.org/guide/essentials/computed) that returns the URL string.
Every time a dependency changes, the data will be fetched using the newly constructed URL. Combine this with [not-immediate](/docs/4.x/getting-started/data-fetching#not-immediate), and you can wait until the reactive element changes before fetching.
```vue
Type an user ID
Loading ...
{{ data }}
```
If you need to force a refresh when other reactive values change, you can also [watch other values](/docs/4.x/getting-started/data-fetching#watch).
### Not immediate
The `useFetch` composable will start fetching data the moment is invoked. You may prevent this by setting `immediate: false`, for example, to wait for user interaction.
With that, you will need both the `status` to handle the fetch lifecycle, and `execute` to start the data fetch.
```vue
Loading comments...
{{ data }}
```
For finer control, the `status` variable can be:
- `idle` when the fetch hasn't started
- `pending` when a fetch has started but not yet completed
- `error` when the fetch fails
- `success` when the fetch is completed successfully
## Passing Headers and Cookies
When we call `$fetch` in the browser, user headers like `cookie` will be directly sent to the API.
Normally, during server-side-rendering, due to security considerations, the `$fetch` wouldn't include the user's browser cookies, nor pass on cookies from the fetch response.
However, when calling `useFetch` with a relative URL on the server, Nuxt will use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
### Pass Cookies From Server-side API Calls on SSR Response
If you want to pass on/proxy cookies in the other direction, from an internal request back to the client, you will need to handle this yourself.
```ts [app/composables/fetch.ts]
import { appendResponseHeader } from 'h3'
import type { H3Event } from 'h3'
export const fetchWithCookie = async (event: H3Event, url: string) => {
/* Get the response from the server endpoint */
const res = await $fetch.raw(url)
/* Get the cookies from the response */
const cookies = res.headers.getSetCookie()
/* Attach each cookie to our incoming Request */
for (const cookie of cookies) {
appendResponseHeader(event, 'set-cookie', cookie)
}
/* Return the data of the response */
return res._data
}
```
```vue
```
## Options API Support
Nuxt provides a way to perform `asyncData` fetching within the Options API. You must wrap your component definition within `defineNuxtComponent` for this to work.
```vue
```
Using `
```
### Custom serializer function
To customize the serialization behavior, you can define a `toJSON` function on your returned object. If you define a `toJSON` method, Nuxt will respect the return type of the function and will not try to convert the types.
```ts [server/api/bar.ts]
export default defineEventHandler(() => {
const data = {
createdAt: new Date(),
toJSON () {
return {
createdAt: {
year: this.createdAt.getFullYear(),
month: this.createdAt.getMonth(),
day: this.createdAt.getDate(),
},
}
},
}
return data
})
```
```vue [app/app.vue]
```
### Using an alternative serializer
Nuxt does not currently support an alternative serializer to `JSON.stringify`. However, you can return your payload as a normal string and utilize the `toJSON` method to maintain type safety.
In the example below, we use [superjson](https://github.com/flightcontrolhq/superjson) as our serializer.
```ts [server/api/superjson.ts]
import superjson from 'superjson'
export default defineEventHandler(() => {
const data = {
createdAt: new Date(),
// Workaround the type conversion
toJSON () {
return this
},
}
// Serialize the output to string, using superjson
return superjson.stringify(data) as unknown as typeof data
})
```
```vue [app/app.vue]
```
## Recipes
### Consuming SSE (Server-Sent Events) via POST request
If you're consuming SSE via GET request, you can use [`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) or VueUse composable [`useEventSource`](https://vueuse.org/core/useeventsource/).
When consuming SSE via POST request, you need to handle the connection manually. Here's how you can do it:
```ts
// Make a POST request to the SSE endpoint
const response = await $fetch('/chats/ask-ai', {
method: 'POST',
body: {
query: 'Hello AI, how are you?',
},
responseType: 'stream',
})
// Create a new ReadableStream from the response with TextDecoderStream to get the data as text
const reader = response.pipeThrough(new TextDecoderStream()).getReader()
// Read the chunk of data as we get it
while (true) {
const { value, done } = await reader.read()
if (done) { break }
console.log('Received:', value)
}
```
### Making parallel requests
When requests don't rely on each other, you can make them in parallel with `Promise.all()` to boost performance.
```ts
const { data } = await useAsyncData((_nuxtApp, { signal }) => {
return Promise.all([
$fetch('/api/comments/', { signal }),
$fetch('/api/author/12', { signal }),
])
})
const comments = computed(() => data.value?.[0])
const author = computed(() => data.value?.[1])
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/debugging.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/debugging.md
# Debugging
> In Nuxt, you can get started with debugging your application directly in the browser as well as in your IDE.
## Sourcemaps
Sourcemaps are enabled for your server build by default, and for the client build in dev mode, but you can enable them more specifically in your configuration.
```ts
export default defineNuxtConfig({
// or sourcemap: true
sourcemap: {
server: true,
client: true,
},
})
```
## Debugging with Node Inspector
You can use [Node inspector](https://nodejs.org/en/learn/getting-started/debugging) to debug Nuxt server-side.
```bash
nuxt dev --inspect
```
This will start Nuxt in `dev` mode with debugger active. If everything is working correctly a Node.js icon will appear on your Chrome DevTools and you can attach to the debugger.
Note that the Node.js and Chrome processes need to be run on the same platform. This doesn't work inside of Docker.
## Debugging in Your IDE
It is possible to debug your Nuxt app in your IDE while you are developing it.
### Example VS Code Debug Configuration
You may need to update the config below with a path to your web browser. For more information, visit the [VS Code documentation about debug configuration](https://code.visualstudio.com/docs/debugtest/debugging#_launch-configurations).
```json5
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "client: chrome",
"url": "http://localhost:3000",
// this should point to your Nuxt `srcDir`, which is `app` by default
"webRoot": "${workspaceFolder}/app"
},
{
"type": "node",
"request": "launch",
"name": "server: nuxt",
"outputCapture": "std",
"program": "${workspaceFolder}/node_modules/nuxt/bin/nuxt.mjs",
"args": [
"dev"
],
}
],
"compounds": [
{
"name": "fullstack: nuxt",
"configurations": [
"server: nuxt",
"client: chrome"
]
}
]
}
```
If you prefer your usual browser extensions, add this to the *chrome* configuration above:
```json5
"userDataDir": false,
```
### Example JetBrains IDEs Debug Configuration
You can also debug your Nuxt app in JetBrains IDEs such as IntelliJ IDEA, WebStorm, or PhpStorm.
1. Create a new file in your project root directory and name it `nuxt.run.xml`.
2. Open the `nuxt.run.xml` file and paste the following debug configuration:
```html
```
### Other IDEs
If you have another IDE and would like to contribute sample configuration, feel free to [open a PR](https://github.com/nuxt/nuxt/edit/main/docs/2.guide/3.going-further/9.debugging.md)!
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/define-lazy-hydration-component.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/define-lazy-hydration-component.md
# defineLazyHydrationComponent
> Define a lazy hydration component with a specific strategy.
`defineLazyHydrationComponent` is a compiler macro that helps you create a component with a specific lazy hydration strategy. Lazy hydration defers hydration until components become visible or until the browser has completed more critical tasks. This can significantly reduce the initial performance cost, especially for non-essential components.
## Usage
### Visibility Strategy
Hydrates the component when it becomes visible in the viewport.
```vue
```
The `hydrateOnVisible` prop is optional. You can pass an object to customize the behavior of the `IntersectionObserver` under the hood.
Read more about the options for `hydrate-on-visible`.
Under the hood, this uses Vue's built-in [`hydrateOnVisible` strategy](https://vuejs.org/guide/components/async#hydrate-on-visible).
### Idle Strategy
Hydrates the component when the browser is idle. This is suitable if you need the component to load as soon as possible, but not block the critical rendering path.
```vue
```
The `hydrateOnIdle` prop is optional. You can pass a positive number to specify the maximum timeout.
Idle strategy is for components that can be hydrated when the browser is idle.
Under the hood, this uses Vue's built-in [`hydrateOnIdle` strategy](https://vuejs.org/guide/components/async#hydrate-on-idle).
### Interaction Strategy
Hydrates the component after a specified interaction (e.g., click, mouseover).
```vue
```
The `hydrateOnInteraction` prop is optional. If you do not pass an event or a list of events, it defaults to hydrating on `pointerenter`, `click`, and `focus`.
Under the hood, this uses Vue's built-in [`hydrateOnInteraction` strategy](https://vuejs.org/guide/components/async#hydrate-on-interaction).
### Media Query Strategy
Hydrates the component when the window matches a media query.
```vue
```
Under the hood, this uses Vue's built-in [`hydrateOnMediaQuery` strategy](https://vuejs.org/guide/components/async#hydrate-on-media-query).
### Time Strategy
Hydrates the component after a specified delay (in milliseconds).
```vue
```
Time strategy is for components that can wait a specific amount of time.
### If Strategy
Hydrates the component based on a boolean condition.
```vue
```
If strategy is best for components that might not always need to be hydrated.
### Never Hydrate
Never hydrates the component.
```vue
```
### Listening to Hydration Events
All delayed hydration components emit a `@hydrated` event when they are hydrated.
```vue
```
## Parameters
To ensure that the compiler correctly recognizes this macro, avoid using external variables. The following approach will prevent the macro from being properly recognized:
```vue
```
### `strategy`
- **Type**: `'visible' | 'idle' | 'interaction' | 'mediaQuery' | 'if' | 'time' | 'never'`
- **Required**: `true`
Strategy
Description
visible
Hydrates when the component becomes visible in the viewport.
idle
Hydrates when the browser is idle or after a delay.
interaction
Hydrates upon user interaction (e.g., click, hover).
mediaQuery
Hydrates when the specified media query condition is met.
if
Hydrates when a specified boolean condition is met.
time
Hydrates after a specified time delay.
never
Prevents Vue from hydrating the component.
### `source`
- **Type**: `() => Promise`
- **Required**: `true`
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/define-nuxt-component.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/define-nuxt-component.md
# defineNuxtComponent
> defineNuxtComponent() is a helper function for defining type safe components with Options API.
`defineNuxtComponent()` is a helper function for defining type safe Vue components using options API similar to [`defineComponent()`](https://vuejs.org/api/general#definecomponent). `defineNuxtComponent()` wrapper also adds support for `asyncData` and `head` component options.
Using `
```
## `head()`
If you choose not to use `setup()` in your app, you can use the `head()` method within your component definition:
```vue [app/pages/index.vue]
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/define-nuxt-plugin.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/define-nuxt-plugin.md
# defineNuxtPlugin
> defineNuxtPlugin() is a helper function for creating Nuxt plugins.
`defineNuxtPlugin` is a helper function for creating Nuxt plugins with enhanced functionality and type safety. This utility normalizes different plugin formats into a consistent structure that works seamlessly within Nuxt's plugin system.
```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
// Doing something with nuxtApp
})
```
## Type
```ts [Signature]
export function defineNuxtPlugin> (plugin: Plugin | ObjectPlugin): Plugin & ObjectPlugin
type Plugin = (nuxt: NuxtApp) => Promise | Promise<{ provide?: T }> | void | { provide?: T }
interface ObjectPlugin {
name?: string
enforce?: 'pre' | 'default' | 'post'
dependsOn?: string[]
order?: number
parallel?: boolean
setup?: Plugin
hooks?: Partial
env?: {
islands?: boolean
}
}
```
## Parameters
**plugin**: A plugin can be defined in two ways:
1. **Function Plugin**: A function that receives the [`NuxtApp`](/docs/4.x/guide/going-further/internals#the-nuxtapp-interface) instance and can return a promise with a potential object with a [`provide`](/docs/4.x/directory-structure/app/plugins#providing-helpers) property if you want to provide a helper on [`NuxtApp`](/docs/4.x/guide/going-further/internals#the-nuxtapp-interface) instance.
2. **Object Plugin**: An object that can include various properties to configure the plugin's behavior, such as `name`, `enforce`, `dependsOn`, `order`, `parallel`, `setup`, `hooks`, and `env`.
Property
Type
Required
Description
name
string
false
Optional name for the plugin, useful for debugging and dependency management.
enforce
'pre'
|
'default'
|
'post'
false
Controls when the plugin runs relative to other plugins.
dependsOn
string[]
false
Array of plugin names this plugin depends on. Ensures proper execution order.
order
number
false
This allows more granular control over plugin order and should only be used by advanced users.
It overrides the value of
enforce
and is used to sort plugins.
parallel
boolean
false
Whether to execute the plugin in parallel with other parallel plugins.
setup
Plugin
<
T
>
false
The main plugin function, equivalent to a function plugin.
hooks
Partial
<
RuntimeNuxtHooks
>
false
Nuxt app runtime hooks to register directly.
env
{
islands
?:
boolean
}
false
Set this value to
false
if you don't want the plugin to run when rendering server-only or island components.
## Examples
### Basic Usage
The example below demonstrates a simple plugin that adds global functionality:
```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
// Add a global method
return {
provide: {
hello: (name: string) => `Hello ${name}!`,
},
}
})
```
### Object Syntax Plugin
The example below shows the object syntax with advanced configuration:
```ts [plugins/advanced.ts]twoslash
export default defineNuxtPlugin({
name: 'my-plugin',
enforce: 'pre',
async setup (nuxtApp) {
// Plugin setup logic
const data = await $fetch('/api/config')
return {
provide: {
config: data,
},
}
},
hooks: {
'app:created' () {
console.log('App created!')
},
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/define-nuxt-route-middleware.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/define-nuxt-route-middleware.md
# defineNuxtRouteMiddleware
> Create named route middleware using defineNuxtRouteMiddleware helper function.
Route middleware are stored in the [`app/middleware/`](/docs/4.x/directory-structure/app/middleware) of your Nuxt application (unless [set otherwise](/docs/4.x/api/nuxt-config#middleware)).
## Type
```ts [Signature]
export function defineNuxtRouteMiddleware (middleware: RouteMiddleware): RouteMiddleware
interface RouteMiddleware {
(to: RouteLocationNormalized, from: RouteLocationNormalized): ReturnType
}
```
## Parameters
### `middleware`
- **Type**: `RouteMiddleware`
A function that takes two Vue Router's route location objects as parameters: the next route `to` as the first, and the current route `from` as the second.
Learn more about available properties of `RouteLocationNormalized` in the **Vue Router docs**.
## Examples
### Showing Error Page
You can use route middleware to throw errors and show helpful error messages:
```ts [app/middleware/error.ts]
export default defineNuxtRouteMiddleware((to) => {
if (to.params.id === '1') {
throw createError({ status: 404, statusText: 'Page Not Found' })
}
})
```
The above route middleware will redirect a user to the custom error page defined in the `~/error.vue` file, and expose the error message and code passed from the middleware.
### Redirection
Use [`useState`](/docs/4.x/api/composables/use-state) in combination with `navigateTo` helper function inside the route middleware to redirect users to different routes based on their authentication status:
```ts [app/middleware/auth.ts]
export default defineNuxtRouteMiddleware((to, from) => {
const auth = useState('auth')
if (!auth.value.isAuthenticated) {
return navigateTo('/login')
}
if (to.path !== '/dashboard') {
return navigateTo('/dashboard')
}
})
```
Both [navigateTo](/docs/4.x/api/utils/navigate-to) and [abortNavigation](/docs/4.x/api/utils/abort-navigation) are globally available helper functions that you can use inside `defineNuxtRouteMiddleware`.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/define-page-meta.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/define-page-meta.md
# definePageMeta
> Define metadata for your page components.
`definePageMeta` is a compiler macro that you can use to set metadata for your **page** components located in the [`app/pages/`](/docs/4.x/directory-structure/app/pages) directory (unless [set otherwise](/docs/4.x/api/nuxt-config#pages)). This way you can set custom metadata for each static or dynamic route of your Nuxt application.
```vue [app/pages/some-page.vue]
```
## Type
```ts [Signature]
export function definePageMeta (meta: PageMeta): void
interface PageMeta {
validate?: ((route: RouteLocationNormalized) => boolean | Promise | Partial | Promise>)
redirect?: RouteRecordRedirectOption
name?: string
path?: string
props?: RouteRecordRaw['props']
alias?: string | string[]
groups?: string[]
pageTransition?: boolean | TransitionProps
layoutTransition?: boolean | TransitionProps
viewTransition?: boolean | 'always'
key?: false | string | ((route: RouteLocationNormalizedLoaded) => string)
keepalive?: boolean | KeepAliveProps
layout?: false | LayoutKey | Ref | ComputedRef
middleware?: MiddlewareKey | NavigationGuard | Array
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
[key: string]: unknown
}
```
## Parameters
### `meta`
- **Type**: `PageMeta`
An object accepting the following page metadata:
**name**
- **Type**: `string`
You may define a name for this page's route. By default, name is generated based on path inside the [`app/pages/` directory](/docs/4.x/directory-structure/app/pages).
**path**
- **Type**: `string`
You may define a [custom regular expression](/docs/4.x/api/utils/define-page-meta#using-a-custom-regular-expression) if you have a more complex pattern than can be expressed with the file name.
**props**
- **Type**: [`RouteRecordRaw['props']`](https://router.vuejs.org/guide/essentials/passing-props)
Allows accessing the route `params` as props passed to the page component.
**alias**
- **Type**: `string | string[]`
Aliases for the record. Allows defining extra paths that will behave like a copy of the record. Allows having paths shorthands like `/users/:id` and `/u/:id`. All `alias` and `path` values must share the same params.
**groups**
- **Type**: `string[]`
Route groups the page belongs to, based on the folder structure. Automatically populated for pages within [route groups](/docs/4.x/guide/directory-structure/app/pages#route-groups).
**keepalive**
- **Type**: `boolean` | [`KeepAliveProps`](https://vuejs.org/api/built-in-components#keepalive)
Set to `true` when you want to preserve page state across route changes or use the [`KeepAliveProps`](https://vuejs.org/api/built-in-components#keepalive) for a fine-grained control.
**key**
- **Type**: `false` | `string` | `((route: RouteLocationNormalizedLoaded) => string)`
Set `key` value when you need more control over when the `` component is re-rendered.
**layout**
- **Type**: `false` | `LayoutKey` | `Ref` | `ComputedRef`
Set a static or dynamic name of the layout for each route. This can be set to `false` in case the default layout needs to be disabled.
**layoutTransition**
- **Type**: `boolean` | [`TransitionProps`](https://vuejs.org/api/built-in-components#transition)
Set name of the transition to apply for current layout. You can also set this value to `false` to disable the layout transition.
**middleware**
- **Type**: `MiddlewareKey` | [`NavigationGuard`](https://router.vuejs.org/api/interfaces/navigationguard) | `Array`
Define anonymous or named middleware directly within `definePageMeta`. Learn more about [route middleware](/docs/4.x/directory-structure/app/middleware).
**pageTransition**
- **Type**: `boolean` | [`TransitionProps`](https://vuejs.org/api/built-in-components#transition)
Set name of the transition to apply for current page. You can also set this value to `false` to disable the page transition.
**viewTransition**
- **Type**: `boolean | 'always'`
**Experimental feature, only available when enabled in your nuxt.config file**
Enable/disable View Transitions for the current page.
If set to true, Nuxt will not apply the transition if the users browser matches `prefers-reduced-motion: reduce` (recommended). If set to `always`, Nuxt will always apply the transition.
**redirect**
- **Type**: [`RouteRecordRedirectOption`](https://router.vuejs.org/guide/essentials/redirect-and-alias)
Where to redirect if the route is directly matched. The redirection happens before any navigation guard and triggers a new navigation with the new target location.
**validate**
- **Type**: `(route: RouteLocationNormalized) => boolean | Promise | Partial | Promise>`
Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with `status`/`statusText` to respond immediately with an error (other matches will not be checked).
**scrollToTop**
- **Type**: `boolean | (to: RouteLocationNormalized, from: RouteLocationNormalized) => boolean`
Tell Nuxt to scroll to the top before rendering the page or not. If you want to overwrite the default scroll behavior of Nuxt, you can do so in `~/router.options.ts` (see [custom routing](/docs/4.x/guide/recipes/custom-routing#using-routeroptions)) for more info.
**[key: string]**
- **Type**: `any`
Apart from the above properties, you can also set **custom** metadata. You may wish to do so in a type-safe way by [augmenting the type of the `meta` object](/docs/4.x/directory-structure/app/pages/#typing-custom-metadata).
## Examples
### Basic Usage
The example below demonstrates:
- how `key` can be a function that returns a value;
- how `keepalive` property makes sure that the `` component is not cached when switching between multiple components;
- adding `pageType` as a custom property:
```vue [app/pages/some-page.vue]
```
### Defining Middleware
The example below shows how the middleware can be defined using a `function` directly within the `definePageMeta` or set as a `string` that matches the middleware file name located in the `app/middleware/` directory:
```vue [app/pages/some-page.vue]
```
### Using a Custom Regular Expression
A custom regular expression is a good way to resolve conflicts between overlapping routes, for instance:
The two routes "/test-category" and "/1234-post" match both `[postId]-[postSlug].vue` and `[categorySlug].vue` page routes.
To make sure that we are only matching digits (`\d+`) for `postId` in the `[postId]-[postSlug]` route, we can add the following to the `[postId]-[postSlug].vue` page template:
```vue [app/pages/[postId]-[postSlug].vue]
```
For more examples see [Vue Router's Matching Syntax](https://router.vuejs.org/guide/essentials/route-matching-syntax).
### Defining Layout
You can define the layout that matches the layout's file name located (by default) in the [`app/layouts/` directory](/docs/4.x/directory-structure/app/layouts). You can also disable the layout by setting the `layout` to `false`:
```vue [app/pages/some-page.vue]
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/define-route-rules.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/define-route-rules.md
# defineRouteRules
> Define route rules for hybrid rendering at the page level.
This feature is experimental and in order to use it you must enable the `experimental.inlineRouteRules` option in your `nuxt.config`.
## Usage
```vue [app/pages/index.vue]
Hello world!
```
Will be translated to:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
},
})
```
When running [`nuxt build`](/docs/4.x/api/commands/build), the home page will be pre-rendered in `.output/public/index.html` and statically served.
## Notes
- A rule defined in `~/pages/foo/bar.vue` will be applied to `/foo/bar` requests.
- A rule in `~/pages/foo/[id].vue` will be applied to `/foo/**` requests.
For more control, such as if you are using a custom `path` or `alias` set in the page's [`definePageMeta`](/docs/4.x/api/utils/define-page-meta), you should set `routeRules` directly within your `nuxt.config`.
Read more about the `routeRules`.
---
# Source: https://nuxt.com/raw/deploy/deno-deploy.md
# Deno Deploy
> Deploy your Nuxt Application to Deno Deploy infrastructure.
Deno deploy preset is experimental.
## Deploy with the CLI
You can use [deployctl](https://deno.com/deploy/docs/deployctl) to deploy your app.
Login to [Deno Deploy](https://dash.deno.com/account#access-tokens) to obtain a `DENO_DEPLOY_TOKEN` access token, and set it as an environment variable.
```bash
# Build with the deno_deploy preset
npm run build --preset=deno_deploy
# Make sure to run the deployctl command from the output directory
cd .output
deployctl deploy --project=my-project server/index.ts --token=
```
## Deploy within CI/CD using GitHub Actions
Link your GitHub repository to your Deno Deploy project and choose the "GitHub Actions" deployment mode. You can do this in your project settings on [https://dash.deno.com](https://dash.deno.com).
Create a GitHub action file in your repository:
```yaml [.github/workflows/deno_deploy.yml]
name: deno-deploy
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
deploy:
steps:
- uses: actions/checkout@v3
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 18
cache: pnpm
- run: pnpm install
- run: pnpm build
env:
NITRO_PRESET: deno_deploy
- name: Deploy to Deno Deploy
uses: denoland/deployctl@v1
with:
project:
entrypoint: server/index.ts
root: .output
```
Make sure to rename `` with your project name.
## Templates
A collaborative todo-list app built with Deno KV and Nuxt.
## Learn more
Head over **Nitro documentation** to learn more about the deno-deploy deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/getting-started/deployment.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/deployment.md
# Deployment
> Learn how to deploy your Nuxt application to any hosting provider.
A Nuxt application can be deployed on a Node.js server, pre-rendered for static hosting, or deployed to serverless or edge (CDN) environments.
If you are looking for a list of cloud providers that support Nuxt, see the [Hosting providers](/deploy) section.
## Node.js Server
Discover the Node.js server preset with Nitro to deploy on any Node hosting.
- **Default output format** if none is specified or auto-detected
- Loads only the required chunks to render the request for optimal cold start timing
- Useful for deploying Nuxt apps to any Node.js hosting
### Entry Point
When running `nuxt build` with the Node server preset, the result will be an entry point that launches a ready-to-run Node server.
```bash [Terminal]
node .output/server/index.mjs
```
This will launch your production Nuxt server that listens on port 3000 by default.
It respects the following runtime environment variables:
- `NITRO_PORT` or `PORT` (defaults to `3000`)
- `NITRO_HOST` or `HOST` (defaults to `'0.0.0.0'`)
- `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL.
### PM2
[PM2](https://pm2.keymetrics.io/) (Process Manager 2) is a fast and easy solution for hosting your Nuxt application on your server or VM.
To use `pm2`, use an `ecosystem.config.cjs`:
```ts [ecosystem.config.cjs]
module.exports = {
apps: [
{
name: 'NuxtAppName',
port: '3000',
exec_mode: 'cluster',
instances: 'max',
script: './.output/server/index.mjs',
},
],
}
```
### Cluster Mode
You can use `NITRO_PRESET=node_cluster` in order to leverage multi-process performance using Node.js [cluster](https://nodejs.org/dist/latest/docs/api/cluster.html) module.
By default, the workload gets distributed to the workers with the round robin strategy.
### Learn More
## Static Hosting
There are two ways to deploy a Nuxt application to any static hosting services:
- Static site generation (SSG) with `ssr: true` pre-renders routes of your application at build time. (This is the default behavior when running `nuxt generate`.) It will also generate `/200.html` and `/404.html` single-page app fallback pages, which can render dynamic routes or 404 errors on the client (though you may need to configure this on your static host).
- Alternatively, you can prerender your site with `ssr: false` (static single-page app). This will produce HTML pages with an empty `` where your Vue app would normally be rendered. You will lose many SEO benefits of prerendering your site, so it is suggested instead to use [``](/docs/4.x/api/components/client-only) to wrap the portions of your site that cannot be server rendered (if any).
### Client-side Only Rendering
If you don't want to pre-render your routes, another way of using static hosting is to set the `ssr` property to `false` in the `nuxt.config` file. The `nuxt generate` command will then output an `.output/public/index.html` entrypoint and JavaScript bundles like a classic client-side Vue.js application.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
ssr: false,
})
```
## Hosting Providers
Nuxt can be deployed to several cloud providers with a minimal amount of configuration:
## Presets
In addition to Node.js servers and static hosting services, a Nuxt project can be deployed with several well-tested presets and minimal amount of configuration.
You can explicitly set the desired preset in the [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file:
```ts [nuxt.config.ts]twoslash
// @errors: 2353
export default defineNuxtConfig({
nitro: {
preset: 'node-server',
},
})
```
... or use the `NITRO_PRESET` environment variable when running `nuxt build`:
```bash [Terminal]
NITRO_PRESET=node-server nuxt build
```
🔎 Check [the Nitro deployment](https://nitro.build/deploy) for all possible deployment presets and providers.
## CDN Proxy
In most cases, Nuxt can work with third-party content that is not generated or created by Nuxt itself. But sometimes such content can cause problems, especially Cloudflare's "Minification and Security Options".
Accordingly, you should make sure that the following options are unchecked / disabled in Cloudflare. Otherwise, unnecessary re-rendering or hydration errors could impact your production application.
1. Speed > Optimization > Content Optimization > Disable "Rocket Loader™"
2. Speed > Optimization > Image Optimization > Disable "Mirage"
3. Scrape Shield > Disable "Email Address Obfuscation"
With these settings, you can be sure that Cloudflare won't inject scripts into your Nuxt application that may cause unwanted side effects.
Their location on the Cloudflare dashboard sometimes changes so don't hesitate to look around.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/dev-only.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/dev-only.md
#
> Render components only during development with the component.
Nuxt provides the `` component to render a component only during development.
The content will not be included in production builds.
```vue [app/pages/example.vue]
```
## Slots
- `#fallback`: if you ever require to have a replacement during production.
```vue
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/dev.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/dev.md
# nuxt dev
> The dev command starts a development server with hot module replacement at http://localhost:3000
```bash [Terminal]
npx nuxt dev [ROOTDIR] [--cwd=] [--logLevel=] [--dotenv] [--envName] [-e, --extends=] [--clear] [--no-f, --no-fork] [-p, --port] [-h, --host] [--clipboard] [-o, --open] [--https] [--publicURL] [--qr] [--public] [--tunnel] [--sslCert] [--sslKey]
```
The `dev` command starts a development server with hot module replacement at [http://localhost:3000](https://localhost:3000)
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--dotenv
Path to
.env
file to load, relative to the root directory
--envName
The environment to use when resolving configuration overrides (default is
production
when building, and
development
when running the dev server)
-e, --extends=
Extend from a Nuxt layer
--clear
false
Clear console on restart
--no-f, --no-fork
Disable forked mode
-p, --port
Port to listen on (default:
NUXT_PORT || NITRO_PORT || PORT || nuxtOptions.devServer.port
)
-h, --host
Host to listen on (default:
NUXT_HOST || NITRO_HOST || HOST || nuxtOptions.devServer?.host
)
The port and host can also be set via NUXT_PORT, PORT, NUXT_HOST or HOST environment variables.
Additionally to the above options, `@nuxt/cli` can pass options through to `listhen`, e.g. `--no-qr` to turn off the dev server QR code. You can find the list of `listhen` options in the [unjs/listhen](https://github.com/unjs/listhen) docs.
This command sets `process.env.NODE_ENV` to `development`.
If you are using a self-signed certificate in development, you will need to set `NODE_TLS_REJECT_UNAUTHORIZED=0` in your environment.
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/devtools.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/devtools.md
# nuxt devtools
> The devtools command allows you to enable or disable Nuxt DevTools on a per-project basis.
```bash [Terminal]
npx nuxt devtools [ROOTDIR] [--cwd=]
```
Running `nuxt devtools enable` will install the Nuxt DevTools globally, and also enable it within the particular project you are using. It is saved as a preference in your user-level `.nuxtrc`. If you want to remove devtools support for a particular project, you can run `nuxt devtools disable`.
## Arguments
Argument
Description
COMMAND
Command to run (options: )
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
Read more about the **Nuxt DevTools**.
---
# Source: https://nuxt.com/raw/deploy/digitalocean.md
# DigitalOcean
> Deploy your Nuxt Application to DigitalOcean infrastructure.
Nuxt supports deploying on the [DigitalOcean App Platform](https://docs.digitalocean.com/products/app-platform/) with minimal configuration.
## Setup
1. Create a new DigitalOcean app following the [guide](https://docs.digitalocean.com/products/app-platform/how-to/create-apps/).
2. Next, you'll need to configure environment variables. In your app settings, ensure the following [app-level environment variables](https://docs.digitalocean.com/products/app-platform/how-to/use-environment-variables/):```bash
SERVER_PRESET=digital-ocean
```
3. You will need to ensure you set an `engines.node` field in your app's `package.json` to ensure DigitalOcean uses a supported version of Node.js:```json [package.json]
{
"engines": {
"node": "20.x"
}
}
```
4. You'll also need to add a run command so DigitalOcean knows what command to run after a build. You can do so by adding a start script to your `package.json`:```json [package.json]
{
"scripts": {
"start": "node .output/server/index.mjs"
}
}
```
5. Finally, you'll need to add this start script to your DigitalOcean app's run command. Go to `Components > Settings > Commands`, click "Edit", then add `npm run start`
Your Nuxt app should be live at a DigitalOcean generated URL and you can now follow [the rest of the DigitalOcean deployment guide](https://docs.digitalocean.com/products/app-platform/how-to/manage-deployments/).
## Learn more
Head over **Nitro documentation** to learn more about the digitalocean deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure.md
# Nuxt Directory Structure
> Learn about the directory structure of a Nuxt application and how to use it.
Nuxt applications have a specific directory structure that is used to organize the code. This structure is designed to be easy to understand and to be used in a consistent way.
## Root Directory
The root directory of a Nuxt application is the directory that contains the `nuxt.config.ts` file. This file is used to configure the Nuxt application.
## App Directory
The `app/` directory is the main directory of the Nuxt application. It contains the following subdirectories:
- [`assets/`](/docs/4.x/directory-structure/app/assets): website's assets that the build tool (Vite or webpack) will process
- [`components/`](/docs/4.x/directory-structure/app/components): Vue components of the application
- [`composables/`](/docs/4.x/directory-structure/app/composables): add your Vue composables
- [`layouts/`](/docs/4.x/directory-structure/app/layouts): Vue components that wrap around your pages and avoid re-rendering between pages
- [`middleware/`](/docs/4.x/directory-structure/app/middleware): run code before navigating to a particular route
- [`pages/`](/docs/4.x/directory-structure/app/pages): file-based routing to create routes within your web application
- [`plugins/`](/docs/4.x/directory-structure/app/plugins): use Vue plugins and more at the creation of your Nuxt application
- [`utils/`](/docs/4.x/directory-structure/app/utils): add functions throughout your application that can be used in your components, composables, and pages.
This directory also includes specific files:
- [`app.config.ts`](/docs/4.x/directory-structure/app/app-config): a reactive configuration within your application
- [`app.vue`](/docs/4.x/directory-structure/app/app): the root component of your Nuxt application
- [`error.vue`](/docs/4.x/directory-structure/app/error): the error page of your Nuxt application
## Public Directory
The [`public/`](/docs/4.x/directory-structure/public) directory is the directory that contains the public files of the Nuxt application. Files contained within this directory are served at the root and are not modified by the build process.
This is suitable for files that have to keep their names (e.g. `robots.txt`) *or* likely won't change (e.g. `favicon.ico`).
## Server Directory
The [`server/`](/docs/4.x/directory-structure/server) directory is the directory that contains the server-side code of the Nuxt application. It contains the following subdirectories:
- [`api/`](/docs/4.x/directory-structure/server#server-routes): contains the API routes of the application.
- [`routes/`](/docs/4.x/directory-structure/server#server-routes): contains the server routes of the application (e.g. dynamic `/sitemap.xml`).
- [`middleware/`](/docs/4.x/directory-structure/server#server-middleware): run code before a server route is processed
- [`plugins/`](/docs/4.x/directory-structure/server#server-plugins): use plugins and more at the creation of the Nuxt server
- [`utils/`](/docs/4.x/directory-structure/server#server-utilities): add functions throughout your application that can be used in your server code.
## Shared Directory
The [`shared/`](/docs/4.x/directory-structure/shared) directory is the directory that contains the shared code of the Nuxt application and Nuxt server. This code can be used in both the Vue app and the Nitro server.
## Content Directory
The [`content/`](/docs/4.x/directory-structure/content) directory is enabled by the [Nuxt Content](https://content.nuxt.com) module. It is used to create a file-based CMS for your application using Markdown files.
## Modules Directory
The [`modules/`](/docs/4.x/directory-structure/modules) directory is the directory that contains the local modules of the Nuxt application. Modules are used to extend the functionality of the Nuxt application.
## Layers Directory
The [`layers/`](/docs/4.x/directory-structure/layers) directory allows you to organize and share reusable code, components, composables, and configurations. Layers within this directory are automatically registered in your project.
## Nuxt Files
- [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) file is the main configuration file for the Nuxt application.
- [`.nuxtrc`](/docs/4.x/directory-structure/nuxtrc) file is another syntax for configuring the Nuxt application (useful for global configurations).
- [`.nuxtignore`](/docs/4.x/directory-structure/nuxtignore) file is used to ignore files in the root directory during the build phase.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/dollarfetch.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/dollarfetch.md
# $fetch
> Nuxt uses ofetch to expose globally the $fetch helper for making HTTP requests.
Nuxt uses [ofetch](https://github.com/unjs/ofetch) to expose globally the `$fetch` helper for making HTTP requests within your Vue app or API routes.
During server-side rendering, calling `$fetch` to fetch your internal [API routes](/docs/4.x/directory-structure/server) will directly call the relevant function (emulating the request), **saving an additional API call**.
Using `$fetch` in components without wrapping it with [`useAsyncData`](/docs/4.x/api/composables/use-async-data) causes fetching the data twice: initially on the server, then again on the client-side during hydration, because `$fetch` does not transfer state from the server to the client. Thus, the fetch will be executed on both sides because the client has to get the data again.
## Usage
We recommend using [`useFetch`](/docs/4.x/api/composables/use-fetch) or [`useAsyncData`](/docs/4.x/api/composables/use-async-data) + `$fetch` to prevent double data fetching when fetching the component data.
```vue [app/app.vue]
```
You can use `$fetch` in any methods that are executed only on client-side.
```vue [app/pages/contact.vue]
```
`$fetch` is the preferred way to make HTTP calls in Nuxt instead of [@nuxt/http](https://github.com/nuxt/http) and [@nuxtjs/axios](https://github.com/nuxt-community/axios-module) that are made for Nuxt 2.
If you use `$fetch` to call an (external) HTTPS URL with a self-signed certificate in development, you will need to set `NODE_TLS_REJECT_UNAUTHORIZED=0` in your environment.
### Passing Headers and Cookies
When we call `$fetch` in the browser, user headers like `cookie` will be directly sent to the API.
However, during Server-Side Rendering, due to security risks such as **Server-Side Request Forgery (SSRF)** or **Authentication Misuse**, the `$fetch` wouldn't include the user's browser cookies, nor pass on cookies from the fetch response.
```vue [app/pages/index.vue]
```
```ts [server/api/cookies.ts]
export default defineEventHandler((event) => {
const foo = getCookie(event, 'foo')
// ... Do something with the cookie
})
```
If you need to forward headers and cookies on the server, you must manually pass them:
```vue [app/pages/index.vue]
```
However, when calling `useFetch` with a relative URL on the server, Nuxt will use [`useRequestFetch`](/docs/4.x/api/composables/use-request-fetch) to proxy headers and cookies (with the exception of headers not meant to be forwarded, like `host`).
---
# Source: https://nuxt.com/raw/docs/3.x/guide/modules/ecosystem.md
# Source: https://nuxt.com/raw/docs/4.x/guide/modules/ecosystem.md
# Publish & Share Your Module
> Join the Nuxt module ecosystem and publish your module to npm.
The [Nuxt module ecosystem](/modules) represents more than 35 million monthly NPM downloads and provides extended functionalities and integrations with all sort of tools. You can be part of this ecosystem!
Watch Vue School video about Nuxt module types.
## Understand Module Types
**Official modules** are modules prefixed (scoped) with `@nuxt/` (e.g. [`@nuxt/content`](https://content.nuxt.com)). They are made and maintained actively by the Nuxt team. Like with the framework, contributions from the community are more than welcome to help make them better!
**Community modules** are modules prefixed (scoped) with `@nuxtjs/` (e.g. [`@nuxtjs/tailwindcss`](https://tailwindcss.nuxtjs.org)). They are proven modules made and maintained by community members. Again, contributions are welcome from anyone.
**Third-party and other community modules** are modules (often) prefixed with `nuxt-`. Anyone can make them, using this prefix allows these modules to be discoverable on npm. This is the best starting point to draft and try an idea!
**Private or personal modules** are modules made for your own use case or company. They don't need to follow any naming rules to work with Nuxt and are often seen scoped under an npm organization (e.g. `@my-company/nuxt-auth`)
## List Your Module
Any community modules are welcome to be listed on [the module list](/modules). To be listed, [open an issue in the nuxt/modules](https://github.com/nuxt/modules/issues/new?template=module_request.yml) repository. The Nuxt team can help you to apply best practices before listing.
## Join nuxt-modules
By moving your modules to [nuxt-modules](https://github.com/nuxt-modules), there is always someone else to help, and this way, we can join forces to make one perfect solution.
If you have an already published and working module, and want to transfer it to `nuxt-modules`, [open an issue in nuxt/modules](https://github.com/nuxt/modules/issues/new).
By joining `nuxt-modules` we can rename your community module under the `@nuxtjs/` scope and provide a subdomain (e.g. `my-module.nuxtjs.org`) for its documentation.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/env.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/env.md
# .env
> A .env file specifies your build/dev-time environment variables.
This file should be added to your [`.gitignore`](/docs/4.x/directory-structure/gitignore) file to avoid pushing secrets to your repository.
## Dev, Build and Generate Time
Nuxt CLI has built-in [dotenv](https://github.com/motdotla/dotenv) support in development mode and when running [`nuxt build`](/docs/4.x/api/commands/build) and [`nuxt generate`](/docs/4.x/api/commands/generate).
In addition to any process environment variables, if you have a `.env` file in your project root directory, it will be automatically loaded **at dev, build and generate time**. Any environment variables set there will be accessible within your `nuxt.config` file and modules.
```ini [.env]
MY_ENV_VARIABLE=hello
```
Note that removing a variable from `.env` or removing the `.env` file entirely will not unset values that have already been set.
## Custom File
If you want to use a different file - for example, to use `.env.local` or `.env.production` - you can do so by passing the `--dotenv` flag when using the Nuxt CLI.
```bash [Terminal]
npx nuxt dev --dotenv .env.local
```
When updating `.env` in development mode, the Nuxt instance is automatically restarted to apply new values to the `process.env`.
In your application code, you should use [Runtime Config](/docs/4.x/guide/going-further/runtime-config) instead of plain env variables.
## Production
**After your server is built**, you are responsible for setting environment variables when you run the server.
Your `.env` files will not be read at this point. How you do this is different for every environment.
This design decision was made to ensure compatibility across various deployment environments, some of which may not have a traditional file system available, such as serverless platforms or edge networks like Cloudflare Workers.
Since `.env` files are not used in production, you must explicitly set environment variables using the tools and methods provided by your hosting environment. Here are some common approaches:
- You can pass the environment variables as arguments using the terminal:
`$ DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs`
- You can set environment variables in shell configuration files like `.bashrc` or `.profile`.
- Many cloud service providers, such as Vercel, Netlify, and AWS, provide interfaces for setting environment variables via their dashboards, CLI tools or configuration files.
`runtimeConfig`
won't pick up environment variables that don't start with `NUXT_` in production
([https://nuxt.com/docs/4.x/guide/going-further/runtime-config#environment-variables](https://nuxt.com/docs/4.x/guide/going-further/runtime-config#environment-variables)).
## Production Preview
For local production preview purpose, we recommend using [`nuxt preview`](/docs/4.x/api/commands/preview) since using this command, the `.env` file will be loaded into `process.env` for convenience. Note that this command requires dependencies to be installed in the package directory.
Or you could pass the environment variables as arguments using the terminal. For example, on Linux or macOS:
```bash [Terminal]
DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs
```
Note that for a purely static site, it is not possible to set runtime configuration config after your project is prerendered.
If you want to use environment variables set at build time but do not care about updating these down the line (or only need to update them reactively *within* your app) then `appConfig` may be a better choice. You can define `appConfig` both within your `nuxt.config` (using environment variables) and also within an `~/app.config.ts` file in your project.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/error-handling.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/error-handling.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/error-handling.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/error-handling.md
# Error Handling
> Learn how to catch and handle errors in Nuxt.
Nuxt is a full-stack framework, which means there are several sources of unpreventable user runtime errors that can happen in different contexts:
- Errors during the Vue rendering lifecycle (SSR & CSR)
- Server and client startup errors (SSR + CSR)
- Errors during Nitro server lifecycle ([`server/`](/docs/4.x/directory-structure/server) directory)
- Errors downloading JS chunks
**SSR** stands for **Server-Side Rendering** and **CSR** for **Client-Side Rendering**.
## Vue Errors
You can hook into Vue errors using [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle#onerrorcaptured).
In addition, Nuxt provides a [`vue:error`](/docs/4.x/api/advanced/hooks#app-hooks-runtime) hook that will be called if any errors propagate up to the top level.
If you are using an error reporting framework, you can provide a global handler through [`vueApp.config.errorHandler`](https://vuejs.org/api/application#app-config-errorhandler). It will receive all Vue errors, even if they are handled.
```ts [plugins/error-handler.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
// handle error, e.g. report to a service
}
// Also possible
nuxtApp.hook('vue:error', (error, instance, info) => {
// handle error, e.g. report to a service
})
})
```
Note that the `vue:error` hook is based on [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle#onerrorcaptured) lifecycle hook.
## Startup Errors
Nuxt will call the `app:error` hook if there are any errors in starting your Nuxt application.
This includes:
- running [Nuxt plugins](/docs/4.x/directory-structure/app/plugins)
- processing `app:created` and `app:beforeMount` hooks
- rendering your Vue app to HTML (during SSR)
- mounting the app (on client-side), though you should handle this case with `onErrorCaptured` or with `vue:error`
- processing the `app:mounted` hook
## Nitro Server Errors
You cannot currently define a server-side handler for these errors, but can render an error page, see the [Render an Error Page](/docs/4.x/getting-started/error-handling#error-page) section.
## Errors with JS Chunks
You might encounter chunk loading errors due to a network connectivity failure or a new deployment (which invalidates your old, hashed JS chunk URLs). Nuxt provides built-in support for handling chunk loading errors by performing a hard reload when a chunk fails to load during route navigation.
You can change this behavior by setting `experimental.emitRouteChunkError` to `false` (to disable hooking into these errors at all) or to `manual` if you want to handle them yourself. If you want to handle chunk loading errors manually, you can check out the [the automatic implementation](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/plugins/chunk-reload.client.ts) for ideas.
## Error Page
When Nuxt encounters a fatal error (any unhandled error on the server, or an error created with `fatal: true` on the client) it will either render a JSON response (if requested with `Accept: application/json` header) or trigger a full-screen error page.
An error may occur during the server lifecycle when:
- processing your Nuxt plugins
- rendering your Vue app into HTML
- a server API route throws an error
It can also occur on the client side when:
- processing your Nuxt plugins
- before mounting the application (`app:beforeMount` hook)
- mounting your app if the error was not handled with `onErrorCaptured` or `vue:error` hook
- the Vue app is initialized and mounted in browser (`app:mounted`).
Discover all the Nuxt lifecycle hooks.
Customize the default error page by adding `~/error.vue` in the source directory of your application, alongside `app.vue`.
```vue [error.vue]
{{ error?.status }}
```
Read more about `error.vue` and its uses.
For custom errors we highly recommend using `onErrorCaptured` composable that can be called in a page/component setup function or `vue:error` runtime nuxt hook that can be configured in a nuxt plugin.
```ts [plugins/error-handler.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('vue:error', (err) => {
//
})
})
```
When you are ready to remove the error page, you can call the [`clearError`](/docs/4.x/api/utils/clear-error) helper function, which takes an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
Make sure to check before using anything dependent on Nuxt plugins, such as `$route` or `useRouter`, as if a plugin threw an error, then it won't be re-run until you clear the error.
Rendering an error page is an entirely separate page load, meaning any registered middleware will run again. You can use [`useError`](/docs/4.x/getting-started/error-handling#useerror) in middleware to check if an error is being handled.
If you are running on Node 16 and you set any cookies when rendering your error page, they will [overwrite cookies previously set](https://github.com/nuxt/nuxt/pull/20585). We recommend using a newer version of Node as Node 16 reached end-of-life in September 2023.
## Error Utils
### `useError`
```ts [TS Signature]
function useError (): Ref
```
This function will return the global Nuxt error that is being handled.
Read more about `useError` composable.
### `createError`
```ts [TS Signature]
function createError (err: string | { cause, data, message, name, stack, status, statusText, fatal }): Error
```
Create an error object with additional metadata. You can pass a string to be set as the error `message` or an object containing error properties. It is usable in both the Vue and Server portions of your app, and is meant to be thrown.
If you throw an error created with `createError`:
- on server-side, it will trigger a full-screen error page which you can clear with [`clearError`](/docs/4.x/getting-started/error-handling#clearerror).
- on client-side, it will throw a non-fatal error for you to handle. If you need to trigger a full-screen error page, then you can do this by setting `fatal: true`.
```vue [pages/movies/[slug].vue]twoslash
```
The `statusText` property is intended for short, HTTP-compliant status texts (e.g., "Not Found"). It should only contain horizontal tabs, spaces, and visible ASCII characters (`[\t\u0020-\u007E]`).
For any detailed descriptions, multi-line messages, or content with non-ASCII characters, you should always use the `message` property instead.
Read more about `createError` util.
### `showError`
```ts [TS Signature]
function showError (err: string | Error | { status, statusText }): Error
```
You can call this function at any point on client-side, or (on server side) directly within middleware, plugins or `setup()` functions. It will trigger a full-screen error page which you can clear with [`clearError`](/docs/4.x/getting-started/error-handling#clearerror).
It is recommended instead to use `throw createError()`.
Read more about `showError` util.
### `clearError`
```ts [TS Signature]
function clearError (options?: { redirect?: string }): Promise
```
This function will clear the currently handled Nuxt error. It also takes an optional path to redirect to (for example, if you want to navigate to a 'safe' page).
Read more about `clearError` util.
## Render Error in Component
Nuxt also provides a [``](/docs/4.x/api/components/nuxt-error-boundary) component that allows you to handle client-side errors within your app, without replacing your entire site with an error page.
This component is responsible for handling errors that occur within its default slot. On client-side, it will prevent the error from bubbling up to the top level, and will render the `#error` slot instead.
The `#error` slot will receive `error` as a prop. (If you set `error = null` it will trigger re-rendering the default slot; you'll need to ensure that the error is fully resolved first or the error slot will just be rendered a second time.)
If you navigate to another route, the error will be cleared automatically.
```vue [app/pages/index.vue]
You can display the error locally here: {{ error }}
```
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/error.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/error.md
# error.vue
> The error.vue file is the error page in your Nuxt application.
During the lifespan of your application, some errors may appear unexpectedly at runtime. In such case, we can use the `error.vue` file to override the default error files and display the error nicely.
```vue [error.vue]
{{ error.status }}
Go back home
```
Although it is called an 'error page' it's not a route and shouldn't be placed in your `~/pages` directory. For the same reason, you shouldn't use `definePageMeta` within this page. That being said, you can still use layouts in the error file, by utilizing the [`NuxtLayout`](/docs/4.x/api/components/nuxt-layout) component and specifying the name of the layout.
The error page has a single prop - `error` which contains an error for you to handle.
The `error` object provides the following fields:
```ts
interface NuxtError {
status: number
fatal: boolean
unhandled: boolean
statusText?: string
data?: unknown
cause?: unknown
// legacy/deprecated equivalent of `status`
statusCode: number
// legacy/deprecated equivalent of `statusText`
statusMessage?: string
}
```
If you have an error with custom fields they will be lost; you should assign them to `data` instead:
```ts
throw createError({
status: 404,
statusText: 'Page Not Found',
data: {
myCustomField: true,
},
})
```
---
# Source: https://nuxt.com/raw/blog/eslint-module.md
# Refreshed Nuxt ESLint Integrations
> We revamped our ESLint integrations to support ESLint v9 with the flat config, as well as a new module with many more capabilities.
## TL;DR
We revamped our ESLint integrations to support ESLint v9 with the new flat config. Along the way, we have explored many new possibilities to make it more personalized, powerful, and with better developer experience.
You can run the following command to install the new [`@nuxt/eslint`](https://eslint.nuxt.com/packages/module) module:
```bash [Terminal]
npx nuxi module add eslint
```
Continue reading the story or learn more with [the documentation](https://eslint.nuxt.com/packages/module).
## Background
[ESLint](https://eslint.org/) has become an essential tool for today's web development. It helps you to catch errors and enforce a consistent coding style in your project. At Nuxt, we do our best to provide an out-of-the-box experience for ESLint, making it easy to use, configure and follow the best practices we recommend.
Since, both Nuxt and ESLint have evolved a lot. Historically, we ended up with [a few different packages and integrations for ESLint in Nuxt](https://eslint.nuxt.com/guide/faq#package-disambiguation), and it wasn't always obvious which one to use for what purpose. We have received a lot of feedback from our community.
To improve the situation and also make it future-proof, we recently refreshed our ESLint integrations to support [ESLint v9](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/) with the [flat config](https://eslint.org/docs/latest/use/configure/configuration-files). It opens up many more capabilities for customizing your ESLint setup, providing a more straightforward and unified experience.
## Nuxt ESLint Monorepo
We moved ESLint-related packages scattered across different repositories into a single monorepo: [`nuxt/eslint`](https://github.com/nuxt/eslint), with a dedicated new documentation site: [eslint.nuxt.com](https://eslint.nuxt.com/).
To help understand the differences between each package and what to use, we also have a [FAQ](https://eslint.nuxt.com/guide/faq) page comparing them and explaining their scopes.
This monorepo now includes:
- `@nuxt/eslint` - The new, all-in-one ESLint module for Nuxt 3, supporting project-aware ESLint flat config and more.
- `@nuxt/eslint-config` - The unopinionated but customizable shared ESLint config for Nuxt 3. Supports both [the flat config format](https://eslint.org/docs/latest/use/configure/configuration-files) and [the legacy format](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated).
- `@nuxt/eslint-plugin` - The ESLint plugin for Nuxt 3 provides Nuxt-specific rules and configurations.
- Two packages for Nuxt 2 in maintenance mode.
## ESLint Flat Config
Before diving into new Nuxt integrations, let me introduce you to the concept of [ESLint flat config](https://eslint.org/docs/latest/use/configure/configuration-files).
Flat config is a configuration format introduced in ESLint `v8.21.0` as experimental, and became the default format in [ESLint v9](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/).
A quick reference to differentiate:
- **Flat config**: `eslint.config.js` `eslint.config.mjs` etc.
- **Legacy config**: `.eslintrc` `.eslintrc.json` `.eslintrc.js` etc.
### Why Flat Config?
[This blog post from ESLint](https://eslint.org/blog/2022/08/new-config-system-part-1/) explains the motivation behind the flat config system in detail. In short, the legacy `eslintrc` format was designed in the early time of JavaScript, when ES modules and modern JavaScript features were not yet standardized. Many implicit conventions involved, and the `extends` feature makes the final config result hard to understand and predict. Which also makes shared configs hard to maintain and debug.
```jsonc [.eslintrc]
{
"extends": [
// Solve from `import("@nuxtjs/eslint-config").then(mod => mod.default)`
"@nuxtjs",
// Solve from `import("eslint-config-vue").then(mod => mod.default.configs["vue3-recommended"])`
"plugin:vue/vue3-recommended",
],
"rules": {
// ...
}
}
```
The new flat config moves the plugins and configs resolution from ESLint's internal convention to the native ES module resolution. This in turn makes it more explicit and transparent, allowing you to even import it from other modules. Since the flat config is just a JavaScript module, it also opens the door for much more customization.
## Nuxt Presets for Flat Config
In the latest [`@nuxt/eslint-config` package](https://eslint.nuxt.com/packages/config#flat-config-format), we leverage the flexibility we have to provide a factory function that allows you to customize the config presets easily in a more high-level way. Here is an example of how you can use it:
```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt()
```
`@nuxt/eslint-config` starts with an unopinionated base config, which means we only include rules for best practices of TypeScript, Vue and Nuxt, and leave the rest like code style, formatting, etc for you to decide. You can also run [Prettier](https://prettier.io/) alongside for formatting with the defaults.
The config also allows you to opt-in to more opinionated features as needed. For example, if you want ESLint to take care of the formatting as well, you can turn it on by passing `features.stylistic` to the factory function (powered by [ESLint Stylistic](https://eslint.style/)):
```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt({
features: {
stylistic: true
}
})
```
Or tweak your preferences with an options object ([learn more with the options here](https://eslint.style/guide/config-presets#configuration-factory)):
```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt({
features: {
stylistic: {
semi: false,
indent: 2, // 4 or 'tab'
quotes: 'single',
// ... and more
}
}
})
```
And if you are [authoring a Nuxt Module](https://nuxt.com/docs/guide/going-further/modules), you can turn on `features.tooling` to enable the rules for the Nuxt module development:
```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt({
features: {
tooling: true
}
})
```
...and so on. The factory function in flat config allows the presets to cover the complexity of the underlying ESLint configuration, and provide high-level and user-friendly abstractions for end users to customize. All this without requiring users to worry about the internal details.
While this approach offers you a Prettier-like experience with minimal configurations (because it's powered by ESLint), you still get the full flexibility to customize and override fine-grained rules and plugins as needed.
We also made a [`FlatConfigComposer`](https://github.com/antfu/eslint-flat-config-utils#composer) utility from [`eslint-flat-config-utils`](https://github.com/antfu/eslint-flat-config-utils) to make it even easier to override and extend the flat config. The factory function in `@nuxt/eslint-config/flat` returns a `FlatConfigComposer` instance:
```ts [eslint.config.js]
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt({
// ...options for Nuxt integration
})
.append(
// ...append other flat config items
)
.prepend(
// ...prepend other flat config items before the base config
)
// override a specific config item based on their name
.override(
'nuxt/typescript', // specify the name of the target config, or index
{
rules: {
// ...override the rules
'@typescript-eslint/no-unsafe-assignment': 'off'
}
}
)
// an so on, operations are chainable
```
With this approach, we get the best of both worlds: the simplicity and high-level abstraction for easy to use, and the power for customization and fine-tuning.
## Nuxt ESLint Module
Taking this even further, we made the new, all-in-one [`@nuxt/eslint` module](https://eslint.nuxt.com/packages/module) for Nuxt 3. It leverages Nuxt's context to generate project-aware and type-safe ESLint configurations for your project.
### Project-aware Rules
We know that Vue's Style Guide suggests the use of [multi-word names for components](https://vuejs.org/style-guide/rules-essential.html#use-multi-word-component-names) to avoid conflicts with existing and future HTML elements. Thus, in [`eslint-plugin-vue`](https://github.com/vuejs/eslint-plugin-vue), we have the rule [`vue/multi-word-component-names`](https://eslint.vuejs.org/rules/multi-word-component-names.html) enabled by default. It's a good practice to follow, but we know that in a Nuxt project, not all `.vue` files are registered as components. Files like `app.vue`, `pages/index.vue`, `layouts/default.vue`, etc. are not available as components in other Vue files, and the rule will be irrelevant to them.
Usually, we could turn off the rule for those files like:
```js [eslint.config.js]
export default [
{
files: ['*.vue'],
rules: {
'vue/multi-word-component-names': 'error'
}
},
{
files: ['app.vue', 'error.vue', 'pages/**/*.vue', 'layouts/**/*.vue'],
rules: {
// disable the rule for these files
'vue/multi-word-component-names': 'off'
}
}
]
```
It should work for the majority of the cases. However, we know that in Nuxt you can [customize the path for each directory](https://nuxt.com/docs/api/nuxt-config#dir), and [layers](https://nuxt.com/docs/getting-started/layers) allow you to have multiple sources for each directory. This means the linter rules will be less accurate and potentially cause users extra effort to keep them aligned **manually**.
Similarly, we want to have [`vue/no-multiple-template-root`](https://eslint.vuejs.org/rules/no-multiple-template-root.html) enabled only for `pages` and `layouts`, etc. As the cases grow, it becomes unrealistic to ask users to maintain the rules manually.
That's where the magic of `@nuxt/eslint` comes in! It leverages Nuxt's context to generate the configurations and rules specific to your project structure. Very similar to the [`.nuxt/tsconfig.json`](http://nuxt.com/docs/guide/concepts/typescript#auto-generated-types) Nuxt provides, you now also have the project-aware `.nuxt/eslint.config.mjs` to extend from.
To use it, you can add the module to your Nuxt project:
```bash [Terminal]
npx nuxi module add eslint
```
### Config Inspector DevTools Integrations
During the migrations and research for the new flat config, I came up with the idea to make an interactive UI inspector for the flat config and make the configurations more transparent and easier to understand. We have integrated it into [Nuxt DevTools](https://github.com/nuxt/devtools) when you have the `@nuxt/eslint` module installed so you easily access it whenever you need it.

The inspector allows you to see the final resolved configurations, rules and plugins that have been enabled, and do quick matches to see how rules and configurations have applied to specific files. It's great for debugging and learning how ESLint works in your project.
We are delighted that the ESLint team also finds it useful and is interested in having it for the broader ESLint community. We later joined the effort and made it [the official ESLint Config Inspector](https://github.com/eslint/config-inspector) (it's built with Nuxt, by the way). You can read [this announcement post](https://eslint.org/blog/2024/04/eslint-config-inspector/) for more details.
### Type Generation for Rules
One of the main pain points of configuring ESLint was the leak of type information for the rules and configurations. It's hard to know what options are available for a specific rule, and it would require you to jump around the documentation for every rule to figure that out.
Thanks again for the new flat config being dynamic with so many possibilities. We figured out a new tool, [`eslint-typegen`](https://github.com/antfu/eslint-typegen), that we could generate the corresponding types from rules configuration schema for each rule **based on the actual plugins you are using**. This means it's a universal solution that works for any ESLint plugins, and the types are always accurate and up-to-date.
In the `@nuxt/eslint` module, this feature is integrated out-of-box, so that you will get this awesome experience right away:

### Dev Server Checker
With the new module, we took the chance to merge the [`@nuxtjs/eslint-module`](https://github.com/nuxt-modules/eslint) and the dev server checker for ESLint into the new `@nuxt/eslint` module as an opt-in feature.
You might not need this feature most of the time, as your editor integration should already provide ESLint diagnostics right in your editor. However, for some teams that work with different editors and want to ensure ESLint is always running, being able to run ESLint within the dev server might be helpful in some cases.
To enable it, you can set the `checker` option to `true` in the module options:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: [
'@nuxt/eslint'
],
eslint: {
checker: true // <---
}
})
```
Whenever you get some ESLint errors, you will see a warning in the console and the browser. To learn more about this feature, you can check the [documentation](https://eslint.nuxt.com/packages/module#dev-server-checker).
### Module Hooks
Since we are now in the Nuxt module with the codegen capabilities and the project-aware configurations, we can actually do a lot more interesting things with this. One is that we can allow modules to contribute to the ESLint configurations as well. Imagine that in the future, when you install a Nuxt module like `@nuxtjs/i18n` it can automatically enable specific ESLint rules for i18n-related files, or when you install something like `@pinia/nuxt` it can install the Pinia ESLint plugin to enforce the best practices for Pinia, etc.
As an experiment, we made a module [`nuxt-eslint-auto-explicit-import`](https://github.com/antfu/nuxt-eslint-auto-explicit-import) that can do auto inserts for the auto-imports registered in your Nuxt project with a preconfigured ESLint preset. So that you can get the same nice developer experience with auto-imports on using APIs, but still have the auto-inserted explicit imports in your codebase.
This is still in the early stages, and we are still exploring the possibilities and best practices. But we are very excited about the potential and the opportunities it opens up. We will collaborate with the community to see how we can make the most out of it. If you have any ideas or feedback, please do not hesitate to share them with us!
## Ecosystem
At Nuxt, we care a lot about the ecosystem and the community as always. During our explorations to adopt the new flat config and improve the developer experience, we made quite a few tools to reach that goal. All of them are general-purposed and can be used outside of Nuxt:
- [`@eslint/config-inspector`](https://github.com/eslint/config-inspector) - The official ESLint Config Inspector, provides interactive UI for your configs.
- [`eslint-typegen`](https://github.com/antfu/eslint-typegen) - Generate TypeScript types for ESLint rules based on the actual plugins you are using.
- [`eslint-flat-config-utils`](https://github.com/antfu/eslint-flat-config-utils) - Utilities for managing and composing ESLint flat configs.
We are committed to supporting the broader community and collaborating with developers to improve these tools and expand their possibilities. We are excited to see how these tools can benefit the ESLint ecosystem and contribute to the overall developer experience.
## The Future
The flat config format is still fairly new, and ESLint v9 was just released a couple of weeks ago. Plugins and the community are gradually catching up to the new format. It's still in the phase of exploration and experimentation.
Looking ahead, we are eager to see how the ESLint ecosystem will continue to evolve and how we can leverage new capabilities and possibilities to further enhance Nuxt's developer experience. We are dedicated to providing a seamless and powerful development environment for Nuxt users, and we will continue to explore new ideas and collaborate with the community to achieve this goal.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/esm.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/esm.md
# ES Modules
> Nuxt uses native ES modules.
This guide helps explain what ES Modules are and how to make a Nuxt app (or upstream library) compatible with ESM.
## Background
### CommonJS Modules
CommonJS (CJS) is a format introduced by Node.js that allows sharing functionality between isolated JavaScript modules ([read more](https://nodejs.org/api/modules.html)).
You might be already familiar with this syntax:
```js
const a = require('./a')
module.exports.a = a
```
Bundlers like webpack and Rollup support this syntax and allow you to use modules written in CommonJS in the browser.
### ESM Syntax
Most of the time, when people talk about ESM vs. CJS, they are talking about a different syntax for writing [modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules).
```js
import a from './a'
export { a }
```
Before ECMAScript Modules (ESM) became a standard (it took more than 10 years!), tooling like
[webpack](https://webpack.js.org/guides/ecma-script-modules/) and even languages like TypeScript started supporting so-called **ESM syntax**.
However, there are some key differences with actual spec; here's [a helpful explainer](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/).
### What is 'Native' ESM?
You may have been writing your app using ESM syntax for a long time. After all, it's natively supported by the browser, and in Nuxt 2 we compiled all the code you wrote to the appropriate format (CJS for server, ESM for browser).
When adding modules to your package, things were a little different. A sample library might expose both CJS and ESM versions, and let us pick which one we wanted:
```json
{
"name": "sample-library",
"main": "dist/sample-library.cjs.js",
"module": "dist/sample-library.esm.js"
}
```
So in Nuxt 2, the bundler (webpack) would pull in the CJS file ('main') for the server build and use the ESM file ('module') for the client build.
The `module` field is a convention used by bundlers like webpack and Rollup, but is not recognized by Node.js itself. Node.js only uses the [`exports`](https://nodejs.org/api/packages.html#exports) and [`main`](https://nodejs.org/api/packages.html#main) fields for module resolution.
However, in recent Node.js LTS releases, it is now possible to [use native ESM module](https://nodejs.org/api/esm.html) within Node.js. That means that Node.js itself can process JavaScript using ESM syntax, although it doesn't do it by default. The two most common ways to enable ESM syntax are:
- set `"type": "module"` within your `package.json` and keep using `.js` extension
- use the `.mjs` file extensions (recommended)
This is what we do for Nuxt Nitro; we output a `.output/server/index.mjs` file. That tells Node.js to treat this file as a native ES module.
### What Are Valid Imports in a Node.js Context?
When you `import` a module rather than `require` it, Node.js resolves it differently. For example, when you import `sample-library`, Node.js will look for the `exports` entry in that library's `package.json`, or fall back to the `main` entry if `exports` is not defined.
This is also true of dynamic imports, like `const b = await import('sample-library')`.
Node supports the following kinds of imports (see [docs](https://nodejs.org/api/packages.html#determining-module-system)):
1. files ending in `.mjs` - these are expected to use ESM syntax
2. files ending in `.cjs` - these are expected to use CJS syntax
3. files ending in `.js` - these are expected to use CJS syntax unless their `package.json` has `"type": "module"`
### What Kinds of Problems Can There Be?
For a long time module authors have been producing ESM-syntax builds but using conventions like `.esm.js` or `.es.js`, which they have added to the `module` field in their `package.json`. This hasn't been a problem until now because they have only been used by bundlers like webpack, which don't especially care about the file extension.
However, if you try to import a package with an `.esm.js` file in a Node.js ESM context, it won't work, and you'll get an error like:
```bash [Terminal]
(node:22145) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/path/to/index.js:1
export default {}
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:1001:16)
at Module._compile (internal/modules/cjs/loader.js:1049:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
....
at async Object.loadESM (internal/process/esm_loader.js:68:5)
```
You might also get this error if you have a named import from an ESM-syntax build that Node.js thinks is CJS:
```bash [Terminal]
file:///path/to/index.mjs:5
import { named } from 'sample-library'
^^^^^
SyntaxError: Named export 'named' not found. The requested module 'sample-library' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'sample-library';
const { named } = pkg;
at ModuleJob._instantiate (internal/modules/esm/module_job.js:120:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:165:5)
at async Loader.import (internal/modules/esm/loader.js:177:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
```
## Troubleshooting ESM Issues
If you encounter these errors, the issue is almost certainly with the upstream library. They need to [fix their library](/docs/4.x/guide/concepts/esm#library-author-guide) to support being imported by Node.
### Transpiling Libraries
In the meantime, you can tell Nuxt not to try to import these libraries by adding them to `build.transpile`:
```tstwoslash
export default defineNuxtConfig({
build: {
transpile: ['sample-library'],
},
})
```
You may find that you *also* need to add other packages that are being imported by these libraries.
### Aliasing Libraries
In some cases, you may also need to manually alias the library to the CJS version, for example:
```tstwoslash
export default defineNuxtConfig({
alias: {
'sample-library': 'sample-library/dist/sample-library.cjs.js',
},
})
```
### Default Exports
A dependency with CommonJS format, can use `module.exports` or `exports` to provide a default export:
```js [node_modules/cjs-pkg/index.js]
module.exports = { test: 123 }
// or
exports.test = 123
```
This normally works well if we `require` such dependency:
```js [test.cjs]
const pkg = require('cjs-pkg')
console.log(pkg) // { test: 123 }
```
[Node.js in native ESM mode](https://nodejs.org/api/esm.html#interoperability-with-commonjs), [typescript with `esModuleInterop` enabled](https://www.typescriptlang.org/tsconfig/#esModuleInterop) and bundlers such as webpack, provide a compatibility mechanism so that we can default import such library.
This mechanism is often referred to as "interop require default":
```js
import pkg from 'cjs-pkg'
console.log(pkg) // { test: 123 }
```
However, because of the complexities of syntax detection and different bundle formats, there is always a chance that the interop default fails and we end up with something like this:
```js
import pkg from 'cjs-pkg'
console.log(pkg) // { default: { test: 123 } }
```
Also when using dynamic import syntax (in both CJS and ESM files), we always have this situation:
```js
import('cjs-pkg').then(console.log) // [Module: null prototype] { default: { test: '123' } }
```
In this case, we need to manually interop the default export:
```js
// Static import
import { default as pkg } from 'cjs-pkg'
// Dynamic import
import('cjs-pkg').then(m => m.default || m).then(console.log)
```
For handling more complex situations and more safety, we recommend and internally use [mlly](https://github.com/unjs/mlly) in Nuxt that can preserve named exports.
```js
import { interopDefault } from 'mlly'
// Assuming the shape is { default: { foo: 'bar' }, baz: 'qux' }
import myModule from 'my-module'
console.log(interopDefault(myModule)) // { foo: 'bar', baz: 'qux' }
```
## Library Author Guide
The good news is that it's relatively simple to fix issues of ESM compatibility. There are two main options:
1. **You can rename your ESM files to end with .mjs.**
*This is the recommended and simplest approach.* You may have to sort out issues with your library's dependencies and possibly with your build system, but in most cases, this should fix the problem for you. It's also recommended to rename your CJS files to end with `.cjs`, for the greatest explicitness.
2. **You can opt to make your entire library ESM-only**.
This would mean setting `"type": "module"` in your `package.json` and ensuring that your built library uses ESM syntax. However, you may face issues with your dependencies - and this approach means your library can *only* be consumed in an ESM context.
### Migration
The initial step from CJS to ESM is updating any usage of `require` to use `import` instead:
```ts [Before]
module.exports = function () { /* ... */ }
exports.hello = 'world'
```
```ts [After]
export default function () { /* ... */ }
export const hello = 'world'
```
```js [Before]
const myLib = require('my-lib')
```
```js [After]
import myLib from 'my-lib'
// or
const dynamicMyLib = await import('my-lib').then(lib => lib.default || lib)
```
In ESM Modules, unlike CJS, `require`, `require.resolve`, `__filename` and `__dirname` globals are not available
and should be replaced with `import()` and `import.meta.filename`.
```js [Before]
const { join } = require('node:path')
const newDir = join(__dirname, 'new-dir')
```
```js [After]
import { fileURLToPath } from 'node:url'
const newDir = fileURLToPath(new URL('./new-dir', import.meta.url))
```
```js [Before]
const someFile = require.resolve('./lib/foo.js')
```
```js [After]
import { resolvePath } from 'mlly'
const someFile = await resolvePath('my-lib', { url: import.meta.url })
```
### Best Practices
- Prefer named exports rather than default export. This helps reduce CJS conflicts. (see [Default exports](/docs/4.x/guide/concepts/esm#default-exports) section)
- Avoid depending on Node.js built-ins and CommonJS or Node.js-only dependencies as much as possible to make your library usable in Browsers and Edge Workers without needing Nitro polyfills.
- Use new `exports` field with conditional exports. ([read more](https://nodejs.org/api/packages.html#conditional-exports)).
```json
{
"exports": {
".": {
"import": "./dist/mymodule.mjs"
}
}
}
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/events.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/events.md
# Creating Custom Events
> Nuxt provides a powerful event system powered by hookable.
Using events is a great way to decouple your application and allow for more flexible and modular communication between different parts of your code. Events can have multiple listeners that do not depend on each other. For example, you may wish to send an email to your user each time an order has shipped. Instead of coupling your order processing code to your email code, you can emit an event which a listener can receive and use to dispatch an email.
The Nuxt event system is powered by [unjs/hookable](https://github.com/unjs/hookable), which is the same library that powers the Nuxt hooks system.
## Creating Events and Listeners
You can create your own custom events using the `hook` method:
```ts
const nuxtApp = useNuxtApp()
nuxtApp.hook('app:user:registered', (payload) => {
console.log('A new user has registered!', payload)
})
```
To emit an event and notify any listeners, use `callHook`:
```ts
const nuxtApp = useNuxtApp()
await nuxtApp.callHook('app:user:registered', {
id: 1,
name: 'John Doe',
})
```
You can also use the payload object to enable two-way communication between the emitter and listeners. Since the payload is passed by reference, a listener can modify it to send data back to the emitter.
```ts
const nuxtApp = useNuxtApp()
nuxtApp.hook('app:user:registered', (payload) => {
payload.message = 'Welcome to our app!'
})
const payload = {
id: 1,
name: 'John Doe',
}
await nuxtApp.callHook('app:user:registered', {
id: 1,
name: 'John Doe',
})
// payload.message will be 'Welcome to our app!'
```
You can inspect all events using the **Nuxt DevTools** Hooks panel.
Learn more about Nuxt's built-in hooks and how to extend them
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/examples.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/examples.md
# Examples
> Examples of Nuxt Kit utilities in use.
## Accessing Nuxt Vite Config
If you are building an integration that needs access to the runtime Vite or webpack config that Nuxt uses, it is possible to extract this using Kit utilities.
Some examples of projects doing this already:
- [histoire](https://github.com/histoire-dev/histoire/blob/main/packages/histoire-plugin-nuxt/src/index.ts)
- [nuxt-vitest](https://github.com/danielroe/nuxt-vitest/blob/main/packages/nuxt-vitest/src/config.ts)
- [@storybook-vue/nuxt](https://github.com/storybook-vue/storybook-nuxt/blob/main/packages/storybook-nuxt/src/preset.ts)
Here is a brief example of how you might access the Vite config from a project; you could implement a similar approach to get the webpack configuration.
```js
import { buildNuxt, loadNuxt } from '@nuxt/kit'
// https://github.com/nuxt/nuxt/issues/14534
async function getViteConfig () {
const nuxt = await loadNuxt({ cwd: process.cwd(), dev: false, overrides: { ssr: false } })
return new Promise((resolve, reject) => {
nuxt.hook('vite:extend', (config) => {
resolve(config)
throw new Error('_stop_')
})
buildNuxt(nuxt).catch((err) => {
if (!err.toString().includes('_stop_')) {
reject(err)
}
})
}).finally(() => nuxt.close())
}
const viteConfig = await getViteConfig()
console.log(viteConfig)
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/experimental-features.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/experimental-features.md
# Experimental Features
> Enable Nuxt experimental features to unlock new possibilities.
Nuxt includes experimental features that you can enable in your configuration file.
Internally, Nuxt uses `@nuxt/schema` to define these experimental features. You can refer to the [API documentation](/docs/4.x/guide/going-further/experimental-features) or the [source code](https://github.com/nuxt/nuxt/blob/main/packages/schema/src/config/experimental.ts) for more information.
Note that these features are experimental and could be removed or modified in the future.
## alwaysRunFetchOnKeyChange
Whether to run `useFetch` when the key changes, even if it is set to `immediate: false` and it has not been triggered yet.
`useFetch` and `useAsyncData` will always run when the key changes if `immediate: true` or if it has been already triggered.
This flag is disabled by default, but you can enable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
alwaysRunFetchOnKeyChange: true,
},
})
```
## appManifest
Use app manifests to respect route rules on client-side.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
appManifest: false,
},
})
```
## asyncContext
Enable native async context to be accessible for nested composables in Nuxt and in Nitro. This opens the possibility to use composables inside async composables and reduce the chance to get the `Nuxt instance is unavailable` error.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
asyncContext: true,
},
})
```
See full explanation on the GitHub pull-request.
## asyncEntry
Enables generation of an async entry point for the Vue bundle, aiding module federation support.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
asyncEntry: true,
},
})
```
## externalVue
Externalizes `vue`, `@vue/*` and `vue-router` when building.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
externalVue: false,
},
})
```
This feature will likely be removed in a near future.
## extractAsyncDataHandlers
Extracts handler functions from `useAsyncData` and `useLazyAsyncData` calls into separate chunks for improved code splitting and caching efficiency.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
extractAsyncDataHandlers: true,
},
})
```
This feature transforms inline handler functions into dynamically imported chunks:
```vue
```
```vue
```
The benefit of this transformation is that we can split out data fetching logic — while still allowing the code to be loaded if required.
This feature is only recommended for **static builds** with payload extraction, and where data does not need to be re-fetched at runtime.
## emitRouteChunkError
Emits `app:chunkError` hook when there is an error loading vite/webpack chunks. Default behavior is to perform a reload of the new route on navigation to a new route when a chunk fails to load.
By default, Nuxt will also perform a reload of the new route when a chunk fails to load when navigating to a new route (`automatic`).
Setting `automatic-immediate` will lead Nuxt to perform a reload of the current route right when a chunk fails to load (instead of waiting for navigation). This is useful for chunk errors that are not triggered by navigation, e.g., when your Nuxt app fails to load a [lazy component](/docs/4.x/directory-structure/app/components#dynamic-imports). A potential downside of this behavior is undesired reloads, e.g., when your app does not need the chunk that caused the error.
You can disable automatic handling by setting this to `false`, or handle chunk errors manually by setting it to `manual`.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
emitRouteChunkError: 'automatic', // or 'automatic-immediate', 'manual' or false
},
})
```
## enforceModuleCompatibility
Whether Nuxt should throw an error (and fail to load) if a Nuxt module is incompatible.
This feature is disabled by default.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
enforceModuleCompatibility: true,
},
})
```
## restoreState
Allows Nuxt app state to be restored from `sessionStorage` when reloading the page after a chunk error or manual [`reloadNuxtApp()`](/docs/4.x/api/utils/reload-nuxt-app) call.
To avoid hydration errors, it will be applied only after the Vue app has been mounted, meaning there may be a flicker on initial load.
Consider carefully before enabling this as it can cause unexpected behavior,
and consider providing explicit keys to [`useState`](/docs/4.x/api/composables/use-state) as auto-generated keys may not match across builds.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
restoreState: true,
},
})
```
## inlineRouteRules
Define route rules at the page level using [`defineRouteRules`](/docs/4.x/api/utils/define-route-rules).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
inlineRouteRules: true,
},
})
```
Matching route rules will be created, based on the page's `path`.
Read more in `defineRouteRules` utility.
## renderJsonPayloads
Allows rendering of JSON payloads with support for revivifying complex types.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
renderJsonPayloads: false,
},
})
```
## noVueServer
Disables Vue server renderer endpoint within Nitro.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
noVueServer: true,
},
})
```
## parseErrorData
Whether to parse `error.data` when rendering a server error page.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
parseErrorData: false,
},
})
```
## payloadExtraction
Enables extraction of payloads of pages generated with `nuxt generate`.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
payloadExtraction: true,
},
})
```
Payload extraction also works for routes using ISR (Incremental Static Regeneration) or SWR (Stale-While-Revalidate) caching strategies. This allows CDNs to cache payload files alongside HTML, improving client-side navigation performance for cached routes.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
payloadExtraction: true,
},
routeRules: {
// Payload files will be generated for these cached routes
'/products/**': { isr: 3600 },
'/blog/**': { swr: true },
},
})
```
## clientFallback
Enables the experimental [``](/docs/4.x/api/components/nuxt-client-fallback) component for rendering content on the client if there's an error in SSR.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
clientFallback: true,
},
})
```
## crossOriginPrefetch
Enables cross-origin prefetch using the Speculation Rules API.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
crossOriginPrefetch: true,
},
})
```
Read more about the **Speculation Rules API**.
## viewTransition
Enables View Transition API integration with client-side router.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
viewTransition: true,
},
})
```
Read more about the **View Transition API**.
## writeEarlyHints
Enables writing of early hints when using node server.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
writeEarlyHints: true,
},
})
```
## componentIslands
Enables experimental component islands support with [``](/docs/4.x/api/components/nuxt-island) and `.island.vue` files.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
componentIslands: true, // false or 'local+remote'
},
})
```
You can follow the server components roadmap on GitHub.
## localLayerAliases
Resolve `~`, `~~`, `@` and `@@` aliases located within layers with respect to their layer source and root directories.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
localLayerAliases: false,
},
})
```
## typedPages
Enable the new experimental typed router using [`unplugin-vue-router`](https://github.com/posva/unplugin-vue-router).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
typedPages: true,
},
})
```
Out of the box, this will enable typed usage of [`navigateTo`](/docs/4.x/api/utils/navigate-to), [``](/docs/4.x/api/components/nuxt-link), [`router.push()`](/docs/4.x/api/composables/use-router) and more.
You can even get typed params within a page by using `const route = useRoute('route-name')`.
If you use `pnpm` without `shamefully-hoist=true`, you will need to have `unplugin-vue-router` installed as a devDependency in order for this feature to work.
## watcher
Set an alternative watcher that will be used as the watching service for Nuxt.
Nuxt uses `chokidar-granular` by default, which will ignore top-level directories
(like `node_modules` and `.git`) that are excluded from watching.
You can set this instead to `parcel` to use `@parcel/watcher`, which may improve
performance in large projects or on Windows platforms.
You can also set this to `chokidar` to watch all files in your source directory.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
watcher: 'chokidar-granular', // 'chokidar' or 'parcel' are also options
},
})
```
## sharedPrerenderData
Nuxt automatically shares payload *data* between pages that are prerendered. This can result in a significant performance improvement when prerendering sites that use `useAsyncData` or `useFetch` and fetch the same data in different pages.
You can disable this feature if needed.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
sharedPrerenderData: false,
},
})
```
It is particularly important when enabling this feature to make sure that any unique key of your data
is always resolvable to the same data. For example, if you are using `useAsyncData` to fetch
data related to a particular page, you should provide a key that uniquely matches that data. (`useFetch`
should do this automatically for you.)
```ts
// This would be unsafe in a dynamic page (e.g. `[slug].vue`) because the route slug makes a difference
// to the data fetched, but Nuxt can't know that because it's not reflected in the key.
const route = useRoute()
const { data } = await useAsyncData(async (_nuxtApp, { signal }) => {
return await $fetch(`/api/my-page/${route.params.slug}`, { signal })
})
// Instead, you should use a key that uniquely identifies the data fetched.
const { data } = await useAsyncData(route.params.slug, async (_nuxtApp, { signal }) => {
return await $fetch(`/api/my-page/${route.params.slug}`, { signal })
})
```
## clientNodeCompat
With this feature, Nuxt will automatically polyfill Node.js imports in the client build using [`unenv`](https://github.com/unjs/unenv).
To make globals like `Buffer` work in the browser, you need to manually inject them.
```ts
import { Buffer } from 'node:buffer'
globalThis.Buffer ||= Buffer
```
## scanPageMeta
Nuxt exposing some route metadata defined in `definePageMeta` at build-time to modules (specifically `alias`, `name`, `path`, `redirect`, `props` and `middleware`).
This only works with static or strings/arrays rather than variables or conditional assignment. See [original issue](https://github.com/nuxt/nuxt/issues/24770) for more information and context.
By default page metadata is only scanned after all routes have been registered in `pages:extend`. Then another hook, `pages:resolved` will be called.
You can disable this feature if it causes issues in your project.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
scanPageMeta: false,
},
})
```
## cookieStore
Enables CookieStore support to listen for cookie updates (if supported by the browser) and refresh `useCookie` ref values.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
cookieStore: false,
},
})
```
Read more about the **CookieStore**.
## buildCache
Caches Nuxt build artifacts based on a hash of the configuration and source files.
This only works for source files within `srcDir` and `serverDir` for the Vue/Nitro parts of your app.
This flag is disabled by default, but you can enable it:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
buildCache: true,
},
})
```
When enabled, changes to the following files will trigger a full rebuild:
```bash [Directory structure]
.nuxtrc
.npmrc
package.json
package-lock.json
yarn.lock
pnpm-lock.yaml
tsconfig.json
bun.lock
bun.lockb
```
In addition, any changes to files within `srcDir` will trigger a rebuild of the Vue client/server bundle. Nitro will always be rebuilt (though work is in progress to allow Nitro to announce its cacheable artifacts and their hashes).
A maximum of 10 cache tarballs are kept.
## checkOutdatedBuildInterval
Set the time interval (in ms) to check for new builds. Disabled when `experimental.appManifest` is `false`.
Set to `false` to disable.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
checkOutdatedBuildInterval: 3600000, // 1 hour, or false to disable
},
})
```
## extraPageMetaExtractionKeys
The `definePageMeta()` macro is a useful way to collect build-time meta about pages. Nuxt itself provides a set list of supported keys which is used to power some of the internal features such as redirects, page aliases and custom paths.
This option allows passing additional keys to extract from the page metadata when using `scanPageMeta`.
```vue
```
```ts
export default defineNuxtConfig({
experimental: {
extraPageMetaExtractionKeys: ['foo'],
},
hooks: {
'pages:resolved' (ctx) {
// ✅ foo is available
},
},
})
```
This allows modules to access additional metadata from the page metadata in the build context. If you are using this within a module, it's recommended also to [augment the `NuxtPage` types with your keys](/docs/4.x/directory-structure/app/pages#typing-custom-metadata).
## navigationRepaint
Wait for a single animation frame before navigation, which gives an opportunity for the browser to repaint, acknowledging user interaction.
It can reduce INP when navigating on prerendered routes.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
navigationRepaint: false,
},
})
```
## normalizeComponentNames
Nuxt updates auto-generated Vue component names to match the full component name you would use to auto-import the component.
If you encounter issues, you can disable this feature.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: false,
},
})
```
By default, if you haven't set it manually, Vue will assign a component name that matches
the filename of the component.
```bash [Directory structure]
├─ components/
├─── SomeFolder/
├───── MyComponent.vue
```
In this case, the component name would be `MyComponent`, as far as Vue is concerned. If you wanted to use `` with it, or identify it in the Vue DevTools, you would need to use this component.
But in order to auto-import it, you would need to use `SomeFolderMyComponent`.
By setting `experimental.normalizeComponentNames`, these two values match, and Vue will generate a component name that matches the Nuxt pattern for component naming.
## spaLoadingTemplateLocation
When rendering a client-only page (with `ssr: false`), we optionally render a loading screen (from `~/spa-loading-template.html`).
It can be set to `within`, which will render it like this:
```html
```
Alternatively, you can render the template alongside the Nuxt app root by setting it to `body`:
```html
```
This avoids a white flash when hydrating a client-only page.
## browserDevtoolsTiming
Enables performance markers for Nuxt hooks in browser devtools. This adds performance markers that you can track in the Performance tab of Chromium-based browsers, which is useful for debugging and optimizing performance.
This is enabled by default in development mode. If you need to disable this feature, it is possible to do so:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
browserDevtoolsTiming: false,
},
})
```
See PR #29922 for implementation details.
Learn more about Chrome DevTools Performance API.
## debugModuleMutation
Records mutations to `nuxt.options` in module context, helping to debug configuration changes made by modules during the Nuxt initialization phase.
This is enabled by default when `debug` mode is enabled. If you need to disable this feature, it is possible to do so:
To enable it explicitly:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
debugModuleMutation: true,
},
})
```
See PR #30555 for implementation details.
## lazyHydration
This enables hydration strategies for `` components, which improves performance by deferring hydration of components until they're needed.
Lazy hydration is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
lazyHydration: false,
},
})
```
Read more about lazy hydration.
## templateImportResolution
Disable resolving imports into Nuxt templates from the path of the module that added the template.
By default, Nuxt attempts to resolve imports in templates relative to the module that added them. Setting this to `false` disables this behavior, which may be useful if you're experiencing resolution conflicts in certain environments.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
templateImportResolution: false,
},
})
```
See PR #31175 for implementation details.
## templateRouteInjection
By default the route object returned by the auto-imported `useRoute()` composable is kept in sync with the current page in view in ``. This is not true for `vue-router`'s exported `useRoute` or for the default `$route` object available in your Vue templates.
By enabling this option a mixin will be injected to keep the `$route` template object in sync with Nuxt's managed `useRoute()`.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
templateRouteInjection: false,
},
})
```
## decorators
This option enables enabling decorator syntax across your entire Nuxt/Nitro app, powered by [esbuild](https://github.com/evanw/esbuild/releases/tag/v0.21.3).
For a long time, TypeScript has had support for decorators via `compilerOptions.experimentalDecorators`. This implementation predated the TC39 standardization process. Now, decorators are a [Stage 3 Proposal](https://github.com/tc39/proposal-decorators), and supported without special configuration in TS 5.0+ (see [https://github.com/microsoft/TypeScript/pull/52582](https://github.com/microsoft/TypeScript/pull/52582) and [https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#decorators](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#decorators)).
Enabling `experimental.decorators` enables support for the TC39 proposal, **NOT** for TypeScript's previous `compilerOptions.experimentalDecorators` implementation.
Note that there may be changes before this finally lands in the JS standard.
### Usage
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
decorators: true,
},
})
```
```ts [app/app.vue]
function something (_method: () => unknown) {
return () => 'decorated'
}
class SomeClass {
@something
public someMethod () {
return 'initial'
}
}
const value = new SomeClass().someMethod()
// this will return 'decorated'
```
## defaults
This allows specifying the default options for core Nuxt components and composables.
These options will likely be moved elsewhere in the future, such as into `app.config` or into the `app/` directory.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: {
componentName: 'NuxtLink',
prefetch: true,
prefetchOn: {
visibility: true,
},
},
useAsyncData: {
deep: true,
},
},
},
})
```
## purgeCachedData
Whether to clean up Nuxt static and asyncData caches on route navigation.
Nuxt will automatically purge cached data from `useAsyncData` and `nuxtApp.static.data`. This helps prevent memory leaks and ensures fresh data is loaded when needed, but it is possible to disable it.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
purgeCachedData: false,
},
})
```
See PR #31379 for implementation details.
## granularCachedData
Whether to call and use the result from `getCachedData` when refreshing data for `useAsyncData` and `useFetch` (whether by `watch`, `refreshNuxtData()`, or a manual `refresh()` call.
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
granularCachedData: false,
},
})
```
See PR #31373 for implementation details.
## headNext
Use head optimisations:
- Add the capo.js head plugin in order to render tags in of the head in a more performant way.
- Uses the hash hydration plugin to reduce initial hydration
This flag is enabled by default, but you can disable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
headNext: false,
},
})
```
## pendingWhenIdle
For `useAsyncData` and `useFetch`, whether `pending` should be `true` when data has not yet started to be fetched.
This flag is disabled by default, but you can enable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
pendingWhenIdle: true,
},
})
```
## entryImportMap
By default, Nuxt improves chunk stability by using an import map to resolve the entry chunk of the bundle.
This injects an import map at the top of your `` tag:
```html
```
Within the script chunks emitted by Vite, imports will be from `#entry`. This means that changes to the entry will not invalidate chunks which are otherwise unchanged.
Nuxt smartly disables this feature if you have configured `vite.build.target` to include a browser that doesn't support import maps, or if you have configured `vite.build.rollupOptions.output.entryFileNames` to a value that does not include `[hash]`.
If you need to disable this feature you can do so:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
entryImportMap: false,
},
// or, better, simply tell vite your desired target
// which nuxt will respect
vite: {
build: {
target: 'safari13',
},
},
})
```
## typescriptPlugin
Enable enhanced TypeScript developer experience with the `@dxup/nuxt` module.
This experimental plugin provides improved TypeScript integration and development tooling for better DX when working with TypeScript in Nuxt applications.
This flag is disabled by default, but you can enable this feature:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
typescriptPlugin: true,
},
})
```
To use this feature, you need to:
- Have `typescript` installed as a dependency
- Configure VS Code to use your workspace TypeScript version (see [VS Code documentation](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript))
Learn more about **@dxup/nuxt**.
## viteEnvironmentApi
Enable Vite 6's new [Environment API](https://vite.dev/guide/api-environment) for improved build configuration and plugin architecture.
When you set `future.compatibilityVersion` to `5`, this feature is enabled by default. You can also enable it explicitly for testing:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
viteEnvironmentApi: true,
},
})
```
The Vite Environment API provides better consistency between development and production builds, more granular control over environment-specific configuration, and improved performance.
Enabling this feature changes how Vite plugins are registered and configured. See the [Vite Environment API migration guide](/docs/4.x/getting-started/upgrade#migration-to-vite-environment-api) for details on updating your plugins.
Learn more about Vite's Environment API.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/features.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/features.md
# Features
> Enable or disable optional Nuxt features to unlock new possibilities.
Some features of Nuxt are available on an opt-in basis, or can be disabled based on your needs.
## `features`
### devLogs
Stream server logs to the client as you are developing. These logs can be handled in the `dev:ssr-logs` hook.
By default, this is enabled in development (when test mode is not active).
If set to `silent`, the logs will not be printed to the browser console.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
features: {
devLogs: true,
},
})
```
### inlineStyles
Inlines styles when rendering HTML. This is currently available only when using Vite.
You can also pass a function that receives the path of a Vue component and returns a boolean indicating whether to inline the styles for that component.
It defaults to `(id) => id.includes('.vue')`.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
features: {
inlineStyles: false, // or a function to determine inlining
},
})
```
### noScripts
Turn off rendering of Nuxt scripts and JavaScript resource hints. Can also be configured granularly within `routeRules`.
You can also disable scripts more granularly within `routeRules`.
If set to 'production' or `true`, JavaScript will be disabled in production mode only. If set to 'all', JavaScript will be disabled in both development and production modes.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
features: {
noScripts: true, // or 'production' | 'all' | false
},
})
```
## `future`
There is also a `future` namespace for early opting-in to new features that will become default in a future (possibly major) version of the framework.
### compatibilityVersion
This enables early access to Nuxt features or flags.
Setting `compatibilityVersion` to `5` changes defaults throughout your Nuxt configuration to opt in to Nuxt v5 behaviour, including enabling the [Vite Environment API](/docs/4.x/guide/going-further/experimental-features#viteenvironmentapi).
```ts
export default defineNuxtConfig({
future: {
compatibilityVersion: 5,
},
})
```
Learn more about testing Nuxt 5.
### multiApp
This enables early access to the experimental multi-app support. You can follow the [tracker issue #21635](https://github.com/nuxt/nuxt/issues/21635) to see the progress of multi-app support in Nuxt.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
future: {
multiApp: true,
},
})
```
### typescriptBundlerResolution
This enables 'Bundler' module resolution mode for TypeScript, which is the recommended setting for frameworks like Nuxt and [Vite](https://vite.dev/guide/performance#reduce-resolve-operations).
It improves type support when using modern libraries with `exports`.
See [the original TypeScript pull request](https://github.com/microsoft/TypeScript/pull/51669).
You can set it to false to use the legacy 'Node' mode, which is the default for TypeScript.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
future: {
typescriptBundlerResolution: false,
},
})
```
---
# Source: https://nuxt.com/raw/deploy/firebase.md
# Firebase
> Deploy your Nuxt Application to Firebase infrastructure.
## Firebase App Hosting (recommended)
You will need to be on the [**Blaze plan**](https://firebase.google.com/pricing) (Pay as you go) to get started.
### Project Setup
1. Go to the Firebase [console](https://console.firebase.google.com/) and set up a new project.
2. Select **Build > App Hosting** from the sidebar.
- You may need to upgrade your billing plan at this step.
3. Click **Get Started**.
- Choose a region.
- Import a GitHub repository (you’ll need to link your GitHub account).
- Configure deployment settings (project root directory and branch), and enable automatic rollouts.
- Choose a unique ID for your backend.
4. Click Finish & Deploy to create your first rollout.
When you deploy with Firebase App Hosting, the App Hosting preset will be run automatically at build time.
## Firebase Functions (deprecated)
This deployment method is deprecated and is not recommended. Firebase App Hosting is the recommended way to deploy Nuxt apps on Firebase.
To use the more recent and recommended generation of Firebase functions, set the `firebase.gen` option to `2`:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
nitro: {
firebase: {
gen: 2
}
}
})
```
If you cannot use configuration for any reason, alternatively you can use `NITRO_FIREBASE_GEN=2` environment variable.
If you already have a deployed version of your website and want to upgrade to 2nd gen, [see the Migration process on Firebase docs](https://firebase.google.com/docs/functions/2nd-gen-upgrade). Namely, the CLI will ask you to delete your existing functions before deploying the new ones.
Comparison between 1st and 2nd generation functions
## Project Setup
You may instead prefer to set up your project with the Firebase CLI, which will fetch your project ID for you, add required dependencies (see above) and even set up automated deployments via GitHub Actions (for hosting only). [Learn about installing the firebase CLI](https://firebase.google.com/docs/cli#windows-npm).
1. Install the latest version of the Firebase CLI.
```bash [Terminal]
npm install -g firebase-tools@latest
```
1. Initialize your Firebase Project
```bash [Terminal]
firebase login
firebase init hosting
```
When prompted, you can enter `.output/public` as the public directory. In the next step, **do not** configure your project as a single-page app.
Once complete, add the following to your `firebase.json` to enable server rendering in Cloud Functions:
```json [firebase.json]
{
"functions": { "source": ".output/server" },
"hosting": [
{
"site": "",
"public": ".output/public",
"cleanUrls": true,
"rewrites": [{ "source": "**", "function": "server" }]
}
]
}
```
## Local Preview
You can preview a local version of your site if you need to test things out without deploying.
```bash
npm run build -- --preset=firebase
firebase emulators:start
```
## Build and Deploy
Deploy to Firebase Hosting by running a Nuxt build and then running the `firebase deploy` command.
```bash
npm run build -- --preset=firebase
firebase deploy
```
## Options
You can set options for Firebase functions in your `nuxt.config.ts` file:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
nitro: {
firebase: {
gen: 2,
httpsOptions: {
region: 'europe-west1',
maxInstances: 3,
},
},
},
});
```
### Runtime Node.js Version
You can set a custom Node.js version in configuration:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
nitro: {
firebase: {
nodeVersion: '18' // Can be '16' or '18' or '20'
},
},
});
```
Firebase tools use the `engines.node` version in `package.json` to determine which node version to use for your functions. Nuxt automatically writes to the `.output/server/package.json` with configured Node.js version.
You might also need to add a runtime key to your `firebase.json` file:
```json [firebase.json]
{
"functions": {
"source": ".output/server",
"runtime": "nodejs20"
}
}
```
You can read more about this in **Firebase Docs**.
## Other Cloud Functions
You may be warned that other cloud functions will be deleted when you deploy your Nuxt project. This is because Nitro will deploy your entire project to firebase functions. If you want to deploy only your Nuxt project, you can use the `--only` flag:
```bash
firebase deploy --only functions:server,hosting
```
Head over to the **Nitro documentation** to learn more about the Firebase deployment preset.
## Using Cookies in Production
When using Firebase Hosting together with Cloud Functions or Cloud Run, cookies are generally stripped from incoming requests to allow for efficient CDN cache behavior. Only the specially-named `__session` cookie is permitted to pass through to your app.
For more information, refer to the **Firebase documentation**.
## Working with Environment Variables
To set environment variables for your Firebase functions, you need to copy the `.env` file to the `.output/server` directory.
You can do this by adding a `postbuild` script to your `package.json`, that will automatically run after the build command:
```json [package.json]
{
"scripts": {
"postbuild": "cp .env .output/server/.env"
}
}
```
For more information, refer to the **Firebase documentation**.
---
# Source: https://nuxt.com/raw/deploy/flightcontrol.md
# Flightcontrol
> Deploy your Nuxt Application to Flightcontrol infrastructure.
Nitro supports deploying to [AWS via Flightcontrol](https://flightcontrol.dev?ref=nuxt) with minimal configuration.
**Zero Configuration ✨**
Integration with Flightcontrol is possible with zero configuration.
## Set Up your Flightcontrol account
On a high level, the steps you will need to follow to deploy a project for the first time are:
1. Create an account at [Flightcontrol](https://app.flightcontrol.dev/signup?ref=nuxt)
2. Create an account at [AWS](https://portal.aws.amazon.com/billing/signup) (if you don't already have one)
3. Link your AWS account to the Flightcontrol
4. Authorize the Flightcontrol GitHub App to access your chosen repositories, public or private.
5. Create a Flightcontrol project with configuration via the Dashboard or with configuration via `flightcontrol.json`.
## Create a Project with Configuration via the Dashboard
1. Create a Flightcontrol project from the Dashboard. Select a repository for the source.
2. Select the `GUI` config type.
3. Select the Nuxt preset.
4. Select your preferred AWS server size.
5. Submit the new project form.
## Create a Project with Configuration via `flightcontrol.json`
1. Create a Flightcontrol project from your dashboard. Select a repository for the source.
2. Select the `flightcontrol.json` config type.
3. Add a new file at the root of your repository called `flightcontrol.json`. Here is an example configuration that creates an AWS fargate service for your app:
```json [flightcontrol.json]
{
"$schema": "https://app.flightcontrol.dev/schema.json",
"environments": [
{
"id": "production",
"name": "Production",
"region": "us-west-2",
"source": {
"branch": "main"
},
"services": [
{
"id": "nitro",
"buildType": "nixpacks",
"name": "My Nitro site",
"type": "fargate",
"domain": "www.yourdomain.com",
"outputDirectory": ".output",
"startCommand": "node .output/server/index.mjs",
"cpu": 0.25,
"memory": 0.5
}
]
}
]
}
```
1. Submit the new project form.
Learn more about Flightcontrol's configuration.
Head over **Nitro documentation** to learn more about the flightcontrol deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/community/framework-contribution.md
# Source: https://nuxt.com/raw/docs/4.x/community/framework-contribution.md
# Framework
> Some specific points about contributions to the framework repository.
Once you've read the [general contribution guide](/docs/4.x/community/contribution), here are some specific points to make about contributions to the [`nuxt/nuxt`](https://github.com/nuxt/nuxt) repository.
## Monorepo Guide
- `packages/kit`: Toolkit for authoring Nuxt modules, published as [`@nuxt/kit`](https://www.npmjs.com/package/@nuxt/kit).
- `packages/nuxt`: The core of Nuxt, published as [`nuxt`](https://www.npmjs.com/package/nuxt).
- `packages/schema`: Cross-version Nuxt typedefs and defaults, published as [`@nuxt/schema`](https://www.npmjs.com/package/@nuxt/schema).
- `packages/rspack`: The [Rspack](https://rspack.rs) bundler for Nuxt, published as [`@nuxt/rspack-builder`](https://www.npmjs.com/package/@nuxt/rspack-builder).
- `packages/vite`: The [Vite](https://vite.dev) bundler for Nuxt, published as [`@nuxt/vite-builder`](https://www.npmjs.com/package/@nuxt/vite-builder).
- `packages/webpack`: The [webpack](https://webpack.js.org) bundler for Nuxt, published as [`@nuxt/webpack-builder`](https://www.npmjs.com/package/@nuxt/webpack-builder).
## Setup
To contribute to Nuxt, you need to set up a local environment.
1. [Fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) the [`nuxt/nuxt`](https://github.com/nuxt/nuxt) repository to your own GitHub account and then [clone](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) it to your local device.
2. Ensure using the latest [Node.js](https://nodejs.org/en)
3. Enable [Corepack](https://github.com/nodejs/corepack) to have `pnpm` and `yarn````bash [Terminal]
corepack enable
```
4. Run `pnpm install --frozen-lockfile` to Install the dependencies with pnpm:
```bash [Terminal]
pnpm install --frozen-lockfile
```
If you are adding a dependency, please use `pnpm add`.
The `pnpm-lock.yaml` file is the source of truth for all Nuxt dependencies.
5. Activate the passive development system
```bash [Terminal]
pnpm dev:prepare
```
6. Check out a branch where you can work and commit your changes:
```bash [Terminal]
git checkout -b my-new-branch
```
Then, test your changes against the [playground](/docs/4.x/community/framework-contribution#playground) and [test](/docs/4.x/community/framework-contribution#testing) your changes before submitting a pull request.
### Playground
While working on a pull request, you will likely want to check if your changes are working correctly.
You can modify the example app in `playground/`, and run:
```bash [Terminal]
pnpm dev
```
Please make sure not to commit it to your branch, but it could be helpful to add some example code to your PR description. This can help reviewers and other Nuxt users understand the feature you've built in-depth.
### Testing
Every new feature should have a corresponding unit test (if possible). The `test/` directory in this repository is currently a work in progress, but do your best to create a new test following the example of what's already there.
Before creating a PR or marking it as ready-to-review, ensure that all tests pass by running:
```bash [Terminal]
pnpm test
```
### Linting
You might have noticed already that we use ESLint to enforce a coding standard.
Before committing your changes, to verify that the code style is correct, run:
```bash [Terminal]
pnpm lint
```
You can use `pnpm lint --fix` to fix most of the style changes.
If there are still errors left, you must correct them manually.
### Documentation
If you are adding a new feature or refactoring or changing the behavior of Nuxt in any other manner, you'll likely want to document the changes. Please include any changes to the docs in the same PR. You don't have to write documentation up on the first commit (but please do so as soon as your pull request is mature enough).
Make sure to make changes according to the [Documentation Style Guide](/docs/4.x/community/contribution#documentation-style-guide).
### Final Checklist
When submitting your PR, there is a simple template that you have to fill out. Please tick all appropriate "answers" in the checklists.
## Documentation Guide
If you spot an area where we can improve documentation or error messages, please do open a PR - even if it's just to fix a typo!
Make sure to make changes according to the [Documentation Style Guide](/docs/4.x/community/contribution#documentation-style-guide).
### Quick Edits
If you spot a typo or want to rephrase a sentence, you can click on the **Edit this page** link located on the right aside in the **Community** section.
Make the change directly in the GitHub interface and open a Pull Request.
### Longer Edits
The documentation content is inside the `docs/` directory of the [nuxt/nuxt](https://github.com/nuxt/nuxt) repository and written in markdown.
To preview the docs locally, follow the steps on [nuxt/nuxt.com](https://github.com/nuxt/nuxt.com) repository.
We recommend that you install the [MDC extension](https://marketplace.visualstudio.com/items?itemName=Nuxt.mdc) for VS Code.
### Linting Docs
Documentation is linted using [MarkdownLint](https://github.com/DavidAnson/markdownlint) and [case police](https://github.com/antfu/case-police) to keep the documentation cohesive.
```bash [Terminal]
pnpm lint:docs
```
You can also run `pnpm lint:docs:fix` to highlight and resolve any lint issues.
### Open a PR
Please make sure your PR title adheres to the [conventional commits](https://www.conventionalcommits.org) guidelines.
```bash [Example of PR title]
docs: update the section about the nuxt.config.ts file
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/generate.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/generate.md
# nuxt generate
> Pre-renders every route of the application and stores the result in plain HTML files.
```bash [Terminal]
npx nuxt generate [ROOTDIR] [--cwd=] [--logLevel=] [--preset] [--dotenv] [--envName] [-e, --extends=]
```
The `generate` command pre-renders every route of your application and stores the result in plain HTML files that you can deploy on any static hosting services. The command triggers the `nuxt build` command with the `prerender` argument set to `true`
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--preset
Nitro server preset
--dotenv
Path to
.env
file to load, relative to the root directory
--envName
The environment to use when resolving configuration overrides (default is
production
when building, and
development
when running the dev server)
-e, --extends=
Extend from a Nuxt layer
Read more about pre-rendering and static hosting.
---
# Source: https://nuxt.com/raw/docs/3.x/community/getting-help.md
# Source: https://nuxt.com/raw/docs/4.x/community/getting-help.md
# Getting Help
> We're a friendly community of developers and we'd love to help.
At some point, you may find that there's an issue you need some help with.
But don't worry! We're a friendly community of developers and we'd love to help.
Get real-time help, exchange with the core team and the community, and stay updated on the latest Nuxt news.
Connect with other Nuxt enthusiasts.
## "I can't figure out how to (...)."
You've read through these docs and you think it should be possible, but it's not clear how. The best thing is to [open a GitHub Discussion](https://github.com/nuxt/nuxt/discussions).
Please don't feel embarrassed about asking a question that you think is easy - we've all been there! ❤️
Everyone you'll encounter is helping out because they care, not because they are paid to do so. The kindest thing to do is make it easy for them to help you. Here are some ideas:
- *Explain what your objective is, not just the problem you're facing.* "I need to ensure my form inputs are accessible, so I'm trying to get the ids to match between server and client."
- *Make sure you've first read the docs and used your favorite search engine*. Let people know by saying something like "I've Googled for 'nuxt script setup' but I couldn't find code examples anywhere."
- *Explain what you've tried.* Tell people the kind of solutions you've experimented with, and why. Often this can make people's advice more relevant to your situation.
- *Share your code.* People probably won't be able to help if they just see an error message or a screenshot - but that all changes if you share your code in a copy/pasteable format - preferably in the form of a minimal reproduction like a CodeSandbox.
And finally, just ask the question! There's no need to [ask permission to ask a question](https://dontasktoask.com) or [wait for someone to reply to your 'hello'](https://www.nohello.com). If you do, you might not get a response because people are waiting for the whole question before engaging.
## "Could there be a bug?"
Something isn't working the way that the docs say that it should. You're not sure if it's a bug. You've searched through the [open issues](https://github.com/nuxt/nuxt/issues) and [discussions](https://github.com/nuxt/nuxt/discussions) but you can't find anything. (if there is a closed issue, please create a new one)
We recommend taking a look at [how to report bugs](/docs/4.x/community/reporting-bugs). Nuxt is still in active development, and every issue helps make it better.
## "I need professional help"
If the community couldn't provide the help you need in the time-frame you have, NuxtLabs offers professional support with the [Nuxt Experts](https://nuxt.com/enterprise/support).
The objective of the Nuxt Expert is to provide support to the Vue ecosystem, while also creating freelance opportunities for those contributing to open-source solutions, thus helping to maintain the sustainability of the ecosystem.
The Nuxt experts are Vue, Nuxt and Vite chosen contributors providing professional support and consulting services.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/modules/getting-started.md
# Source: https://nuxt.com/raw/docs/4.x/guide/modules/getting-started.md
# Create Your First Module
> Learn how to create your first Nuxt module using the official starter template.
## Create a Module
We recommend you get started with Nuxt modules using our [starter template](https://github.com/nuxt/starter/tree/module):
```bash [npm]
npm create nuxt -- -t module my-module
```
```bash [yarn]
yarn create nuxt -t module my-module
```
```bash [pnpm]
pnpm create nuxt -t module my-module
```
```bash [bun]
bun create nuxt --template=module my-module
```
This will create a `my-module` project with all the boilerplate necessary to develop and publish your module.
**Next steps:**
1. Open `my-module` in your IDE of choice
2. Install dependencies using your favorite package manager
3. Prepare local files for development using `npm run dev:prepare`
4. Follow this document to learn more about Nuxt modules
## Use the Starter Template
Learn how to perform basic tasks with the module starter.
Watch Vue School video about Nuxt module starter template.
### Develop Your Module
While your module source code lives inside the `src` directory, to develop a module you often need a Nuxt application to test it against. That's what the `playground` directory is for. It's a Nuxt application you can tinker with that is already configured to run with your module.
You can interact with the playground like with any Nuxt application.
- Launch its development server with `npm run dev`, it should reload itself as you make changes to your module in the `src` directory
- Build it with `npm run dev:build`
All other `nuxt` commands can be used against the `playground` directory (e.g. `nuxt playground`). Feel free to declare additional `dev:*` scripts within your `package.json` referencing them for convenience.
### Run Tests
The module starter comes with a basic test suite:
- A linter powered by [ESLint](https://eslint.org), run it with `npm run lint`
- A test runner powered by [Vitest](https://vitest.dev), run it with `npm run test` or `npm run test:watch`
Feel free to augment this default test strategy to better suit your needs.
### Build Your Module
Nuxt modules come with their own builder provided by [`@nuxt/module-builder`](https://github.com/nuxt/module-builder#readme). This builder doesn't require any configuration on your end, supports TypeScript, and makes sure your assets are properly bundled to be distributed to other Nuxt applications.
You can build your module by running `npm run prepack`.
While building your module can be useful in some cases, most of the time you won't need to build it on your own: the `playground` takes care of it while developing, and the release script also has you covered when publishing.
### Publish to npm
Before publishing your module to npm, makes sure you have an [npmjs.com](https://www.npmjs.com) account and that you're authenticated to it locally with `npm login`.
While you can publish your module by bumping its version and using the `npm publish` command, the module starter comes with a release script that helps you make sure you publish a working version of your module to npm and more.
To use the release script, first, commit all your changes (we recommend you follow [Conventional Commits](https://www.conventionalcommits.org) to also take advantage of automatic version bump and changelog update), then run the release script with `npm run release`.
When running the release script, the following will happen:
- First, it will run your test suite by:
- Running the linter (`npm run lint`)
- Running unit, integration, and e2e tests (`npm run test`)
- Building the module (`npm run prepack`)
- Then, if your test suite went well, it will proceed to publish your module by:
- Bumping your module version and generating a changelog according to your Conventional Commits
- Publishing the module to npm (for that purpose, the module will be built again to ensure its updated version number is taken into account in the published artifact)
- Pushing a git tag representing the newly published version to your git remote origin
As with other scripts, feel free to fine-tune the default `release` script in your `package.json` to better suit your needs.
---
# Source: https://nuxt.com/raw/deploy/github-pages.md
# GitHub Pages
> Deploy your Nuxt Application to GitHub Pages infrastructure.
Nuxt supports deploying to [GitHub Pages](https://pages.github.com/) with minimal configuration.
GitHub Pages only support static sites, Nuxt will pre-render your application to static HTML files.
If you are **not** using a custom domain, you need to set `NUXT_APP_BASE_URL` to your repository-slug for your build step.
**Example**: `https://.github.io//`: `NUXT_APP_BASE_URL=// npx nuxt build --preset github_pages`
## Setup
Follow the steps to [create a GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site).
## Deployment
Here is an example GitHub Actions workflow to deploy your site to GitHub Pages using the `github_pages` preset:
```yaml [.github/workflows/deploy.yml]
# https://github.com/actions/deploy-pages#usage
name: Deploy to GitHub Pages
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: "20"
# Pick your own package manager and build script
- run: npm install
- run: npx nuxt build --preset github_pages
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./.output/public
# Deployment job
deploy:
# Add a dependency to the build job
needs: build
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github_pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
# Specify runner + deployment step
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
```
Head over **Nitro documentation** to learn more about the github-pages deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/gitignore.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/gitignore.md
# .gitignore
> A .gitignore file specifies intentionally untracked files that git should ignore.
A `.gitignore` file specifies intentionally untracked files that git should ignore.
We recommend having a `.gitignore` file that has **at least** the following entries present:
```bash [.gitignore]
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
# Local env files
.env
.env.*
!.env.example
```
---
# Source: https://nuxt.com/raw/deploy/gitlab.md
# GitLab Pages
> Deploy your Nuxt Application to GitLab Pages.
Nuxt supports deploying on the [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages) with minimal configuration.
GitLab Pages only support static sites, Nuxt will pre-render your application to static HTML files.
If you are **not** using a custom domain, you need to set `NUXT_APP_BASE_URL` to your repository-slug for your build step.
**Example**: `https://.gitlab.io//`: `NUXT_APP_BASE_URL=// npm run generate`
## Deployment
1. Here is an example GitLab Pages workflow to deploy your site to GitLab Pages:
```yaml [.gitlab-ci.yml]
# Job name has to be `pages`. See https://docs.gitlab.com/ee/user/project/pages/#how-it-works
pages:
image: node
before_script:
- npm ci --cache .npm --prefer-offline
script:
# Specify the steps involved to build your app here
- npm run generate
cache: # https://docs.gitlab.com/ee/ci/caching/#cache-nodejs-dependencies
key:
files:
- package-lock.json
paths:
- .npm/
artifacts:
paths:
# The directory that contains the built files to be published
- .output/public
# The directory that contains the built files to be published
publish: .output/public
rules:
# This ensures that only pushes to the default branch
# will trigger a pages deploy
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
```
## Learn more
Head over **GitLab Pages default domain names and URLs** to learn more about the GitLab Pages default domain names.
---
# Source: https://nuxt.com/raw/blog/going-full-static.md
# Going Full Static
> Long awaited features for JAMstack fans has been shipped in v2.13: full static export, improved smart prefetching, integrated crawler, faster re-deploy, built-in web server and new target option for config ⚡️
## Too long to read
1. Upgrade nuxt to `2.14.0`
2. Set `target: 'static'` in your `nuxt.config.js`
3. Run `nuxt generate`
4. That's it ✨
*Bonus: you can run nuxt start to run a local server serving your generated static application.*
Note: in this video we are using `nuxt export` which has been deprecated in favor of `nuxt generate`.
## History
Nuxt had the static generation feature with `nuxt generate` since [v0.3.2](https://github.com/nuxt/nuxt.js/releases/tag/v0.3.2) (November 2016), since then we have improved it in multiple ways but never achieved full static generation. Today I am excited to announce that full static export is now possible with Nuxt 2.13.
## Current issues
`nuxt generate` is mostly pre-rendering, when you navigate client-side, `asyncData` and `fetch` are called, *making a request to your API*. A lot of users asked to support a "full static" mode, meaning to not call these 2 hooks on navigation, since the next page has been already pre-rendered.
Also, the developer experience is not optimal:
- You have access to `req` or `res` on SSR but not when running `nuxt generate`
- `process.static` is `true` only when running `nuxt generate`, making it slow to develop Nuxt modules or plugins for static generation
- You have to specify all your [dynamic routes](https://v2.nuxt.com/docs/features/file-system-routing#dynamic-routes) in `generate.routes`, making it harder since you don't have access to nuxt modules there.
- You cannot test the [SPA fallback](https://v2.nuxt.com/docs/concepts/static-site-generation#spa-fallback) in development, the fallback is a client-only version of your Nuxt application that loads when hitting a 404 page
- `nuxt generate` runs `nuxt build` by default, making it slower to generate your website if only your content changed
Note that it was possible to have full static support with [nuxt-payload-extractor](https://github.com/DreaMinder/nuxt-payload-extractor) module but it was more verbose to use and had limitations.
## New config option: `target`
To improve the user experience as well as telling Nuxt that you want to export your application to static hosting, we are introducing a `target` option in your `nuxt.config.js`:
```vue
```
Full static doesn't work with `ssr: 'false'` (which is the same as the deprecated `mode: 'spa'`) as this is used for client-side rendering only (Single Page Applications).
Running `nuxt dev` with the static target will improve the developer experience:
- Remove `req` & `res` from context
- Fallback to client-side rendering on 404, errors and redirects (see [SPA fallback](https://v2.nuxt.com/docs/concepts/static-site-generation#spa-fallback))
- `$route.query` will always be equal to `{}` on server-side rendering
- `process.static` is `true`
We are also exposing `process.target` for modules author to add logic depending on the user target.
## Smarter `nuxt generate`
Now with `v2.14.0`, you can use `nuxt generate`, it will smartly know if it has to build or not.
### Crazy fast static applications
`nuxt generate` with `target: 'static'` will pre-render all your pages to HTML and save a payload file in order to mock `asyncData` and `fetch` on client-side navigation, this means **no** **more HTTP calls to your API on client-side navigation.** By extracting the page payload to a js file, **it also reduces the HTML size** served as well as preloading it (from the
in the header) for optimal performance.
We also improved the [smart prefetching](/blog/introducing-smart-prefetching) when doing full static, it will also fetch the payloads, making navigation instant 👀
### Crawler integrated
On top of that, it also has a crawler inside, detecting every relative link and generating it:
If you want to exclude a bunch of routes, use the [generate.exclude](https://v2.nuxt.com/docs/configuration-glossary/configuration-generate#exclude). You can keep using [generate.routes](https://v2.nuxt.com/docs/configuration-glossary/configuration-generate#routes) to add extra routes that the crawler could not detect.
To disable the crawler, set `generate.crawler: false` in your `nuxt.config.js`
### Faster re-deploy
By separating `nuxt build` and `nuxt export`, we are opening a new range of improvements: pre-render your pages only if you content has changed, this means: no webpack build → faster re-deployments.
## Smarter `nuxt start`
Once you statically generated your Nuxt app into `dist/`, use `nuxt start` to start a production HTTP server and serve your static app, supporting [SPA Fallback](https://v2.nuxt.com/docs/concepts/static-site-generation#spa-fallback).
This command is perfect to locally test your static application before pushing to your favorite static hosting provider.
## Preview mode
We do support live preview out of the box to keep calling your API:
```js [plugins/preview.client.js]
export default async function ({ query, enablePreview }) {
if (query.preview) {
enablePreview()
}
}
```
It will automatically refresh the page data (calling `nuxtServerInit`, `asyncData` and `fetch`).
When the preview mode is activated, `asyncData` and `fetch` original methods will be called.
## Commands
Depending of the `target`, you can run these commands.
- `server`
- `nuxt dev`: Start the development server
- `nuxt build`: Bundle your Nuxt application for production
- `nuxt start`: Start the production server
- `static`
- `nuxt dev`: Start the development server (static aware)
- `nuxt generate`: Bundle your Nuxt application for production if needed (static aware) and export your application to static HTML in `dist/` directory
- `nuxt start`: Serve your production application from `dist/`
### What to do next
Learn more about how to move from `@nuxtjs/dotenv` to runtime config.
---
# Source: https://nuxt.com/raw/docs/3.x/guide.md
# Source: https://nuxt.com/raw/docs/4.x/guide.md
# Nuxt Guide
> Learn how Nuxt works with in-depth guides.
Discover the main concepts behind Nuxt, from auto-import, hybrid rendering to its TypeScript support.
Learn about best practices when developing with Nuxt.
Integrate AI tools into your Nuxt workflow with MCP Server and LLMs.txt.
Learn how to create Nuxt modules to integrate, enhance or extend any Nuxt application.
Find solutions to common problems and learn how to implement them in your Nuxt project.
Master Nuxt with advanced concepts like experimental features, hooks, and more.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/hello-world.md
# Source: https://nuxt.com/raw/docs/4.x/examples/hello-world.md
# Hello World
> A minimal Nuxt application only requires the `app.vue` and `nuxt.config.js` files.
---
# Source: https://nuxt.com/raw/deploy/heroku.md
# Heroku
> Deploy your Nuxt Application to Heroku infrastructure.
Nuxt supports deploying on [Heroku](https://heroku.com/) with minimal configuration.
## Using the Heroku CLI
1. Create a new Heroku app.```bash [Terminal]
heroku create myapp
```
2. Configure Heroku to use the nodejs buildpack.```bash [Terminal]
heroku buildpacks:set heroku/nodejs
```
3. Configure your app.```bash [Terminal]
heroku config:set SERVER_PRESET=heroku
```
4. Ensure you have `start` and `build` commands in your `package.json` file.```json [package.json]
{
"scripts": {
"build": "nuxt build",
"start": "node .output/server/index.mjs"
}
}
```
## Learn more
Head over **Nitro documentation** to learn more about the Heroku deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/api/advanced/hooks.md
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/hooks.md
# Source: https://nuxt.com/raw/docs/4.x/api/advanced/hooks.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/hooks.md
# Lifecycle Hooks
> Nuxt provides a powerful hooking system to expand almost every aspect using hooks.
The hooking system is powered by [unjs/hookable](https://github.com/unjs/hookable).
## Nuxt Hooks (Build Time)
These hooks are available for [Nuxt modules](/docs/4.x/guide/modules) and build context.
### Within `nuxt.config.ts`
```ts [nuxt.config.ts]
export default defineNuxtConfig({
hooks: {
close: () => { },
},
})
```
### Within Nuxt Modules
```js
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
nuxt.hook('close', async () => { })
},
})
```
Explore all available Nuxt hooks.
## App Hooks (Runtime)
App hooks can be mainly used by [Nuxt Plugins](/docs/4.x/directory-structure/app/plugins) to hook into rendering lifecycle but could also be used in Vue composables.
```ts [app/plugins/test.ts]
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:start', () => {
/* your code goes here */
})
})
```
Explore all available App hooks.
## Server Hooks (Runtime)
These hooks are available for [server plugins](/docs/4.x/directory-structure/server#server-plugins) to hook into Nitro's runtime behavior.
```ts [~/server/plugins/test.ts]
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
console.log('render:html', html)
html.bodyAppend.push('Appended by custom plugin')
})
nitroApp.hooks.hook('render:response', (response, { event }) => {
console.log('render:response', response)
})
})
```
Learn more about available Nitro lifecycle hooks.
## Adding Custom Hooks
You can define your own custom hooks support by extending Nuxt's hook interfaces.
```ts
import type { HookResult } from '@nuxt/schema'
declare module '#app' {
interface RuntimeNuxtHooks {
'your-nuxt-runtime-hook': () => HookResult
}
interface NuxtHooks {
'your-nuxt-hook': () => HookResult
}
}
declare module 'nitropack/types' {
interface NitroRuntimeHooks {
'your-nitro-hook': () => void
}
}
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/best-practices/hydration.md
# Source: https://nuxt.com/raw/docs/4.x/guide/best-practices/hydration.md
# Nuxt and hydration
> Why fixing hydration issues is important
When developing, you may face hydration issues. Don't ignore those warnings.
# Why is it important to fix them?
Hydration mismatches are not just warnings - they are indicators of serious problems that can break your application:
## Performance Impact
- **Increased time to interactive**: Hydration errors force Vue to re-render the entire component tree, which will increase the time for your Nuxt app to become interactive
- **Poor user experience**: Users may see content flashing or unexpected layout shifts
## Functionality Issues
- **Broken interactivity**: Event listeners may not attach properly, leaving buttons and forms non-functional
- **State inconsistencies**: Application state can become out of sync between what the user sees and what the application thinks is rendered
- **SEO problems**: Search engines may index different content than what users actually see
# How to detect them
## Development Console Warnings
Vue will log hydration mismatch warnings in the browser console during development:

# Common reasons
## Browser-only APIs in Server Context
**Problem**: Using browser-specific APIs during server-side rendering.
```html
User preference: {{ userTheme }}
```
**Solution**: You can use [`useCookie`](/docs/4.x/api/composables/use-cookie):
```html
User preference: {{ userTheme }}
```
## Inconsistent Data
**Problem**: Different data between server and client.
```html
{{ Math.random() }}
```
**Solution**: Use SSR-friendly state:
```html
{{ state }}
```
## Conditional Rendering Based on Client State
**Problem**: Using client-only conditions during SSR.
```html
Desktop content
```
**Solution**: Use media queries or handle it client-side:
```html
Desktop content
Mobile content
```
## Third-party Libraries with Side Effects
**Problem**: Libraries that modify the DOM or have browser dependencies (this happens a LOT with tag managers).
```html
```
**Solution**: Initialise libraries after hydration has completed:
```html
```
## Dynamic Content Based on Time
**Problem**: Content that changes based on current time.
```html
{{ greeting }}
```
**Solution**: Use [`NuxtTime`](/docs/4.x/api/components/nuxt-time) component or handle it client-side:
```html
```
```html
{{ greeting }}
Hello!
```
## In summary
1. **Use SSR-friendly composables**: [`useFetch`](/docs/4.x/api/composables/use-fetch), [`useAsyncData`](/docs/4.x/api/composables/use-async-data), [`useState`](/docs/4.x/api/composables/use-state)
2. **Wrap client-only code**: Use [`ClientOnly`](/docs/4.x/api/components/client-only) component for browser-specific content
3. **Consistent data sources**: Ensure server and client uses the same data
4. **Avoid side effects in setup**: Move browser-dependent code to `onMounted`
You can read the [Vue documentation on SSR hydration mismatch](https://vuejs.org/guide/scaling-up/ssr#hydration-mismatch) for a better understanding of hydration.
---
# Source: https://nuxt.com/raw/deploy/iis.md
# IIS
> Deploy your Nuxt Application to IIS infrastructure.
## Using IISnode
1. Install the latest LTS version of [Node.js](https://nodejs.org/en/) on your Windows Server.
2. Install [IISnode](https://github.com/azure/iisnode/releases)
3. Install [IIS `URLRewrite` Module](https://www.iis.net/downloads/microsoft/url-rewrite).
4. In IIS, add `.mjs` as a new mime type and set its content type to `application/javascript`.
5. Build you application with the following command:
```bash [Terminal]
npx nuxi build --preset=iis_node
```
6. Deploy the contents of your `.output` folder to your website in IIS.
## More options
Head over **Nitro documentation** to learn more about the IIS deployment presets.
---
# Source: https://nuxt.com/raw/docs/3.x/api/advanced/import-meta.md
# Source: https://nuxt.com/raw/docs/4.x/api/advanced/import-meta.md
# Import meta
> Understand where your code is running using `import.meta`.
## The `import.meta` object
With ES modules you can obtain some metadata from the code that imports or compiles your ES-module.
This is done through `import.meta`, which is an object that provides your code with this information.
Throughout the Nuxt documentation you may see snippets that use this already to figure out whether the
code is currently running on the client or server side.
Read more about `import.meta`.
## Runtime (App) Properties
These values are statically injected and can be used for tree-shaking your runtime code.
Property
Type
Description
import.meta.client
boolean
True when evaluated on the client side.
import.meta.browser
boolean
True when evaluated on the client side.
import.meta.server
boolean
True when evaluated on the server side.
import.meta.nitro
boolean
True when evaluated on the server side.
import.meta.dev
boolean
True when running the Nuxt dev server.
import.meta.test
boolean
True when running in a test context.
import.meta.prerender
boolean
True when rendering HTML on the server in the prerender stage of your build.
## Builder Properties
These values are available both in modules and in your `nuxt.config`.
Property
Type
Description
import.meta.env
object
Equals
process.env
import.meta.url
string
Resolvable path for the current file.
## Examples
### Using `import.meta.url` to resolve files within modules
```ts [modules/my-module/index.ts]
import { createResolver } from 'nuxt/kit'
// Resolve relative from the current file
const resolver = createResolver(import.meta.url)
export default defineNuxtModule({
meta: { name: 'myModule' },
setup () {
addComponent({
name: 'MyModuleComponent',
// Resolves to '/modules/my-module/components/MyModuleComponent.vue'
filePath: resolver.resolve('./components/MyModuleComponent.vue'),
})
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/info.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/info.md
# nuxt info
> The info command logs information about the current or specified Nuxt project.
```bash [Terminal]
npx nuxt info [ROOTDIR] [--cwd=]
```
The `info` command logs information about the current or specified Nuxt project.
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
Start shell after installation in project directory
--packageManager
Package manager choice (npm, pnpm, yarn, bun)
-M, --modules
Nuxt modules to install (comma separated without spaces)
--no-modules
Skip module installation prompt
--nightly
Use Nuxt nightly release channel (3x or latest)
## Environment variables
- `NUXI_INIT_REGISTRY`: Set to a custom template registry. ([learn more](https://github.com/unjs/giget#custom-registry)).
- Default registry is loaded from [nuxt/starter/templates](https://github.com/nuxt/starter/tree/templates/templates)
---
# Source: https://nuxt.com/raw/docs/3.x/getting-started/installation.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/installation.md
# Installation
> Get started with Nuxt quickly with our online starters or start locally with your terminal.
## Play Online
If you just want to play around with Nuxt in your browser without setting up a project, you can use one of our online sandboxes:
Or follow the steps below to set up a new Nuxt project on your computer.
## New Project
### Prerequisites
- **Node.js** - [`20.x`](https://nodejs.org/en) or newer (but we recommend the [active LTS release](https://github.com/nodejs/release#release-schedule))
- **Text editor** - There is no IDE requirement, but we recommend [Visual Studio Code](https://code.visualstudio.com/) with the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously known as Volar) or [WebStorm](https://www.jetbrains.com/webstorm/), which, along with [other JetBrains IDEs](https://www.jetbrains.com/ides/), offers great Nuxt support right out-of-the-box.
- **Terminal** - In order to run Nuxt commands
Additional notes for an optimal setup:
- **Node.js**: Make sure to use an even numbered version (20, 22, etc.)
- **WSL**: If you are using Windows and experience slow HMR, you may want to try using [WSL (Windows Subsystem for Linux)](https://learn.microsoft.com/en-us/windows/wsl/install) which may solve some performance issues.
- **Windows slow DNS resolution**: Instead of using `localhost:3000` for local dev server on Windows, use `127.0.0.1` for much faster loading experience on browsers.
Open a terminal (if you're using [Visual Studio Code](https://code.visualstudio.com), you can open an [integrated terminal](https://code.visualstudio.com/docs/terminal/basics)) and use the following command to create a new starter project:
```bash [npm]
npm create nuxt@latest
```
```bash [yarn]
yarn create nuxt
```
```bash [pnpm]
pnpm create nuxt@latest
```
```bash [bun]
bun create nuxt@latest
```
```bash [deno]
deno -A npm:create-nuxt@latest
```
Alternatively, you can find other starters or themes by opening [nuxt.new](https://nuxt.new) and following the instructions there.
Open your project folder in Visual Studio Code:
```bash [Terminal]
code
```
Or change directory into your new project from your terminal:
```bash
cd
```
## Development Server
Now you'll be able to start your Nuxt app in development mode:
```bash [npm]
npm run dev -- -o
```
```bash [yarn]
yarn dev --open
```
```bash [pnpm]
pnpm dev -o
```
```bash [bun]
bun run dev -o
# To use the Bun runtime during development
# bun --bun run dev -o
```
```bash [deno]
deno run dev -o
```
Well done! A browser window should automatically open for [http://localhost:3000](http://localhost:3000).
## Next Steps
Now that you've created your Nuxt project, you are ready to start building your application.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/internals.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/internals.md
# How Nuxt Works?
> Nuxt is a minimal but highly customizable framework to build web applications.
This guide helps you better understand Nuxt internals to develop new solutions and module integrations on top of Nuxt.
## The Nuxt Interface
When you start Nuxt in development mode with [`nuxt dev`](/docs/4.x/api/commands/dev) or building a production application with [`nuxt build`](/docs/4.x/api/commands/build),
a common context will be created, referred to as `nuxt` internally. It holds normalized options merged with `nuxt.config` file,
some internal state, and a powerful [hooking system](/docs/4.x/api/advanced/hooks) powered by [unjs/hookable](https://github.com/unjs/hookable)
allowing different components to communicate with each other. You can think of it as **Builder Core**.
This context is globally available to be used with [Nuxt Kit](/docs/4.x/guide/going-further/kit) composables.
Therefore only one instance of Nuxt is allowed to run per process.
To extend the Nuxt interface and hook into different stages of the build process, we can use [Nuxt modules](/docs/4.x/guide/modules).
For more details, check out [the source code](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nuxt.ts).
## The NuxtApp Interface
When rendering a page in the browser or on the server, a shared context will be created, referred to as `nuxtApp`.
This context keeps vue instance, runtime hooks, and internal states like ssrContext and payload for hydration.
You can think of it as **Runtime Core**.
This context can be accessed using [`useNuxtApp()`](/docs/4.x/api/composables/use-nuxt-app) composable within Nuxt plugins and `
About Page
```
Due to the lack of support for virtual `.vue` files by `@vitejs/plugin-vue`, you can work around this limitation by passing `write: true` to the first argument of `addLayout`.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/features/layouts.md
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/layouts.md
# Source: https://nuxt.com/raw/docs/4.x/examples/features/layouts.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/layouts.md
# layouts
> Nuxt provides a layouts framework to extract common UI patterns into reusable layouts.
For best performance, components placed in this directory will be automatically loaded via asynchronous import when used.
## Enable Layouts
Layouts are enabled by adding [``](/docs/4.x/api/components/nuxt-layout) to your [`app.vue`](/docs/4.x/directory-structure/app/app):
```vue [app/app.vue]
```
To use a layout:
- Set a `layout` property in your page with [definePageMeta](/docs/4.x/api/utils/define-page-meta).
- Set the `name` prop of ``.
- Set the `appLayout` property in route rules.
The layout name is normalized to kebab-case, so `someLayout` becomes `some-layout`.
If no layout is specified, `app/layouts/default.vue` will be used.
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/4.x/directory-structure/app/app) instead.
Unlike other components, your layouts must have a single root element to allow Nuxt to apply transitions between layout changes - and this root element cannot be a ``.
## Default Layout
Add a `~/layouts/default.vue`:
```vue [app/layouts/default.vue]
Some default layout content shared across all pages
```
In a layout file, the content of the page will be displayed in the `` component.
## Named Layout
```bash [Directory Structure]
-| layouts/
---| default.vue
---| custom.vue
```
Then you can use the `custom` layout in your page:
```vue [pages/about.vue]twoslash
```
Learn more about `definePageMeta`.
You can directly override the default layout for all pages using the `name` property of [``](/docs/4.x/api/components/nuxt-layout):
```vue [app/app.vue]
```
If you have a layout in nested directories, the layout's name will be based on its own path directory and filename, with duplicate segments being removed.
File
Layout Name
~/layouts/desktop/default.vue
desktop-default
~/layouts/desktop-base/base.vue
desktop-base
~/layouts/desktop/index.vue
desktop
For clarity, we recommend that the layout's filename matches its name:
File
Layout Name
~/layouts/desktop/DesktopDefault.vue
desktop-default
~/layouts/desktop-base/DesktopBase.vue
desktop-base
~/layouts/desktop/Desktop.vue
desktop
## Changing the Layout Dynamically
You can also use the [`setPageLayout`](/docs/4.x/api/utils/set-page-layout) helper to change the layout dynamically:
```vuetwoslash
```
You can also set layouts for specific routes using the `appLayout` property in route rules:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
// Set layout for specific route
'/admin': { appLayout: 'admin' },
// Set layout for multiple routes
'/dashboard/**': { appLayout: 'dashboard' },
// Disable layout for a route
'/landing': { appLayout: false },
},
})
```
This is useful when you want to manage layouts centrally in your configuration rather than in each page file, or when you need to apply layouts to routes that don't have corresponding page components (such as catchall pages which might match many paths).
## Overriding a Layout on a Per-page Basis
If you are using pages, you can take full control by setting `layout: false` and then using the `` component within the page.
```vue [app/pages/index.vue]
Some header template content.
The rest of the page
```
```vue [app/layouts/custom.vue]
Default header content
```
If you use `` within your pages, make sure it is not the root element (or [disable layout/page transitions](/docs/4.x/getting-started/transitions#disable-transitions)).
---
# Source: https://nuxt.com/raw/docs/3.x/guide/ai/llms-txt.md
# Source: https://nuxt.com/raw/docs/4.x/guide/ai/llms-txt.md
# Nuxt LLMs.txt
> How to get AI tools like Cursor, Windsurf, GitHub Copilot, ChatGPT, and Claude to understand Nuxt concepts, APIs, and best practices.
## What is LLMs.txt?
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.
## Available routes
We provide LLMs.txt routes to help AI tools access our documentation:
- **/llms.txt** - Contains a structured overview of all documentation pages and their links (~5K tokens)
- **/llms-full.txt** - Provides comprehensive documentation including getting started guides, API references, blog posts, and deployment guides (~1M+ tokens)
## Choosing the Right File
**Most users should start with /llms.txt** - it contains all essential information and works with standard LLM context windows.
Use `/llms-full.txt` only if you need comprehensive implementation details and your AI tool supports large contexts (200K+ tokens).
## Important usage notes
**@-symbol must be typed manually** - 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.
## Usage with AI Tools
### Cursor
Nuxt provides specialized LLMs.txt files that you can reference in Cursor for better AI assistance with Nuxt development.
#### How to use
1. **Direct reference**: Mention the LLMs.txt URLs when asking questions
2. Add these specific URLs to your project context using `@docs`
[Read more about Cursor Web and Docs Search](https://cursor.com/docs/context/symbols)
### Windsurf
Windsurf can directly access the Nuxt LLMs.txt files to understand framework usage and best practices.
#### Using LLMs.txt with Windsurf
- Use `@docs` to reference specific LLMs.txt URLs
- Create persistent rules referencing these URLs in your workspace
[Read more about Windsurf Web and Docs Search](https://docs.windsurf.com/windsurf/cascade/web-search)
### Other AI Tools
Any AI tool that supports LLMs.txt can use these routes to better understand Nuxt.
#### Examples for ChatGPT, Claude, or other LLMs
- "Using Nuxt documentation from [https://nuxt.com/llms.txt](https://nuxt.com/llms.txt)"
- "Follow complete Nuxt guidelines from [https://nuxt.com/llms-full.txt](https://nuxt.com/llms-full.txt)"
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/locale.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/locale.md
# Locale
> This example shows how to define a locale composable to handle the application's locale, both server and client side.
You can right-click to "View Page Source" and see that Nuxt renders the correct date in SSR based on the visitor's locale.
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/logging.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/logging.md
# Logging
> Nuxt Kit provides a set of utilities to help you work with logging. These functions allow you to log messages with extra features.
Nuxt provides a logger instance that you can use to log messages with extra features. `useLogger` allows you to get a logger instance.
## `useLogger`
Returns a logger instance. It uses [consola](https://github.com/unjs/consola) under the hood.
### Usage
```tstwoslash
import { defineNuxtModule, useLogger } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const logger = useLogger('my-module')
logger.info('Hello from my module!')
},
})
```
### Type
```ts
function useLogger (tag?: string, options?: Partial): ConsolaInstance
```
### Parameters
**tag**: A tag to suffix all log messages with, displayed on the right near the timestamp.
**options**: Consola configuration options.
### Examples
```tstwoslash
import { defineNuxtModule, useLogger } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const logger = useLogger('my-module', { level: options.quiet ? 0 : 3 })
logger.info('Hello from my module!')
},
})
```
---
# Source: https://nuxt.com/raw/blog/looking-forward-2024.md
# Nuxt: Looking forward
> A lot of things have happened for Nuxt over the last year. Sébastien and Daniel share their thoughts on what we've achieved, and where we're going next.
## A Review of 2023 - Sébastien
In January 2023, Daniel set out [**Nuxt: A vision for 2023**](/blog/vision-2023). We achieved most of the goals we set out to accomplish. Some of them are missing and we will tackle them this year!
It was a productive year and the team shipped **9 minor releases**: from v3.1 to v3.9.
In the first 365 days, Nuxt 3 reached new milestones:
-
**49,5K stars** on GitHub ([add yours](https://github.com/nuxt/nuxt) 😊)
-
**27M downloads** on npm
-
**612 contributors** on the [nuxt repository](https://github.com/nuxt/nuxt)
-
**184 modules** created by **142 maintainers**
-
**2,423 closed issues**
-
**1,728 merged pull request**
-
**26,300 members** on [Discord](https://chat.nuxt.dev)
End of October, Nuxt 3 downloads [surpassed Nuxt 2 downloads](https://x.com/Atinux/status/1731980841142669379) 🚀.
The same month, we released [Nuxt Image 1.0](https://image.nuxt.com) with Nuxt 3 support and new features to make sure your website stays performant when using Images. Nuxt now auto-installs it as soon as you start using the [``](/docs/api/components/nuxt-img) or [``](/docs/api/components/nuxt-picture) component.
We shipped [Nuxt DevTools](/blog/nuxt-devtools-v1-0), leveling up the Developer Experience we can expect from a Web framework. I am happy to see that we inspired other frameworks to adopt a similar approach: [Vue DevTools](https://x.com/vuejs/status/1741032977919053865), [Next DevTools](https://x.com/xinyao27/status/1741447261132145133), [Remix DevTools](https://x.com/AlemTuzlak59192/status/1741903214860009539), [Vite Plugin DevTools](https://github.com/pheno-agency/vite-plugin-devtools), [Astro Dev Toolbar](https://x.com/n_moore/status/1732164645778071888) and more.
After many months of building our UI library internally, [Benjamin Canac](https://github.com/benjamincanac) open sourced [Nuxt UI](https://ui.nuxt.com) to let you create websites at a faster pace with highly customizable components built with TailwindCSS.
[Nuxt Content](http://content.nuxt.com) has had 10 minor releases with various improvements: from performance to the MDC syntax. We have some ongoing work to better support [edge rendering](https://nuxt.com/blog/nuxt-on-the-edge) in the future. At the same time, the NuxtLabs team is working on [Nuxt Studio](https://nuxt.studio) to let users edit Markdown files with a Notion-like editor while keeping your content inside your git repository.
## Looking forward into 2024 - Daniel
We are well into 2024, and this update is definitely overdue!
Here are a few thoughts on the direction that I'll be seeking to lead Nuxt in over the next year.
### Continued development and reimagination
I would love to see us continuing to adapt our best practices to the changing needs of the ecosystem, expand the boundaries of what good DX could be, and improve Nuxt.
I am really pleased at what we currently offer in Nuxt. But I would never want to rest on our laurels. We need to keep pursuing new possibilities that appear as the web platform develops. We've committed to [Baseline Compatibility](https://developer.mozilla.org/en-US/docs/Glossary/Baseline/Compatibility) going forward (and are included in conversations about it with the [W3C WebDX Community Group](https://github.com/web-platform-dx/web-features)).
We have some strategies to enable us to do this while also prioritising stability for our existing users, and recognising the scope of the Nuxt ecosystem.
1. In general we follow a pattern of **introducing a module or experimental feature** that can be disabled in testing while we gather feedback and confirm the direction and API of new features.
2. We have adopted the **ecosystem-ci pattern** of validating that our code changes in Nuxt don't break downstream projects unintentionally. If you maintain a well-tested module or library that depends on Nuxt, I'd welcome a PR adding your project to [nuxt/ecosystem-ci](https://github.com/nuxt/ecosystem-ci).
3. We plan to release a **pull-based test** that will allow you to configure your CI to test itself against the latest nightly version of Nuxt to provide early feedback on new Nuxt releases, rather than facing an issue when upgrading.
4. Finally, we have adopted a **push-based approach to updating existing projects**. When we identify breaking changes or improvements that can be rolled out to the ecosystem, we will proactively raise PRs to Nuxt modules (and, to a lesser extent, other open-source projects using Nuxt).
I hope this will allow us to continue to innovate and experiment with new features without sacrificing the stability and maintainability.
In particular, look for active development on the following:
- ✅ [nuxt/fonts](https://github.com/nuxt/fonts) - working up to v1.0.0
- ✅ [nuxt/eslint](https://github.com/nuxt/eslint) - working up to v1.0.0
- 🔥 [nuxt/scripts](https://github.com/nuxt/scripts) - soon to be released
- 🚧 [nuxt/a11y](https://github.com/nuxt/a11y) - coming soon!
- 🚧 [nuxt/auth](https://github.com/nuxt/auth) - coming soon!
- 🚧 [nuxt/hints](https://github.com/nuxt/hints) - coming soon!
### Sustainable open source
I want Nuxt to continue to be an independent, community-driven framework for the long term.
I'm really delighted to see successful businesses founded on Nuxt, and initiatives springing up around Nuxt that become [sponsors](/enterprise/sponsors) or otherwise giving back to the core framework, enabling ongoing Nuxt development.
Obviously, [NuxtLabs](https://nuxtlabs.com) is the preeminent example of that. [Pooya Parsa](https://github.com/pi0), [Anthony Fu](https://github.com/antfu) and I are all able to work full-time on open source thanks to their paid services around Nuxt: [Nuxt UI Pro](https://ui.nuxt.com/pro/getting-started), [Nuxt Experts](/enterprise/support), [Nuxt Studio](https://nuxt.studio/) and [NuxtHub](https://hub.nuxt.com/) (soon). They also [sponsor community members](https://github.com/orgs/nuxtlabs/sponsoring) from Vue, Vite, UnJS, and Nuxt.
For me, keeping Nuxt independent and sustainable for the future requires an active and growing team and community. In the weeks ahead, I'll be announcing a broader 'Nuxt team' alongside the core team. This is about recognising the tireless work of the many people whose contributions are already making Nuxt what it is.
I would also love to see more of those team members or the wider community sponsored to work in the Nuxt ecosystem in the years ahead. If your company has benefited from Nuxt, please do consider sponsoring some of the developers working on Nuxt, whether they are team or wider community members.
### Friendly collaboration
From the beginning of our work on Nuxt 3, we have sought to extract out utilities, libraries and even frameworks that we benefit from so they can *also* benefit a much broader audience.
That's the origin of [UnJS](https://unjs.io/), of course, and it continues to thrive under the leadership of [Pooya Parsa](https://github.com/pi0) (who is also a key member of the Nuxt core team).
We'd like to continue that attitude of friendly collaboration. Although building things ourselves or keeping them to ourselves might to be 'success', I don't have any time for zero-sum games. We will go further, both as a framework and as a web community, if we build *together*.
Equally, one of our core values is platform-independence (alongside deep platform *integration*). We support 90+ providers across deployment, testing, stories, KV and cache, databases, image CDNs and font hosts. That breadth of ecosystem is one that bears rich rewards and frees people up to make choices about which providers they use based on the value they bring. But it *also* means we are dependent on our community who use these different providers to help us keep these integrations up-to-date.
Nuxt isn't going anywhere, but we hope that the work we do collaboratively will last long beyond us.
### A welcoming community
Although it is easy to focus on technical excellence or the quality of developer experience, I am more encouraged to see the continued growth of the Nuxt ecosystem as a welcoming and friendly community.
I am incredibly grateful for the kind tone that prevails across [our community Discord](https://chat.nuxt.dev), on [Twitter](https://x.com/nuxt_js), and on [GitHub](https://github.com/nuxt/nuxt).
### What about Nuxt 4?
The JavaScript space is known for producing a new framework every week, which means there is a natural hype cycle.
But we are not aiming for hype with the continued development of Nuxt, which is part of why we have committed to regular release cycles:
- **major** framework releases every year
- **minor** releases every month or so
- **patch** releases every week or so
You can expect to see breaking changes shipped in major releases, with features shipped in our minor releases. That means we aren't holding features back for Nuxt 4; we'll ship those as regularly as we can in our 6-weekly minor release cycle.
Our aim is that Nuxt 4 is an opportunity for *thoughtful* breaking changes with either a straightforward migration path (ideally with automated processes) or the ability to opt-in to previous behaviour.
There are definitely lessons we as a team have learned form the transition from Nuxt 2 to 3, and I see Nuxt 4 as an opportunity for us to prove that major releases can be a good experience for users.
You can preview the changes we have in mind by browsing [our roadmap](https://github.com/orgs/nuxt/projects/8/views/4) or checking through [the issues we've tagged for v4](https://github.com/nuxt/nuxt/issues?q=is:issue+label:4.x). Feedback and wishes are very welcome as always!
#### Timetable
Our roadmap for Nuxt 4 is a little complex as we are also planning on major releases across the UnJS ecosystem.
Roughly speaking, we are aiming to have one more minor release for Nuxt v3 and Nitro v2, before beginning a [raft of major releases across the UnJS ecosystem of packages](https://github.com/unjs/community/discussions/4) - culminating in Nuxt v4.
We are aiming to release **Nuxt v4 on or before June 14** (though obviously this is dependent on having enough time after Nitro's major release to be properly tested in the community, so be aware that this is not an exact date).
#### Ongoing Support
After the release of Nuxt v4, we will be providing **six months** of ongoing support and bug-fixes for Nuxt v3, which we expect will be more than ample to upgrade to v4 given our aim of a gentle upgrade path.
We hope you are as excited as we are about the pending release of Nuxt v4! 🎉
---
Finally, thank you so much for all your trust and support as we've been building Nuxt. I know I speak for the whole team when I say that it's such a privilege to be doing this alongside everyone in the Nuxt community! ❤️
Daniel (on behalf of the whole Nuxt team)
---
# Source: https://nuxt.com/raw/docs/3.x/guide/ai/mcp.md
# Source: https://nuxt.com/raw/docs/4.x/guide/ai/mcp.md
# Nuxt MCP Server
> Use Nuxt documentation in your AI assistants with Model Context Protocol support.
## What is MCP?
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 the Nuxt documentation, making it easy for AI tools to understand and assist with Nuxt development.
## Resources
The Nuxt MCP server provides the following 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
- **resource://nuxt-com/deploy-providers**: Browse all deployment providers and hosting platforms
You're able to access these resources with tools like Claude Code by using `@`.
## Tools
The Nuxt MCP server provides the following tools organized by category:
### Documentation
- **list_documentation_pages**: Lists all available Nuxt documentation pages with their categories and basic information. Supports version filtering (3.x, 4.x, or all)
- **get_documentation_page**: Retrieves documentation page content and details by path
- **get_getting_started_guide**: Gets the getting started guide for a specific Nuxt version
### Blog
- **list_blog_posts**: Lists all Nuxt blog posts with metadata including dates, categories, and tags
- **get_blog_post**: Retrieves blog post content and details by path
### Deployment
- **list_deploy_providers**: Lists all deployment providers and hosting platforms for Nuxt applications
- **get_deploy_provider**: Retrieves deployment provider details and instructions by path
## Prompts
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
- **migration_help**: Get help with migrating between Nuxt versions
You're able to access these resources with tools like Claude Code by using `/`.
## Setup
The Nuxt MCP server uses HTTP transport and can be installed in different AI assistants.
### ChatGPT
**Custom connectors using MCP are available on ChatGPT for Pro and Plus accounts** on the web.
Follow these steps to set up Nuxt as a connector within ChatGPT:
1. **Enable Developer mode:**
- Go to Settings → Connectors → Advanced settings → Developer mode
2. **Open ChatGPT settings**
3. **In the Connectors tab, Create a new connector:**
- Give it a name: `Nuxt`
- MCP server URL: `https://nuxt.com/mcp`
- Authentication: `None`
4. **Click Create**
The Nuxt connector will appear in the composer's "Developer mode" tool later during conversations.
### Claude Code
**Ensure Claude Code is installed** - Visit [Anthropic's documentation](https://docs.claude.com/en/docs/claude-code/quickstart) for installation instructions.
Add the server using the CLI command:
```bash
claude mcp add --transport http nuxt-remote https://nuxt.com/mcp
```
### Claude Desktop
#### Setup Instructions
1. Open Claude Desktop and navigate to "Settings" > "Developer".
2. Click on "Edit Config". This will open the local Claude directory.
3. Modify the `claude_desktop_config.json` file with your custom MCP server configuration.
```json [claude_desktop_config.json]
{
"mcpServers": {
"nuxt": {
"command": "npx",
"args": [
"mcp-remote",
"https://nuxt.com/mcp"
]
}
}
}
```
4. Restart Claude Desktop app. The Nuxt MCP server should now be registered.
### Cursor
Click the button below to install the Nuxt MCP server directly in Cursor:
For manual setup, follow these steps:
1. Open Cursor and go to "Settings" > "Tools & MCP"
2. Add the Nuxt MCP server configuration
Or manually create/update `.cursor/mcp.json` in your project root:
```json [.cursor/mcp.json]
{
"mcpServers": {
"nuxt": {
"type": "http",
"url": "https://nuxt.com/mcp"
}
}
}
```
### Le Chat Mistral
1. Navigate to "Intelligence" > "Connectors"
2. Click on "Add Connector" button, then select "Custom MCP Connector"
3. Create your Custom MCP Connector:
- Connector Name : `Nuxt`
- Connector Server : `https://nuxt.com/mcp`
### Visual Studio Code
**Install required extensions** - Ensure you have [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) and [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) extensions installed.
1. Open VS Code and access the Command Palette (Ctrl/Cmd + Shift + P)
2. Type "Preferences: Open Workspace Settings (JSON)" and select it
3. Navigate to your project's `.vscode` folder or create one if it doesn't exist
4. Create or edit the `mcp.json` file with the following configuration:
```json [.vscode/mcp.json]
{
"servers": {
"nuxt": {
"type": "http",
"url": "https://nuxt.com/mcp"
}
}
}
```
### GitHub Copilot Agent
**Repository administrator access required** to configure MCP servers for GitHub Copilot coding agent.
If you have already configured MCP servers in VS Code (replace the `servers` key with `mcpServers` for GitHub Copilot Agent), you can leverage a similar configuration for GitHub Copilot coding agent. You will need to add a `tools` key specifying which tools are available to Copilot.
1. Navigate to your GitHub repository
2. Go to **Settings** > **Code & automation** > **Copilot** > **Coding agent**
3. In the **MCP configuration** section, add the following configuration:
```json
{
"mcpServers": {
"nuxt": {
"type": "http",
"url": "https://nuxt.com/mcp",
"tools": ["*"]
}
}
}
```
4. Click **Save**
#### Validating the Configuration
To verify the MCP server is configured correctly:
1. Create an issue in your repository and assign it to Copilot
2. Wait for Copilot to create a pull request
3. In the pull request, click **View session** in the "Copilot started work" timeline event
4. Click the ellipsis button (**...**) at the top right, then click **Copilot** in the sidebar
5. Expand the **Start MCP Servers** step to see the configured Nuxt tools
For more information on using MCP with GitHub Copilot coding agent, see [Extend coding agent with MCP](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/extend-coding-agent-with-mcp).
### Windsurf
1. Open Windsurf and navigate to "Settings" > "Windsurf Settings" > "Cascade"
2. Click the "Manage MCPs" button, then select the "View raw config" option
3. Add the following configuration to your MCP settings:
```json [.codeium/windsurf/mcp_config.json]
{
"mcpServers": {
"nuxt": {
"type": "http",
"url": "https://nuxt.com/mcp"
}
}
}
```
### Zed
1. Open Zed and go to "Settings" > "Open Settings"
2. Navigate to the JSON settings file
3. Add the following context server configuration to your settings:
```json [.config/zed/settings.json]
{
"context_servers": {
"nuxt": {
"source": "custom",
"command": "npx",
"args": ["mcp-remote", "https://nuxt.com/mcp"],
"env": {}
}
}
}
```
### Opencode
1. In your project root, create `opencode.json`
2. Add the following configuration:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"nuxt": {
"type": "remote",
"url": "https://nuxt.com/mcp",
"enabled": true
}
}
}
```
## Prompts Examples
Once configured, you can ask your AI assistant questions like:
- "List all available Nuxt documentation pages"
- "Get the introduction documentation"
- "What's the difference between v3 and v4?"
- "How do I deploy to Vercel?"
- "Show me the latest blog posts"
- "Help me migrate from Nuxt 3 to Nuxt 4"
- "Search documentation about composables"
- "Find deployment guides for Cloudflare"
The AI assistant will use the MCP server to fetch structured JSON data and provide guided assistance for Nuxt development.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/features/meta-tags.md
# Source: https://nuxt.com/raw/docs/4.x/examples/features/meta-tags.md
# Meta Tags
> This example shows how to use the Nuxt helpers and composables for SEO and meta management.
---
# Source: https://nuxt.com/raw/docs/3.x/migration/meta.md
# Source: https://nuxt.com/raw/docs/3.x/bridge/meta.md
# Source: https://nuxt.com/raw/docs/4.x/migration/meta.md
# Source: https://nuxt.com/raw/docs/4.x/bridge/meta.md
# Meta Tags
> Learn how to migrate from Nuxt 2 to Nuxt Bridge new meta tags.
If you need to access the component state with `head`, you should migrate to using [`useHead`](/docs/4.x/api/composables/use-head) .
If you need to use the Options API, there is a `head()` method you can use when you use `defineNuxtComponent`.
## Migration
### Set `bridge.meta`
```js
import { defineNuxtConfig } from '@nuxt/bridge'
export default defineNuxtConfig({
bridge: {
meta: true,
nitro: false, // If migration to Nitro is complete, set to true
},
})
```
### Update head properties
In your `nuxt.config`, rename `head` to `app.head`. (Note that objects no longer have a `hid` key for deduplication.)
```ts [Nuxt 2]
export default {
head: {
titleTemplate: '%s - Nuxt',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'Meta description' },
],
},
}
```
```ts [Nuxt 3]
export default defineNuxtConfig({
app: {
head: {
titleTemplate: '%s - Nuxt',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ name: 'description', content: 'Meta description' },
],
},
},
})
```
## `useHead` Composables
Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new [`useHead`](/docs/4.x/api/composables/use-head) composable.
```vue
```
This [`useHead`](/docs/4.x/api/composables/use-head) composable uses `@unhead/vue` under the hood (rather than `vue-meta`) to manipulate your ``.
We recommend not using the native Nuxt 2 `head()` properties in addition to [`useHead`](/docs/4.x/api/composables/use-head) , as they may conflict.
For more information on how to use this composable, see [the docs](/docs/4.x/getting-started/seo-meta).
## Options API
```vue
```
Possible breaking change: `head` receives the nuxt app but cannot access the component instance. If the code in your `head` tries to access the data object through `this` or `this.$data`, you will need to migrate to the `useHead` composable.
## Title Template
If you want to use a function (for full control), then this cannot be set in your nuxt.config, and it is recommended instead to set it within your `/layouts` directory.
```vue [app/layouts/default.vue]
```
---
# Source: https://nuxt.com/raw/docs/3.x/examples/routing/middleware.md
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/middleware.md
# Source: https://nuxt.com/raw/docs/4.x/examples/routing/middleware.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/middleware.md
# middleware
> Nuxt provides middleware to run code before navigating to a particular route.
Nuxt provides a customizable **route middleware** framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.
There are three kinds of route middleware:
1. Anonymous (or inline) route middleware are defined directly within the page.
2. Named route middleware, placed in the `app/middleware/` and automatically loaded via asynchronous import when used on a page.
3. Global route middleware, placed in the `app/middleware/` with a `.global` suffix and is run on every route change.
The first two kinds of route middleware can be defined in [`definePageMeta`](/docs/4.x/api/utils/define-page-meta).
Name of middleware are normalized to kebab-case: `myMiddleware` becomes `my-middleware`.
Route middleware run within the Vue part of your Nuxt app. Despite the similar name, they are completely different from [server middleware](/docs/4.x/directory-structure/server#server-middleware), which are run in the Nitro server part of your app.
## Usage
Route middleware are navigation guards that receive the current route and the next route as arguments.
```ts [middleware/my-middleware.ts]twoslash
export default defineNuxtRouteMiddleware((to, from) => {
if (to.params.id === '1') {
return abortNavigation()
}
// In a real app you would probably not redirect every route to `/`
// however it is important to check `to.path` before redirecting or you
// might get an infinite redirect loop
if (to.path !== '/') {
return navigateTo('/')
}
})
```
Nuxt provides two globally available helpers that can be returned directly from the middleware.
1. [`navigateTo`](/docs/4.x/api/utils/navigate-to) - Redirects to the given route
2. [`abortNavigation`](/docs/4.x/api/utils/abort-navigation) - Aborts the navigation, with an optional error message.
Unlike [navigation guards](https://router.vuejs.org/guide/advanced/navigation-guards#Global-Before-Guards) from `vue-router`, a third `next()` argument is not passed, and **redirect or route cancellation is handled by returning a value from the middleware**.
Possible return values are:
- nothing (a simple `return` or no return at all) - does not block navigation and will move to the next middleware function, if any, or complete the route navigation
- `return navigateTo('/')` - redirects to the given path and will set the redirect code to [`302` Found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/302) if the redirect happens on the server side
- `return navigateTo('/', { redirectCode: 301 })` - redirects to the given path and will set the redirect code to [`301` Moved Permanently](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/301) if the redirect happens on the server side
- `return abortNavigation()` - stops the current navigation
- `return abortNavigation(error)` - rejects the current navigation with an error
We recommend using the helper functions above for performing redirects or stopping navigation. Other possible return values described in [the vue-router docs](https://router.vuejs.org/guide/advanced/navigation-guards#Global-Before-Guards) may work but there may be breaking changes in future.
## Middleware Order
Middleware runs in the following order:
1. Global Middleware
2. Page defined middleware order (if there are multiple middleware declared with the array syntax)
For example, assuming you have the following middleware and component:
```bash [app/middleware/ directory]
-| middleware/
---| analytics.global.ts
---| setup.global.ts
---| auth.ts
```
```vue [pages/profile.vue]twoslash
```
You can expect the middleware to be run in the following order:
1. `analytics.global.ts`
2. `setup.global.ts`
3. Custom inline middleware
4. `auth.ts`
### Ordering Global Middleware
By default, global middleware is executed alphabetically based on the filename.
However, there may be times you want to define a specific order. For example, in the last scenario, `setup.global.ts` may need to run before `analytics.global.ts`. In that case, we recommend prefixing global middleware with 'alphabetical' numbering.
```bash [Directory structure]
-| middleware/
---| 01.setup.global.ts
---| 02.analytics.global.ts
---| auth.ts
```
In case you're new to 'alphabetical' numbering, remember that filenames are sorted as strings, not as numeric values. For example, `10.new.global.ts` would come before `2.new.global.ts`. This is why the example prefixes single digit numbers with `0`.
## When Middleware Runs
If your site is server-rendered or generated, middleware for the initial page will be executed both when the page is rendered and then again on the client. This might be needed if your middleware needs a browser environment, such as if you have a generated site, aggressively cache responses, or want to read a value from local storage.
However, if you want to avoid this behaviour you can do so:
```ts [middleware/example.ts]twoslash
export default defineNuxtRouteMiddleware((to) => {
// skip middleware on server
if (import.meta.server) {
return
}
// skip middleware on client side entirely
if (import.meta.client) {
return
}
// or only skip middleware on initial client load
const nuxtApp = useNuxtApp()
if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) {
return
}
})
```
This is true even if you throw an error in your middleware on the server, and an error page is rendered. The middleware will still run again in the browser.
Rendering an error page is an entirely separate page load, meaning any registered middleware will run again. You can use [`useError`](/docs/4.x/getting-started/error-handling#useerror) in middleware to check if an error is being handled.
## Accessing Route in Middleware
Always use the `to` and `from` parameters in your middleware to access the next and previous routes. Avoid using the [`useRoute()`](/docs/4.x/api/composables/use-route) composable in this context altogether.
There is **no concept of a "current route" in middleware**, as middleware can abort a navigation or redirect to a different route. The `useRoute()` composable will always be inaccurate in this context.
Sometimes, you might call a composable that uses `useRoute()` internally, which can trigger this warning even if there is no direct call in your middleware.
This leads to the **same issue as above**, so you should structure your functions to accept the route as an argument instead when they are used in middleware.
```ts [middleware/access-route.ts]twoslash
// @errors: 2304
export default defineNuxtRouteMiddleware((to) => {
// passing the route to the function to avoid calling `useRoute()` in middleware
doSomethingWithRoute(to)
// ❌ this will output a warning and is NOT recommended
callsRouteInternally()
})
```
```ts [utils/handle-route.ts]twoslash
// providing the route as an argument so that it can be used in middleware correctly
export function doSomethingWithRoute (route = useRoute()) {
// ...
}
```
```ts [utils/dont-do-this.ts]twoslash
// ❌ this function is not suitable for use in middleware
export function callsRouteInternally () {
const route = useRoute()
// ...
}
```
## Adding Middleware Dynamically
It is possible to add global or named route middleware manually using the [`addRouteMiddleware()`](/docs/4.x/api/utils/add-route-middleware) helper function, such as from within a plugin.
```tstwoslash
export default defineNuxtPlugin(() => {
addRouteMiddleware('global-test', () => {
console.log('this global middleware was added in a plugin and will be run on every route change')
}, { global: true })
addRouteMiddleware('named-test', () => {
console.log('this named middleware was added in a plugin and would override any existing middleware of the same name')
})
})
```
## Example
```bash [Directory Structure]
-| middleware/
---| auth.ts
```
In your page file, you can reference this route middleware:
```vuetwoslash
```
Now, before navigation to that page can complete, the `auth` route middleware will be run.
## Setting Middleware at Build Time
Instead of using `definePageMeta` on each page, you can add named route middleware within the `pages:extend` hook.
```ts [nuxt.config.ts]twoslash
import type { NuxtPage } from 'nuxt/schema'
export default defineNuxtConfig({
hooks: {
'pages:extend' (pages) {
function setMiddleware (pages: NuxtPage[]) {
for (const page of pages) {
if (/* some condition */ Math.random() > 0.5) {
page.meta ||= {}
// Note that this will override any middleware set in `definePageMeta` in the page
page.meta.middleware = ['named']
}
if (page.children) {
setMiddleware(page.children)
}
}
}
setMiddleware(pages)
},
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/modules/module-anatomy.md
# Source: https://nuxt.com/raw/docs/4.x/guide/modules/module-anatomy.md
# Understand Module Structure
> Learn how Nuxt modules are structured and how to define them.
There are two types of Nuxt modules:
- published modules are distributed on npm - you can see a list of some community modules on [the Nuxt website](/modules).
- "local" modules exist within a Nuxt project, either [inlined in Nuxt config](/docs/4.x/api/nuxt-config#modules) or within [the `modules` directory](/docs/4.x/directory-structure/modules).
In either case, they work in the same way.
## Define Your Module
When using the starter, your module definition is available at `src/module.ts`.
The module definition is the entry point of your module. It's what gets loaded by Nuxt when your module is referenced within a Nuxt configuration.
At a low level, a Nuxt module definition is a simple, potentially asynchronous, function accepting inline user options and a `nuxt` object to interact with Nuxt.
```ts
export default function (inlineOptions, nuxt) {
// You can do whatever you like here..
console.log(inlineOptions.token) // `123`
console.log(nuxt.options.dev) // `true` or `false`
nuxt.hook('ready', (nuxt) => {
console.log('Nuxt is ready')
})
}
```
You can get type hinting for this function using the higher-level `defineNuxtModule` helper provided by [Nuxt Kit](/docs/4.x/guide/going-further/kit).
```ts
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule((options, nuxt) => {
nuxt.hook('pages:extend', (pages) => {
console.log(`Discovered ${pages.length} pages`)
})
})
```
However, **we do not recommend** using this low-level function definition. Instead, to define a module, **we recommend** using the object-syntax with `meta` property to identify your module, especially when publishing to npm.
This helper makes writing Nuxt modules more straightforward by implementing many common patterns needed by modules, guaranteeing future compatibility and improving the experience for both module authors and users.
```ts
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
// Usually the npm package name of your module
name: '@nuxtjs/example',
// The key in `nuxt.config` that holds your module options
configKey: 'sample',
// Compatibility constraints
compatibility: {
// Semver version of supported nuxt versions
nuxt: '>=3.0.0',
},
},
// Default configuration options for your module, can also be a function returning those
defaults: {},
// Shorthand sugar to register Nuxt hooks
hooks: {},
// Configuration for other modules - this does not ensure the module runs before
// your module, but it allows you to change the other module's configuration before it runs
moduleDependencies: {
'some-module': {
// You can specify a version constraint for the module. If the user has a different
// version installed, Nuxt will throw an error on startup.
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: {},
},
},
// The function holding your module logic, it can be asynchronous
setup (moduleOptions, nuxt) {
// ...
},
})
```
`defineNuxtModule` returns a wrapper function with the lower level `(inlineOptions, nuxt)` module signature. This wrapper function applies defaults and other necessary steps before calling your `setup` function:
- Support `defaults` and `meta.configKey` for automatically merging module options
- Type hints and automated type inference
- Ensure module gets installed only once using a unique key computed from `meta.name` or `meta.configKey`
- Automatically register Nuxt hooks
- Automatically check for compatibility issues based on module meta
- Expose `getOptions` and `getMeta` for internal usage of Nuxt
- Ensuring backward and upward compatibility as long as the module is using `defineNuxtModule` from the latest version of `@nuxt/kit`
- Integration with module builder tooling
## Add Runtime Code
When using the starter, the runtime directory is `src/runtime/`.
Modules, like everything in a Nuxt configuration, aren't included in your application runtime. However, you might want your module to provide, or inject runtime code to the application it's installed on. That's what the runtime directory enables you to do.
Inside the runtime directory, you can provide any kind of assets related to the Nuxt app:
- Vue components
- Composables
- [Nuxt plugins](/docs/4.x/directory-structure/app/plugins)
To the [server engine](/docs/4.x/guide/concepts/server-engine), Nitro:
- API routes
- Middlewares
- Nitro plugins
Or any other kind of asset you want to inject in users' Nuxt applications:
- Stylesheets
- 3D models
- Images
- etc.
You'll then be able to inject all those assets inside the application from your [module definition](#define-your-module).
Learn more about asset injection in [the recipes section](/docs/4.x/guide/modules/recipes-basics).
Published modules cannot leverage auto-imports for assets within their runtime directory. Instead, they have to import them explicitly from `#imports` or alike.
Auto-imports are not enabled for files within `node_modules` (the location where a published module will eventually live) for performance reasons.
---
# Source: https://nuxt.com/raw/docs/3.x/migration/module-authors.md
# Source: https://nuxt.com/raw/docs/4.x/migration/module-authors.md
# Modules
> Learn how to migrate from Nuxt 2 to Nuxt 3 modules.
## Module Compatibility
Nuxt 3 has a basic backward compatibility layer for Nuxt 2 modules using `@nuxt/kit` auto wrappers. But there are usually steps to follow to make modules compatible with Nuxt 3 and sometimes, using Nuxt Bridge is required for cross-version compatibility.
We have prepared a [Dedicated Guide](/docs/4.x/guide/modules) for authoring Nuxt 3 ready modules using `@nuxt/kit`. Currently best migration path is to follow it and rewrite your modules. Rest of this guide includes preparation steps if you prefer to avoid a full rewrite yet making modules compatible with Nuxt 3.
Explore Nuxt 3 compatible modules.
### Plugin Compatibility
Nuxt 3 plugins are **not** fully backward compatible with Nuxt 2.
### Vue Compatibility
Plugins or components using the Composition API need exclusive Vue 2 or Vue 3 support.
By using [vue-demi](https://github.com/vueuse/vue-demi) they should be compatible with both Nuxt 2 and 3.
## Module Migration
When Nuxt 3 users add your module, you will not have access to the module container (`this.*`) so you will need to use utilities from `@nuxt/kit` to access the container functionality.
### Test with `@nuxt/bridge`
Migrating to `@nuxt/bridge` is the first and most important step for supporting Nuxt 3.
If you have a fixture or example in your module, add `@nuxt/bridge` package to its config (see [example](/docs/4.x/bridge/overview#update-nuxtconfig))
### Migrate from CommonJS to ESM
Nuxt 3 natively supports TypeScript and ECMAScript Modules. Please check [Native ES Modules](/docs/4.x/guide/concepts/esm) for more info and upgrading.
### Ensure Plugins Default Export
If you inject a Nuxt plugin that does not have `export default` (such as global Vue plugins), ensure you add `export default () => { }` to the end of it.
```js [Before]
// ~/plugins/vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
```
```js [After]
// ~/plugins/vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
export default () => { }
```
### Avoid Runtime Modules
With Nuxt 3, Nuxt is now a build-time-only dependency, which means that modules shouldn't attempt to hook into the Nuxt runtime.
Your module should work even if it's only added to [`buildModules`](/docs/4.x/api/nuxt-config#runtimeconfig) (instead of `modules`). For example:
- Avoid updating `process.env` within a Nuxt module and reading by a Nuxt plugin; use [`runtimeConfig`](/docs/4.x/api/nuxt-config#runtimeconfig) instead.
- (*) Avoid depending on runtime hooks like `vue-renderer:*` for production
- (*) Avoid adding `serverMiddleware` by importing them inside the module. Instead, add them by referencing a file path so that they are independent of the module's context
(*) Unless it is for `nuxt dev` purpose only and guarded with `if (nuxt.options.dev) { }`.
Continue reading about Nuxt 3 modules in the [Modules Author Guide](/docs/4.x/guide/modules).
### Use TypeScript (Optional)
While it is not essential, most of the Nuxt ecosystem is shifting to use TypeScript, so it is highly recommended to consider migration.
You can start migration by renaming `.js` files, to `.ts`. TypeScript is designed to be progressive!
You can use TypeScript syntax for Nuxt 2 and 3 modules and plugins without any extra dependencies.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/module-extend-pages.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/module-extend-pages.md
# Module Extend Pages
> This example defines a new `test` page using `extendPages` within a module.
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/module.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/module.md
# nuxt module
> Search and add modules to your Nuxt application with the command line.
Nuxt provides a few utilities to work with [Nuxt modules](/modules) seamlessly.
## nuxt module add
```bash [Terminal]
npx nuxt module add [--cwd=] [--logLevel=] [--skipInstall] [--skipConfig] [--dev]
```
Argument
Description
MODULENAME
Specify one or more modules to install by name, separated by spaces
Option
Default
Description
--cwd=
.
Specify the working directory
--logLevel=
Specify build-time log level
--skipInstall
Skip npm install
--skipConfig
Skip nuxt.config.ts update
--dev
Install modules as dev dependencies
The command lets you install [Nuxt modules](/modules) in your application with no manual work.
When running the command, it will:
- install the module as a dependency using your package manager
- add it to your [package.json](/docs/4.x/directory-structure/package) file
- update your [`nuxt.config`](/docs/4.x/directory-structure/nuxt-config) file
**Example:**
Installing the [`Pinia`](/modules/pinia) module
```bash [Terminal]
npx nuxt module add pinia
```
## nuxt module search
```bash [Terminal]
npx nuxt module search [--cwd=] [--nuxtVersion=<2|3>]
```
### Arguments
Argument
Description
QUERY
keywords to search for
### Options
Option
Default
Description
--cwd=
.
Specify the working directory
--nuxtVersion=<2|3>
Filter by Nuxt version and list compatible modules only (auto detected by default)
The command searches for Nuxt modules matching your query that are compatible with your Nuxt version.
**Example:**
```bash [Terminal]
npx nuxt module search pinia
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/modules.md
# Source: https://nuxt.com/raw/docs/3.x/guide/modules.md
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/modules.md
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/modules.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/modules.md
# Source: https://nuxt.com/raw/docs/4.x/guide/modules.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/modules.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/modules.md
# modules
> Use the modules/ directory to automatically register local modules within your application.
It is a good place to place any local modules you develop while building your application.
The auto-registered files patterns are:
- `modules/*/index.ts`
- `modules/*.ts`
You don't need to add those local modules to your [`nuxt.config.ts`](/docs/4.x/directory-structure/nuxt-config) separately.
```ts [modules/hello/index.ts]twoslash
// `nuxt/kit` is a helper subpath import you can use when defining local modules
// that means you do not need to add `@nuxt/kit` to your project's dependencies
import { addComponentsDir, addServerHandler, createResolver, defineNuxtModule } from 'nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'hello',
},
setup () {
const resolver = createResolver(import.meta.url)
// Add an API route
addServerHandler({
route: '/api/hello',
handler: resolver.resolve('./runtime/api-route'),
})
// Add components
addComponentsDir({
path: resolver.resolve('./runtime/app/components'),
pathPrefix: true, // Prefix your exports to avoid conflicts with user code or other modules
})
},
})
```
```ts [modules/hello/runtime/api-route.ts]twoslash
export default defineEventHandler(() => {
return { hello: 'world' }
})
```
When starting Nuxt, the `hello` module will be registered and the `/api/hello` route will be available.
Note that all components, pages, composables and other files that would be normally placed in your `app/` directory need to be in `modules/your-module/runtime/app/`. This ensures they can be type-checked properly.
Modules are executed in the following sequence:
- First, the modules defined in [`nuxt.config.ts`](/docs/4.x/api/nuxt-config#modules-1) are loaded.
- Then, modules found in the `modules/` directory are executed, and they load in alphabetical order.
You can change the order of local module by adding a number to the front of each directory name:
```bash [Directory structure]
modules/
1.first-module/
index.ts
2.second-module.ts
```
Watch Vue School video about Nuxt private modules.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/navigate-to.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/navigate-to.md
# navigateTo
> navigateTo is a helper function that programmatically navigates users.
## Usage
`navigateTo` is available on both server side and client side. It can be used within the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context), or directly, to perform page navigation.
Make sure to always use `await` or `return` on result of `navigateTo` when calling it.
`navigateTo` cannot be used within Nitro routes. To perform a server-side redirect in Nitro routes, use [`sendRedirect`](https://h3.dev/utils/response#redirectlocation-status-statustext) instead.
### Within a Vue Component
```vue
```
### Within Route Middleware
```ts
export default defineNuxtRouteMiddleware((to, from) => {
if (to.path !== '/search') {
// setting the redirect code to '301 Moved Permanently'
return navigateTo('/search', { redirectCode: 301 })
}
})
```
When using `navigateTo` within route middleware, you must **return its result** to ensure the middleware execution flow works correctly.
For example, the following implementation **will not work as expected**:
```ts
export default defineNuxtRouteMiddleware((to, from) => {
if (to.path !== '/search') {
// ❌ This will not work as expected
navigateTo('/search', { redirectCode: 301 })
return
}
})
```
In this case, `navigateTo` will be executed but not returned, which may lead to unexpected behavior.
### Navigating to an External URL
The `external` parameter in `navigateTo` influences how navigating to URLs is handled:
- **Without external: true**:
- Internal URLs navigate as expected.
- External URLs throw an error.
- **With external: true**:
- Internal URLs navigate with a full-page reload.
- External URLs navigate as expected.
#### Example
```vue
```
### Opening a Page in a New Tab
```vue
```
## Type
```ts [Signature]
export function navigateTo (
to: RouteLocationRaw | undefined | null,
options?: NavigateToOptions,
): Promise | false | void | RouteLocationRaw
interface NavigateToOptions {
replace?: boolean
redirectCode?: number
external?: boolean
open?: OpenOptions
}
type OpenOptions = {
target: string
windowFeatures?: OpenWindowFeatures
}
type OpenWindowFeatures = {
popup?: boolean
noopener?: boolean
noreferrer?: boolean
} & XOR<{ width?: number }, { innerWidth?: number }>
& XOR<{ height?: number }, { innerHeight?: number }>
& XOR<{ left?: number }, { screenX?: number }>
& XOR<{ top?: number }, { screenY?: number }>
```
## Parameters
### `to`
**Type**: [`RouteLocationRaw`](https://router.vuejs.org/api/interfaces/routelocationoptions) | `undefined` | `null`
**Default**: `'/'`
`to` can be a plain string or a route object to redirect to. When passed as `undefined` or `null`, it will default to `'/'`.
#### Example
```ts
// Passing the URL directly will redirect to the '/blog' page
await navigateTo('/blog')
// Using the route object, will redirect to the route with the name 'blog'
await navigateTo({ name: 'blog' })
// Redirects to the 'product' route while passing a parameter (id = 1) using the route object.
await navigateTo({ name: 'product', params: { id: 1 } })
```
### `options` (optional)
**Type**: `NavigateToOptions`
An object accepting the following properties:
- `replace`
- **Type**: `boolean`
- **Default**: `false`
- By default, `navigateTo` pushes the given route into the Vue Router's instance on the client side.
This behavior can be changed by setting `replace` to `true`, to indicate that given route should be replaced.
- `redirectCode`
- **Type**: `number`
- **Default**: `302`
- `navigateTo` redirects to the given path and sets the redirect code to [`302 Found`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/302) by default when the redirection takes place on the server side.
This default behavior can be modified by providing different `redirectCode`. Commonly, [`301 Moved Permanently`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/301) can be used for permanent redirections.
- `external`
- **Type**: `boolean`
- **Default**: `false`
- Allows navigating to an external URL when set to `true`. Otherwise, `navigateTo` will throw an error, as external navigation is not allowed by default.
- `open`
- **Type**: `OpenOptions`
- Allows navigating to the URL using the [open()](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) method of the window. This option is only applicable on the client side and will be ignored on the server side.
An object accepting the following properties:
- `target`
- **Type**: `string`
- **Default**: `'_blank'`
- A string, without whitespace, specifying the name of the browsing context the resource is being loaded into.
- `windowFeatures`
- **Type**: `OpenWindowFeatures`
- An object accepting the following properties:
Property
Type
Description
popup
boolean
Requests a minimal popup window instead of a new tab, with UI features decided by the browser.
width
or
innerWidth
number
Specifies the content area's width (minimum 100 pixels), including scrollbars.
height
or
innerHeight
number
Specifies the content area's height (minimum 100 pixels), including scrollbars.
left
or
screenX
number
Sets the horizontal position of the new window relative to the left edge of the screen.
top
or
screenY
number
Sets the vertical position of the new window relative to the top edge of the screen.
noopener
boolean
Prevents the new window from accessing the originating window via
window.opener
.
noreferrer
boolean
Prevents the Referer header from being sent and implicitly enables
noopener
.
Refer to the [documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#windowfeatures) for more detailed information on the **windowFeatures** properties.
---
# Source: https://nuxt.com/raw/deploy/netlify.md
# Netlify
> Deploy your Nuxt Application to Netlify infrastructure.
**Zero Configuration ✨**
Integration with Netlify is possible with zero configuration, [learn more](https://nitro.unjs.io/deploy#zero-config-providers).
## Setup
Nuxt will auto-detect that you are in a [Netlify](https://www.netlify.com) build environment and build an optimized version of your server.
For new sites, Netlify will detect that you are using Nuxt 3 and set the publish directory to `dist` and build command to `npm run build`.
If you are upgrading an existing site from Nuxt 2 you should check these and update them if needed.
If you want to add custom redirects, you can do so with [`routeRules`](/docs/guide/concepts/rendering#hybrid-rendering) or by adding a [`_redirects`](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file) file to your `public` directory.
For deployment, just push to your git repository [as you would normally do for Netlify](https://docs.netlify.com/configure-builds/get-started/).
## Netlify Edge Functions
Netlify Edge Functions use Deno and the powerful V8 JavaScript runtime to let you run globally distributed functions for the fastest possible response times.
Set the following environment variable to run Nuxt on Edge Functions:
```bash
SERVER_PRESET=netlify_edge
```
## On-demand Builders
On-demand Builders are serverless functions used to generate web content as needed that’s automatically cached on Netlify’s Edge CDN.
They enable you to build pages for your site when a user visits them for the first time and then cache them at the edge for subsequent visits until the next deployment.
Read More about Netlify on-demand builders
Set the following environment variable to enable on-demand builders:
```bash
SERVER_PRESET=netlify_builder
```
Head over **Nitro documentation** to learn more about the netlify deployment preset.
---
# Source: https://nuxt.com/raw/blog/new-website.md
# A New Website
> We are thrilled to release the new nuxt.com, powered by Nuxt UI and now open source.
Nuxt.com is the main entry point when you want to learn Nuxt. With **more than 300k visitors every month**, it was time to give it a new look and feel.
## New Design
We are back to the original colors of Nuxt, with a navy background (`#020420`) and its signature shiny green (`#00DC82`).
Discover the **Nuxt Design Kit** as well as our **Logo History**.
We wanted to achieve a consistent design across all our official documentations:
We really love this new design and hope you do too. **This is only the first step toward many improvements coming to the website.**
## Improved Navigation
From now on, you can easily jump between the five main documentation categories:
On the right side, you can see the table of contents as well as community shortcuts: Edit this page, Chat on Discord, etc.
## Source Code Buttons
When looking at Nuxt built-in [components](/docs/api/components), [composables](/docs/api/composables), [utils](/docs/api/utils), [commands](/docs/api/commands) and [kit utilities](/docs/api/kit), you can now jump to the source code by clicking on the
Source
button.
Checkout an example on `` documentation page.
## Improved Search Feature
You may notice a new modal when hitting
. We leverage the Nuxt UI [``](https://ui.nuxt.com/components/command-palette) components combined with Nuxt Content data (search & navigation) to provide a better search experience.
With the command palette, you can:
- Jump to a page
- Search in the documentation
- Search a module
- Switch the color mode
We plan to add more commands soon.
## Migration to Nuxt UI
The new website is powered by [Nuxt UI](https://ui.nuxt.com), our UI library tailored made for Nuxt and built on top of [Tailwind CSS](https://tailwindcss.com) & [Headless UI](https://headlessui.com/).
The website also uses [Nuxt UI Pro](https://ui.nuxt.com/pro), a set of premium components built on top of Nuxt UI to create beautiful & responsive Nuxt applications in minutes.
It includes components such as ``, ``, ``, `` and more.
We plan to launch the full documentation of Nuxt UI Pro at the end of October. If you cannot wait and want early access, you can already [purchase a license](https://ui.nuxt.com/pro/purchase) now and get access to our private repository on GitHub.
This [migration](https://github.com/nuxt/nuxt.com/pull/1365) was a great opportunity to improve Nuxt UI & UI Pro and fix some bugs, as well as a difference of
+9,004
/
-23,113
lines of code changed.
Read more about **Nuxt UI**.
## Open Graph Images
We are big fans of having a custom image when we share a link on social media. That's why we have added OG images on all our documentation pages.
Example of the [Installation page](/docs/getting-started/installation):

Discover the **Nuxt OG Image** module.
## Available on GitHub
We are proud to announce that the website is **now open source** and available on GitHub.
Check out `nuxt/nuxt.com` on GitHub.
## What's next?
This new website is the beginning of upcoming changes we are planing, some of them are:
- Team & Contributors pages
- Integrations page to showcase all the possibilities with Nuxt: Hosting, CMS, Database, etc.
- Templates page (currently [nuxt.new](https://nuxt.new)) to list official and community starters
- And more...
**We are looking forward to your feedback on Twitter, Discord or GitHub**.
Thank you for reading this blog post, and happy Nuxting 🤟
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/nightly-release-channel.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/nightly-release-channel.md
# Nightly Release Channel
> The nightly release channel allows using Nuxt built directly from the latest commits to the repository.
Nuxt lands commits, improvements, and bug fixes every day. You can opt in to test them earlier before the next release.
After a commit is merged into the `main` branch of [nuxt/nuxt](https://github.com/nuxt/nuxt) and **passes all tests**, we trigger an automated npm release, using GitHub Actions.
You can use these 'nightly' releases to beta test new features and changes.
The build and publishing method and quality of these 'nightly' releases are the same as stable ones. The only difference is that you should often check the GitHub repository for updates. There is a slight chance of regressions not being caught during the review process and by the automated tests. Therefore, we internally use this channel to double-check everything before each release.
Features that are only available on the nightly release channel are marked with an alert in the documentation.
The `latest` nightly release channel is currently tracking the Nuxt v4 branch, meaning that it is particularly likely to have breaking changes right now — be careful! You can opt in to the 3.x branch nightly releases with `"nuxt": "npm:nuxt-nightly@3x"`.
## Opting In
Update `nuxt` dependency inside `package.json`:
```diff [package.json]
{
"devDependencies": {
-- "nuxt": "^4.0.0"
++ "nuxt": "npm:nuxt-nightly@latest"
}
}
```
Remove lockfile (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lock` or `bun.lockb`) and reinstall dependencies.
## Opting Out
Update `nuxt` dependency inside `package.json`:
```diff [package.json]
{
"devDependencies": {
-- "nuxt": "npm:nuxt-nightly@latest"
++ "nuxt": "^4.0.0"
}
}
```
Remove lockfile (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lock` or `bun.lockb`) and reinstall dependencies.
## Using Nightly `@nuxt/cli`
To try the latest version of [nuxt/cli](https://github.com/nuxt/cli):
```bash [Terminal]
npx @nuxt/cli-nightly@latest [command]
```
Read more about the available commands.
---
# Source: https://nuxt.com/raw/docs/3.x/bridge/nitro.md
# Source: https://nuxt.com/raw/docs/3.x/api/kit/nitro.md
# Source: https://nuxt.com/raw/docs/4.x/bridge/nitro.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/nitro.md
# Nitro
> Nuxt Kit provides a set of utilities to help you work with Nitro. These functions allow you to add server handlers, plugins, and prerender routes.
Nitro is an open source TypeScript framework to build ultra-fast web servers. Nuxt uses Nitro as its server engine. You can use `useNitro` to access the Nitro instance, `addServerHandler` to add a server handler, `addDevServerHandler` to add a server handler to be used only in development mode, `addServerPlugin` to add a plugin to extend Nitro's runtime behavior, and `addPrerenderRoutes` to add routes to be prerendered by Nitro.
## `addServerHandler`
Adds a Nitro server handler. Use this if you want to create server middleware or a custom route.
### Usage
```tstwoslash
import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options) {
const { resolve } = createResolver(import.meta.url)
addServerHandler({
route: '/robots.txt',
handler: resolve('./runtime/robots.get'),
})
},
})
```
### Type
```ts
function addServerHandler (handler: NitroEventHandler): void
```
### Parameters
**handler**: A handler object with the following properties:
Property
Type
Required
Description
handler
string
true
Path to event handler.
route
string
false
Path prefix or route. If an empty string used, will be used as a middleware.
middleware
boolean
false
Specifies this is a middleware handler. Middleware are called on every route and should normally return nothing to pass to the next handlers.
lazy
boolean
false
Use lazy loading to import the handler. This is useful when you only want to load the handler on demand.
method
string
false
Router method matcher. If handler name contains method name, it will be used as a default value.
### Examples
#### Basic Usage
You can use `addServerHandler` to add a server handler from your module.
```ts [module.ts]twoslash
import { addServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options) {
const { resolve } = createResolver(import.meta.url)
addServerHandler({
route: '/robots.txt',
handler: resolve('./runtime/robots.get'),
})
},
})
```
```ts [runtime/robots.get.ts]twoslash
export default defineEventHandler(() => {
return {
body: `User-agent: *\nDisallow: /`,
}
})
```
When you access `/robots.txt`, it will return the following response:
```txt
User-agent: *
Disallow: /
```
## `addDevServerHandler`
Adds a Nitro server handler to be used only in development mode. This handler will be excluded from production build.
### Usage
```tstwoslash
import { defineEventHandler } from 'h3'
import { addDevServerHandler, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
addDevServerHandler({
handler: defineEventHandler(() => {
return {
body: `Response generated at ${new Date().toISOString()}`,
}
}),
route: '/_handler',
})
},
})
```
### Type
```tstwoslash
// @errors: 2391
import type { NitroDevEventHandler } from 'nitropack/types'
// ---cut---
function addDevServerHandler (handler: NitroDevEventHandler): void
```
### Parameters
**handler**: A handler object with the following properties:
Property
Type
Required
Description
handler
EventHandler
true
Event handler.
route
string
false
Path prefix or route. If an empty string used, will be used as a middleware.
### Examples
#### Basic Usage
In some cases, you may want to create a server handler specifically for development purposes, such as a Tailwind config viewer.
```ts
import { joinURL } from 'ufo'
import { addDevServerHandler, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
async setup (options, nuxt) {
const route = joinURL(nuxt.options.app?.baseURL, '/_tailwind')
// @ts-expect-error - tailwind-config-viewer does not have correct types
const createServer = await import('tailwind-config-viewer/server/index.js').then(r => r.default || r) as any
const viewerDevMiddleware = createServer({ tailwindConfigProvider: () => options, routerPrefix: route }).asMiddleware()
addDevServerHandler({ route, handler: viewerDevMiddleware })
},
})
```
## `useNitro`
Returns the Nitro instance.
You can call `useNitro()` only after `ready` hook.
Changes to the Nitro instance configuration are not applied.
### Usage
```ts
import { defineNuxtModule, useNitro } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
nuxt.hook('ready', () => {
const nitro = useNitro()
// Do something with Nitro instance
})
},
})
```
### Type
```ts
function useNitro (): Nitro
```
## `addServerPlugin`
Add plugin to extend Nitro's runtime behavior.
You can read more about Nitro plugins in the [Nitro documentation](https://nitro.build/guide/plugins).
It is necessary to explicitly import `defineNitroPlugin` from `nitropack/runtime` within your plugin file. The same requirement applies to utilities such as `useRuntimeConfig`.
### Usage
```tstwoslash
import { addServerPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
const { resolve } = createResolver(import.meta.url)
addServerPlugin(resolve('./runtime/plugin.ts'))
},
})
```
### Type
```ts
function addServerPlugin (plugin: string): void
```
### Parameters
Property
Type
Required
Description
plugin
string
true
Path to the plugin. The plugin must export a default function that accepts the Nitro instance as an argument.
## `addServerImports`
Add imports to the server. It makes your imports available in Nitro without the need to import them manually.
If you want to provide a utility that works in both server and client contexts and is usable in the [`shared/`](/docs/4.x/directory-structure/shared) directory, the function must be imported from the same source file for both [`addImports`](/docs/4.x/api/kit/autoimports#addimports) and `addServerImports` and should have identical signature. That source file should not import anything context-specific (i.e., Nitro context, Nuxt app context) or else it might cause errors during type-checking.
### Usage
```tstwoslash
import { addServerImports, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options) {
const names = [
'useStoryblok',
'useStoryblokApi',
'useStoryblokBridge',
'renderRichText',
'RichTextSchema',
]
names.forEach(name =>
addServerImports({ name, as: name, from: '@storyblok/vue' }),
)
},
})
```
### Type
```ts
function addServerImports (dirs: Import | Import[]): void
```
### Parameters
`imports`: An object or an array of objects with the following properties:
Property
Type
Required
Description
name
string
true
Import name to be detected.
from
string
true
Module specifier to import from.
priority
number
false
Priority of the import; if multiple imports have the same name, the one with the highest priority will be used.
disabled
boolean
false
If this import is disabled.
meta
Record
false
Metadata of the import.
type
boolean
false
If this import is a pure type import.
typeFrom
string
false
Use this as the
from
value when generating type declarations.
as
string
false
Import as this name.
## `addServerImportsDir`
Add a directory to be scanned for auto-imports by Nitro.
### Usage
```tstwoslash
import { addServerImportsDir, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule',
},
setup (options) {
const { resolve } = createResolver(import.meta.url)
addServerImportsDir(resolve('./runtime/server/composables'))
},
})
```
### Type
```ts
function addServerImportsDir (dirs: string | string[], opts: { prepend?: boolean }): void
```
### Parameters
Property
Type
Required
Description
dirs
string
|
string[]
true
A directory or an array of directories to register to be scanned by Nitro.
opts
{ prepend?: boolean }
false
Options for the import directory. If
prepend
is
true
, the directory is added to the beginning of the scan list.
### Examples
You can use `addServerImportsDir` to add a directory to be scanned by Nitro. This is useful when you want Nitro to auto-import functions from a custom server directory.
```ts [module.ts]twoslash
import { addServerImportsDir, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule',
},
setup (options) {
const { resolve } = createResolver(import.meta.url)
addServerImportsDir(resolve('./runtime/server/composables'))
},
})
```
```ts [runtime/server/composables/index.ts]twoslash
export function useApiSecret () {
const { apiSecret } = useRuntimeConfig()
return apiSecret
}
```
You can then use the `useApiSecret` function in your server code:
```ts [runtime/server/api/hello.ts]twoslash
const useApiSecret = (): string => ''
// ---cut---
export default defineEventHandler(() => {
const apiSecret = useApiSecret()
// Do something with the apiSecret
})
```
## `addServerScanDir`
Add directories to be scanned by Nitro. It will check for subdirectories, which will be registered
just like the `~/server` folder is.
Only `~/server/api`, `~/server/routes`, `~/server/middleware`, and `~/server/utils` are scanned.
### Usage
```tstwoslash
import { addServerScanDir, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule',
},
setup (options) {
const { resolve } = createResolver(import.meta.url)
addServerScanDir(resolve('./runtime/server'))
},
})
```
### Type
```ts
function addServerScanDir (dirs: string | string[], opts: { prepend?: boolean }): void
```
### Parameters
Property
Type
Required
Description
dirs
string
|
string[]
true
A directory or an array of directories to register to be scanned for by Nitro as server dirs.
opts
{ prepend?: boolean }
false
Options for the import directory. If
prepend
is
true
, the directory is added to the beginning of the scan list.
### Examples
You can use `addServerScanDir` to add a directory to be scanned by Nitro. This is useful when you want to add a custom server directory.
```ts [module.ts]twoslash
import { addServerScanDir, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule',
},
setup (options) {
const { resolve } = createResolver(import.meta.url)
addServerScanDir(resolve('./runtime/server'))
},
})
```
```ts [runtime/server/utils/index.ts]twoslash
export function hello () {
return 'Hello from server utils!'
}
```
You can then use the `hello` function in your server code.
```ts [runtime/server/api/hello.ts]twoslash
function hello () {
return 'Hello from server utils!'
}
// ---cut---
export default defineEventHandler(() => {
return hello() // Hello from server utils!
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/node_modules.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/node_modules.md
# node_modules
> The package manager stores the dependencies of your project in the node_modules/ directory.
The package manager ([`npm`](https://docs.npmjs.com/cli/commands/npm/) or [`yarn`](https://yarnpkg.com) or [`pnpm`](https://pnpm.io/cli/install) or [`bun`](https://bun.com/package-manager) or [`deno`](https://docs.deno.com/runtime/getting_started/installation/)) creates this directory to store the dependencies of your project.
This directory should be added to your [`.gitignore`](/docs/4.x/directory-structure/gitignore) file to avoid pushing the dependencies to your repository.
---
# Source: https://nuxt.com/raw/deploy/northflank.md
# Northflank
> Deploy your Nuxt Application to Northflank infrastructure.
Nuxt supports deploying on [Northflank](https://www.northflank.com) with minimal configuration.
## Setup
1. Link your [Git provider](https://northflank.com/docs/v1/application/getting-started/link-your-git-account) and [create a new project](https://northflank.com/docs/v1/application/getting-started/create-a-project) in Northflank.
2. In your project, create a [Service](https://northflank.com/docs/v1/application/getting-started/build-and-deploy-your-code) and connect it to your Nuxt repository.
3. Ensure your package.json includes a start script that runs the Nuxt production server.
```json [package.json]
{
"scripts": {
"start": "node .output/server/index.mjs"
}
}
```
1. Click "Create Service" to build and deploy your Nuxt app.
For more information, refer to the **Northflank documentation**.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/going-further/nuxt-app.md
# Source: https://nuxt.com/raw/docs/4.x/guide/going-further/nuxt-app.md
# NuxtApp
> In Nuxt, you can access runtime app context within composables, components and plugins.
In Nuxt, you can access runtime app context within composables, components and plugins.
In Nuxt 2, this was referred to as **Nuxt context**.
## Nuxt App Interface
Jump over the `NuxtApp` interface documentation.
## The Nuxt Context
Many composables and utilities, both built-in and user-made, may require access to the Nuxt instance. This doesn't exist everywhere on your application, because a fresh instance is created on every request.
Currently, the Nuxt context is only accessible in [plugins](/docs/4.x/directory-structure/app/plugins), [Nuxt hooks](/docs/4.x/guide/going-further/hooks), [Nuxt middleware](/docs/4.x/directory-structure/app/middleware) (if wrapped in `defineNuxtRouteMiddleware`), and [setup functions](https://vuejs.org/api/composition-api-setup) (in pages and components).
If a composable is called without access to the context, you may get an error stating that 'A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function.' In that case, you can also explicitly call functions within this context by using [`nuxtApp.runWithContext`](/docs/4.x/api/composables/use-nuxt-app#runwithcontext).
## Accessing NuxtApp
Within composables, plugins and components you can access `nuxtApp` with [`useNuxtApp()`](/docs/4.x/api/composables/use-nuxt-app):
```ts [app/composables/useMyComposable.ts]
export function useMyComposable () {
const nuxtApp = useNuxtApp()
// access runtime nuxt app instance
}
```
If your composable does not always need `nuxtApp` or you simply want to check if it is present or not, since [`useNuxtApp`](/docs/4.x/api/composables/use-nuxt-app) throws an exception, you can use [`tryUseNuxtApp`](/docs/4.x/api/composables/use-nuxt-app#tryusenuxtapp) instead.
Plugins also receive `nuxtApp` as the first argument for convenience.
## Providing Helpers
You can provide helpers to be usable across all composables and application. This usually happens within a Nuxt plugin.
```ts
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', name => `Hello ${name}!`)
console.log(nuxtApp.$hello('name')) // Prints "Hello name!"
```
It is possible to inject helpers by returning an object with a `provide` key in plugins.
In Nuxt 2 plugins, this was referred to as **inject function**.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-client-fallback.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-client-fallback.md
#
> Nuxt provides the component to render its content on the client if any of its children trigger an error in SSR
Nuxt provides the `` component to render its content on the client if any of its children trigger an error in SSR.
This component is experimental and in order to use it you must enable the `experimental.clientFallback` option in your `nuxt.config`.
```vue [app/pages/example.vue]
```
## Events
- `@ssr-error`: Event emitted when a child triggers an error in SSR. Note that this will only be triggered on the server.```vue
```
## Props
- `placeholderTag` | `fallbackTag`: Specify a fallback tag to be rendered if the slot fails to render on the server.
- **type**: `string`
- **default**: `div`
- `placeholder` | `fallback`: Specify fallback content to be rendered if the slot fails to render.
- **type**: `string`
- `keepFallback`: Keep the fallback content if it failed to render server-side.
- **type**: `boolean`
- **default**: `false`
The `placeholder` and `fallback` props render content as raw HTML. Do not pass untrusted user input to these props as it may lead to XSS vulnerabilities. Use the `#fallback` or `#placeholder` slots instead for dynamic content that needs proper escaping.
```vue
```
## Slots
- `#fallback`: specify content to be displayed server-side if the slot fails to render.
```vue
Hello world
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/nuxt-config.md
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/nuxt-config.md
# Source: https://nuxt.com/raw/docs/4.x/api/nuxt-config.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/nuxt-config.md
# nuxt.config.ts
> Nuxt can be easily configured with a single nuxt.config file.
The `nuxt.config` file extension can either be `.js`, `.ts` or `.mjs`.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
// My Nuxt config
})
```
`defineNuxtConfig` helper is globally available without import.
You can explicitly import `defineNuxtConfig` from `nuxt/config` if you prefer:
```ts [nuxt.config.ts]twoslash
import { defineNuxtConfig } from 'nuxt/config'
export default defineNuxtConfig({
// My Nuxt config
})
```
Discover all the available options in the **Nuxt configuration** documentation.
To ensure your configuration is up to date, Nuxt will make a full restart when detecting changes in the main configuration file, the [`.env`](/docs/4.x/directory-structure/env), [`.nuxtignore`](/docs/4.x/directory-structure/nuxtignore) and [`.nuxtrc`](/docs/4.x/directory-structure/nuxtrc) dotfiles.
---
# Source: https://nuxt.com/raw/blog/nuxt-devtools-v1-0.md
# Nuxt DevTools v1.0
> Nuxt DevTools v1.0 is out, generally available to all Nuxt projects!
We are thrilled to announce the release of [Nuxt DevTools v1.0](https://github.com/nuxt/devtools)! 🎉
Since this release, Nuxt DevTools is now enabled with [Nuxt v3.8](/blog/v3-8) and onwards by default. Generally available to all Nuxt projects!
You can start playing with it by upgrading to the latest Nuxt, and press `Shift + Option + D` (macOS) or `Shift + Alt + D` (Windows) in your browser to open the DevTools. By default the floating panel is hidden to reduce the distraction. You can enable it inside Nuxt DevTools settings page, or explicitly enabled it in your config:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
devtools: {
enabled: true
}
})
```
## The Reasons We Built Nuxt DevTools
Over the recent years, there has been an increasing focus on Developer Experience (DX). Tools and frameworks have been striving to improve the DX. Along the way, Nuxt introduced many innovative features and conventions to make your day-to-day development easier and more efficient.
For example, [file-based routing](/docs/guide/directory-structure/pages), [layout system](/docs/guide/directory-structure/layouts), [plugins](/docs/guide/directory-structure/plugins), [route middleware](/docs/guide/directory-structure/middleware), [composables auto-import](/docs/guide/concepts/auto-imports), [file-based server APIs](https://nitro.unjs.io/guide/routing), [powerful module system](/modules) and many more.

Nuxt is capable of creating various range of applications, from simple hobby projects to large scale applications, from simple client-rendered single-page applications to hybrid rendered sites with serverless functions on edge, etc. We provide those features and conventions to make it easier to support all those use cases and scenarios.
### The Problem
Out of all these benefits of having a powerful framework, we have to made some trade-offs. Sometimes, we have to sacrifice a bit of the transparency of the underlying implementation to make things easier to use.

Conventional abstractions are great things to transfer implementation complexity and make things easier to get more focus when building. On the other hand, they can also add extra burden for users to learn and understand what's going on under the hood. Leading also to implicitness, like where a auto-imported component is from, or how many modules is using a certain component, etc. It can also make things hard to debug.
Trade-offs are inevitable. Generally we believe those trade-offs are worth it, as they would help organizing users' codebase and make it easier to maintain in the long run. In the meantime, we also want to compensate the transparency we lost by providing a tool to help you understand what's going on under the hood and make the learning curve smoother.
That's where Nuxt DevTools comes in! We [first introduced it](/blog/introducing-nuxt-devtools) in February 2023 to experiment with the idea. After a few months of exploration and development, from surprisingly positive feedbacks from the community, this idea has been proven to be useful and we decided to make it a core part of your Nuxt development experience.
## Features
[Nuxt DevTools](https://github.com/nuxt/devtools) is a set of visual tools to help you understand your Nuxt app and improve the developer experience even further. It's created to provide better transparency between Nuxt and your app, find performance bottlenecks and help you manage your app and configuration.
### In App DevTools
From the overview, Nuxt DevTools is an in-app DevTools that lives alongside your app. It will show up as a floating panel that you can click to open.
We believe this is a better approach than the traditional browser extension DevTools, as it's:
- **Works across all browsers**, and even on mobile devices! - The capability of browser extension DevTools are limited by the APIs each browsers provides, and also maintain multiple extensions would require a lot of effort. This approach would allow us to focus more on the functionality and features, while having it accessible to users on any browsers and devices.
- **Build tools integrations** - Tranditionally browser extension DevTools are only able to access the runtime context of your app and have no access to the build tools. Having the DevTools comes with Nuxt, allows us to communicate with the build tools and provide much more insights and features.
- **Avoid layout shifts** - Having the DevTools as a floating panel would avoid the layout shifts when toggling the DevTools.
### Pages View
To help improving the implicitness of file-based routing, we introduced the Pages View in DevTools. It lists all the pages that have been registered in your app, that you can easily test and navigate between them.
### Components View
The Components tab shows all the components you are using in your app and where they are from. You can also search for them and go to the source code.
It also provides a graph view that show the relationship between components. You can filter the components to see the dependencies of a specific component. This could help to identify unintended dependencies and improve the performance and bundle size of pages.
### Composables View
Composables view shows all the auto-imported composables registered to Nuxt. You can see which files are importing them, and where they are from. Some entries can also provide short descriptions and documentation links.
### Modules Management
The Modules tab shows all the modules that are registered in your app, with the links to their documentations and repositories.
We also provide the ability for you to search for and explore the modules from the community. And install them with a single click!
### Static Assets Management
The Assets tab shows all the static assets under your `public` directory. It supports previewing images, videos, fonts, PDFs, and other files, that you can easily copy the URL or code snippet to use in your app. You may also drag and drop files to upload them directly from Nuxt DevTools.
### Runtime Configs Editor
The Runtime Configs tab shows the runtime configs of your app and provides an interactive editor for you to play with different values.
### Payload Editor
Similar to the Runtime Configs Editor, the Payload Editor allows you to edit the payload from composables like [`useState`](/docs/api/composables/use-state) and [`useFetch`](/docs/api/composables/use-fetch) to see what have been passed from server to client on server-side rendering.
### Open Graph Preview
[Open Graph](https://ogp.me/) plays an important role in social media sharing as well as [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization). In the traditional workflow, we usually need to first deploy our app to check if the Open Graph is working as expected on various social media platforms. With the Open Graph Preview, you can now preview the Open Graph in DevTools and update it live with an instant feedback loop.
We also help you check the Open Graph tags in your app and provide suggestions to improve them. You can copy the generated code snippet and paste it to your routes to fix them in one go.
### Plugins Overview
Plugins Overview list all the [plugins](/docs/guide/directory-structure/plugins) registered in your app. As the plugins are executed in the runtime before your app renders, it's important to keep plugins performant and avoid blocking the rendering. We provide the execution time of each plugin and the total time of all plugins, so you can better identify the potential performance bottlenecks.
### Timeline
Timeline is a tool for you to check when and how each composable been called. Different from browser DevTools' performance tools, this tab only check the high-level composables combining with other events like route navigration, which is closer to day-to-day use. It also records the arguments and return values of each call, so you can better understand what's going on under the hood.
As of November 2023, the Timeline is still an experimental feature that requires manually opt-in.
### Production Build Analyzer
While Nuxt DevTools is mostly focused on providing development tools, sometimes we might want to know how chunks are composed in production. The Build Analyzer allows you to fire up a production build and analyze the chunks and modules at any time and see how they are bundled. You can also do multiple builds on different branches to compare how your refactoring/changes affect the bundle size, etc.
### Server API Playground
Nuxt provides a very convenient way to create server API functions with the [server routes](/docs/guide/directory-structure/server#server-routes). Since in Nuxt we have that information, we are able to provide a playground for you to test and debug your server API functions, similar to tools like Postman. We list all the server APIs available in your app automatically. And we execute those functions **within the same context of your app**, so you don't need to manually set them up in external tools. As always, we also have code snippets for you to copy and paste into your app.
### Embedded Full-feature VS Code
Thanks to the flexibility of our DevTools approach, we can leverage the power of the modern web to embed a full-featured VS Code right in the DevTools. In that VS Code, you can sign in to your account and synchronize your settings, and all the extensions just work as your normal VS Code client. This allows you to quickly edit your code without leaving your browser.
### Component Inspector
The Inspector allows you to inspect the DOM tree and see which component is rendering it. Click to go to your editor for the specific line. Making it much easier to make changes without the requirement of understanding the project structure thoroughly.
### Split Screens
In the recent releases, we introduced a split screen feature, that allows you to open two tabs side-by-side.
### UI Customization
In DevTools setting, we provide a few options for you to customize the tabs you want to see, and the layout of the DevTools.
## Ecosystem
In Nuxt, we value the ecosystem a lot. Similar to how Nuxt modules enhance Nuxt core, we also designed Nuxt DevTools to be highly extensible, allowing modules to provide additional features and integrations.
### Community Modules
We are proud to see the community has already started to build modules for Nuxt DevTools. Here are some of them:
[Vitest module](https://nuxt.com/modules/vitest) provides Vitest UI for tests running with the same pipeline as your Nuxt app. Made it easier to debug your tests alongside your app.
[VueUse module](/modules/vueuse) provides a search page for available composables and see their documentation.
[SiteMap module](/modules/sitemap) provides an interactive editor for you to manage your sitemap.
[TailwindCSS module](/modules/tailwindcss) provides the Tailwind Config Viewer for you to check what's available based on your config.
[UnoCSS module](/modules/unocss) provides an interactive inspector to see how each module contributes to the final CSS.
[Storybook module](/modules/storybook) provides a Storybook UI for your components.
And they are just a few of them! We are looking forward to see more modules coming to Nuxt DevTools!
### Projects Inspired by Nuxt DevTools
In the meantime, we are also flattered that other frameworks are starting to build their own DevTools inspired by Nuxt DevTools:
- [`webfansplz/vite-plugin-vue-devtools`](https://github.com/webfansplz/vite-plugin-vue-devtools) - A Nuxt DevTools port to support DevTools for Vite + Vue 3 apps.
- [`pheno-agency/vite-plugin-devtools`](https://github.com/pheno-agency/vite-plugin-devtools) - An experiment on building framework-agnostic DevTools for Vite.
- [Modern.js DevTools](https://github.com/Asuka109/modern.js/tree/dev/modernjs-devtools/packages/devtools/plugin) - In App DevTools for Modern.js
- [Qwik DevTools](https://github.com/QwikDev/devtools) - DevTools for Qwik
We are working closely with the maintainers of those projects to see how we can bring the experience of DevTools to the next level.
## What's Next
Nuxt DevTools just reached v1.0, but t doesn't mean we are done. There are still a lot of things we want to explore and improve. Here are some of the ideas we are considering:
- Nuxt Accessibility Integration - We are building an a11y integration for Nuxt ([#23255](https://github.com/nuxt/nuxt/issues/23255)). We'll build a dedicated view in Nuxt DevTools for you to check the accessibility hints interactively.
- Vue DevTools Integration - We are working with the Vue team to bring the Vue DevTools experience to a shared tool that works for both browser extensions and in-app DevTools like `vite-plugin-vue-devtools` and Nuxt DevTools.
- [Let us know your ideas/suggestions!](https://github.com/nuxt/devtools/discussions/29)
## The Future
We are excited to see how Nuxt DevTools can help you build better apps and improve your developer experience. Going forward, we are imagining something bigger than Nuxt DevTools itself. We believe that having such framework-specific DevTools is the way onwards to provide even better developer experience. We also see there are many parts of such tools can actually be shared and reused across tools. We came up with the idea of the DevTools Kit.
### DevTools Kit
DevTools Kit is an idea of the universal protocol that is still in the early brainstorming phase. We imagine that in the best world, each feature of the DevTools should be **composable, extensible, and collaborative**. Meta-frameworks could build their own features for their specific needs, while the common web-related tools could be shared and collaborated on between different frameworks.

Imagine we could have all these features, each as a standalone package. We could have general web-related tools like SEO, Accessibility, PWA, Static Assets, etc. Then low-level build tools related, like Vite build analyzer, Vite Inspector, or Webpack visualizer, etc. And finally, we could have framework and meta-framework specific tools like Vue Components view, or Nuxt Server API Playground, etc.


At that time, Vue DevTools would be a composition of common web features and Vue-specific features. And Nuxt DevTools would essentially be a composition of the features above, inherit all features from Vue DevTools, and add Nuxt specific features on top of it.

It would even be possible to compose your own DevTools as you like.
That said, we are still thinking about and discussing the details of the DevTools Kit. Stay tuned for more updates!
## Conclusion
We hope you enjoy the new Nuxt DevTools experience! We are looking forward to seeing how it can help you build better apps and improve your developer experience. If you have any ideas or suggestions, feel free to let us know in the [Ideas & Suggestions](https://github.com/nuxt/devtools/discussions/29) discussion.
Thank you for your support and happy hacking! 🚀
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-error-boundary.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-error-boundary.md
#
> The component handles client-side errors happening in its default slot.
The `` uses Vue's [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle#onerrorcaptured) hook under the hood.
## Events
- `@error`: Event emitted when the default slot of the component throws an error.```vue
```
## Slots
- `#error`: Specify a fallback content to display in case of error.```vue
An error occurred: {{ error }}
```
## Examples
### Accessing `error` and `clearError` in script
You can access `error` and `clearError` properties within the component's script as below:
```vue
```
---
# Source: https://nuxt.com/raw/blog/nuxt-icon-v1-0.md
# Introducing Nuxt Icon v1
> Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
Icons are essential to modern web interfaces. They simplify navigation, clarify functionality, and enhance visual appeal. However, implementing icons efficiently involves challenges like scalability, dynamic loading, and server-side rendering (SSR) compatibility.
To address these challenges, we developed **Nuxt Icon v1** — a versatile, modern solution tailored for Nuxt projects. By building on established icon rendering techniques and introducing novel approaches, Nuxt Icon bridges the gap between performance, usability, and flexibility.
In this post, we’ll explore the challenges of icon rendering, the evolution of icon solutions, and how Nuxt Icon combines the best aspects of these methods to offer a seamless experience for developers.
---
## Why Are Icons Challenging?
At first glance, icons seem simple - they are essentially just tiny image elements that enhance a user interface, providing visual cues and enhancing usability.

However, from an engineering perspective, they pose several challenges. Ideal icons should be:
- **Colorable**: Adaptable to themes and color schemes.
- **Scalable**: Render crisply at various sizes and resolutions.
- **Manageable**: Icon sets can contain hundreds or thousands of icons.
- **Efficiently Bundled**: Minimize network requests.
- **Optimally Loaded**: Affect application performance and user experience.
- **Dynamic**: Support dynamic loading for user-generated or runtime-defined icons.

Meeting all these needs requires a carefully engineered solution that balances trade-offs. Let’s explore the evolution of icon solutions and how they address these challenges.
---
## A Journey Through Icon Solutions
Over the years, developers have experimented with various techniques to render icons efficiently. Let’s explore the evolution of these solutions and the challenges they faced.
### 1. `` Tags: The Early Days
The most straightforward solution: using the `` tag. This was the go-to method in the early days of the web.
You'd host your image assets and use an `` tag to link to that image, specifying its width and height. It's simple, requires no setup or runtime dependencies, and works natively in browsers.

However, there are drawbacks. Images can become pixelated, lack color control, and don't scale well. Each icon being a separate image file results in many network requests, which could be slow, especially back in the days of HTTP 1.1. Before the image is downloaded, you might see a flash of invisible icons, which can hurt the user experience. Lastly, it's quite verbose to write, as you need to specify the full path of the image and manage the relative paths. It explains why this approach is rarely used on modern websites today.
---
### 2. Web Fonts: Icon Fonts
As the next step in icon evolution, web fonts emerged as a popular solution. Fonts are inherently vectorized and colorable, making them a natural fit for icons.
Iconset providers typically compile their icons into a special font file, assigning a unique Unicode character to each icon. This is accompanied by a CSS file that maps these Unicode values to specific icon classes.
The advantages of this approach are clear: it's easy to use, colorable, scalable, and requires only a single request to load all icons.

However, there are some downsides. Loading a large font file upfront can be slow, and customizing the icon set is challenging. Additionally, you might experience a flash of invisible icons before the font loads, as there are no fallback fonts available.
---
### 3. Inline SVGs: Component-Based Icons
With the advent of modern frontend frameworks, reusing HTML elements has become significantly easier. This led to the idea of directly inlining SVG tags as components.
To support this approach, many icon sets provide packages with wrappers tailored for each framework. For instance, MDI icons use a shared component and pass icon data as props, while Tabler icons offer a dedicated component for each icon.
Since these are SVGs, they are inherently colorable, scalable, and retain all the features of SVGs. Typically, icons are bundled into the app, eliminating additional network requests and ensuring they are SSR-friendly and visible on the first render.

However, this method has its downsides. It generates numerous SVG DOM elements, which can impact performance when many icons are used. It also increases the bundle size and requires specific integration support for each icon set and framework combination, leading to a degree of vendor lock-in. This makes it challenging to switch to a different icon set or framework.
Despite these trade-offs, this approach is widely adopted today, as switching icon sets or frameworks is not a frequent necessity for most projects.
---
### 4. Iconify Runtime: Dynamic API Access
[Iconify](https://iconify.design/) revolutionized icon usage by aggregating over 200,000 icons across 100+ collections. Its runtime solution dynamically fetched icons via an API, enabling dynamic access to any icon without pre-bundling.
This is a great fit for rendering icons from user-provided content or other dynamic content that you don't know at build time. And it's super easy to set up, as you can even use it as a CDN without any build tools.

While this method offers great flexibility, it does come with some trade-offs. It introduces runtime dependencies, meaning icons will only render after JavaScript is loaded and the icon data is fetched. This approach also poses challenges for server-side rendering (SSR) and caching layers, such as those used in Progressive Web Apps (PWAs).
---
### 5. On-Demand Component Icons
With the unified interface from Iconify and Vite's on-demand approach, we developed [`unplugin-icons`](https://github.com/unplugin/unplugin-icons). This tool allows you to import any icons as components on-demand.
As an [`unplugin`](https://github.com/unjs/unplugin), it supports all popular build tools, including Vite, webpack, and rspack. We provide compilers for popular frameworks like Vue, React, Svelte, and Solid. With Iconify, you can use any icon across any framework, minimizing vendor lock-in.

While this technique shares the same pros and cons as previous component icon solutions, the integration with build tools allows us to serve the full Iconify collection while only shipping the icons you actually use. However, runtime concerns like DOM element management still persist.
---
### 6. Pure CSS Icons
As a side-effect of working on [UnoCSS](https://unocss.dev/), we discovered the potential of embedding icons entirely in CSS, leading to the innovative solution of [Pure CSS Icons](https://antfu.me/posts/icons-in-pure-css).
This method involves inlining SVG icons as data URLs and providing a single class to display the icons. With some tweaks, these icons become colorable, scalable, and even capable of displaying SVG animations.
Browsers can cache the CSS rules, and each icon requires only **one DOM element** to render. This approach ships the icons in a single CSS file with no additional requests. Since it's pure CSS, the icons display along with the rest of your UI, require zero runtime, and work naturally with SSR—your server doesn't need any extra work on the server side.

The only downsides are the lack of full customization for elements inside the SVG and the need to bundle icons at build-time, which isn't dynamic.
---
## The Challenges to Integrate in Nuxt
While I would say that the [Pure CSS Icons](#_6-pure-css-icons) and [On-demand Component Icons](#_5-on-demand-component-icons) would be pretty sufficient for most of the static usages, Nuxt as a full featured framework, has a bit more requirements to integrate icons efficiently:
- **SSR/CSR**: Nuxt works in both server-side rendering (SSR) and client-side rendering (CSR) modes. We care a lot about the end user experience, and we want to ensure that icons are rendered instantly without flickers.
- **Dynamic Icons**: In integrations like [Nuxt Content](https://content.nuxt.com/), the content can be provided at runtime or from external sources, which we are not aware at build time. We want to ensure we have the capability to integrate with those cases well.
- **Performance**: We want to ensure that the icons are bundled efficiently, and the loading of icons is optimized for the best performance.
- **Custom Icons**: While Iconify provides a wide range of icons for selection, we also aware it's pretty common for projects to have their own icon sets, or wanted to use paid icons that are not available in Iconify. Supporting custom icons is crucial for our users.

With these requirements in mind, let's revisit the solutions we discussed earlier and see how they stack up.
For dynamic icons, the Iconify Runtime stands out as a viable option. It allows for dynamic fetching of icons, making it suitable for content that isn't known at build time. However, it has its drawbacks. The reliance on runtime dependencies means it doesn't integrate seamlessly with SSR, and it doesn't support custom icons since the requests are directed to Iconify's servers, which don't have access to our local icon setup.
Conversely, Pure CSS Icons offer excellent performance and SSR compatibility. They ensure icons are rendered instantly without flickers and are bundled efficiently. However, they fall short when it comes to dynamic icons, as they need to be bundled at build time and lack the flexibility to adapt to runtime content changes.
Balancing these trade-offs is indeed challenging. So, why not leverage the strengths of both approaches? By understanding these trade-offs, we can better appreciate the balanced solution that Nuxt Icon v1 offers.
---
## Introducing Nuxt Icon v1: The Balance of Both Worlds
With the flexibility of the Nuxt Module system, Nuxt Icon combines the best of both worlds: the instant rendering of CSS icons and the dynamic fetching of Iconify icons. This dual approach provides a versatile, modern, and customizable icon solution that seamlessly adapts to your project's needs.
### Dual Rendering Modes
To address the trade-offs in rendering approaches, Nuxt Icon introduces a versatile `` component that supports both CSS and SVG modes, both of which are SSR-friendly. Depending on your customization needs, you can switch between these modes for each icon.
In CSS mode, icons are included in the CSS during SSR, ensuring they render instantly without any runtime cost. In SVG mode, icons are inlined as HTML during SSR, providing the same immediate rendering benefits. Both approaches ensure that icons appear on the initial screen without any delay, offering a seamless user experience.

---
### Icon Bundles
Dynamic icons present unique challenges, especially when it comes to loading them efficiently. To address this, we leverage Iconify's API, which allows us to serve any icon on demand via network requests. However, relying solely on this API can introduce delays, especially if the servers are geographically distant from your users.
To mitigate this, we introduced the concept of Icon Bundles. We can bundle frequently used icons directly into the `Client Bundle`. This ensures that these icons render instantly without additional network requests. However, bundling all possible icons isn't feasible due to the potential increase in bundle size.
Given that Nuxt is a full-stack framework, we can strike a balance by introducing a `Server Bundle`. On the server side, bundle size is less of an issue, allowing us to include a more extensive set of icons. During SSR, these icons can be fetched quickly and sent to the client as needed. This setup ensures high performance for commonly used icons while still providing the flexibility to serve any icon from Iconify as a fallback.
By combining client-side bundling for static icons and server-side bundling for dynamic icons, we achieve an optimal balance between performance and flexibility.

---
### Data Flow
Here is a data flow diagram illustrating how Nuxt Icon requests icon data:
1. You use the `` component and provide the icon `name`.
2. Nuxt Icon will first check if the icon is available in the `Client Bundle`, or the SSR payload (icons that are known at SSR will be presented in the payload). If so, the icon will be rendered instantly.
3. If the icon is not available on the client side, Nuxt Icon will fetch the icon data from the server API shipped along with your Nuxt app. Inside the server endpoint, it will query from the `Server Bundle` to see if the icon is available.
4. Between that, there are multiple cache systems involved. Server endpoint cache, HTTP cache, and client-side cache to ensure the icon is fetched efficiently and quickly. Since icon data does not change frequently, we use hard cache strategies to ensure the best performance.
5. When the icon is unknown to both the client and server (dynamic icons), the server endpoint will fallback to the Iconify API to fetch the icon data. Since the server endpoint is cached, the Iconify API will be called only once for each unique icon regardless of how many clients are requesting it, to save resources on both sides.

This layered approach ensures efficient icon delivery, balancing speed and flexibility, while being as dynamic as possible. And balance out the trade-offs between each solution.
---
## Try Nuxt Icon Today
Nuxt Icon v1 represents the culmination of years of innovation in icon rendering. Whether you’re building a dynamic app, a static website, or anything in between, Nuxt Icon adapts to your needs.
It’s easy to add Nuxt Icon to your project by running the following command:
```bash
npx nuxi module add icon
```
Then, import the `` component in your Vue components, providing icon `name` following [Iconify's conventions](https://iconify.design/docs/icons/icon-basics.html):
```vue
```
Explore more with the [documentation](https://github.com/nuxt/icon), experiment with its features, and let us know your thoughts. We’re excited to see how Nuxt Icon transforms your projects!
**Happy Nuxting ✨**
---
# Source: https://nuxt.com/raw/blog/nuxt-image-v2.md
# Nuxt Image v2
> Nuxt Image v2 is out - with full TypeScript support, IPX v3, and new providers!
We're excited to announce **Nuxt Image v2**! 🎉 This release focuses on TypeScript support, performance improvements, and better developer experience.
Nuxt Image v2 works with 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](https://github.com/nuxt/image/pull/1802)).
### Typed composables
The `$img` helper and `useImage()` composable have full type inference ([#1844](https://github.com/nuxt/image/pull/1844)):
```ts
const img = useImage()
// Full autocomplete for modifiers
const url = img('/image.jpg', {
width: 300,
height: 200,
fit: 'cover' // TypeScript knows the valid values!
})
```
### 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`:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
image: {
provider: 'bunny',
bunny: {
baseURL: '...' // TypeScript error if missing!
}
}
})
```
### Typed providers
Finally, if you are using custom image providers, you should use the new `defineProvider` for type-safe configuration:
```ts
// 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 }
}
})
```
## 🚀 IPX v3
We've upgraded to IPX v3 ([#1799](https://github.com/nuxt/image/pull/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](https://github.com/nuxt/image/pull/1473)).
```ts [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
`` now exposes the underlying `` element via template refs:
```vue
```
### Typed slots
Both `` and `` now have properly typed default slots.
```vue
Loading...
```
The slot provides:
- `imgAttrs` - All computed image attributes (sizes, srcset, etc.)
- `isLoaded` - Whether the placeholder has loaded
- `src` - The computed image source URL
## 🌐 New providers
### Shopify
You can now configure the Shopify provider ([#1890](https://github.com/nuxt/image/pull/1890)):
```ts [nuxt.config.ts]
export default defineNuxtConfig({
image: {
provider: 'shopify',
shopify: {
baseURL: 'https://your-store.myshopify.com'
}
}
})
```
### GitHub
This provider lets you inject GitHub avatars and user content ([#1990](https://github.com/nuxt/image/pull/1990)):
```vue
```
## ⚡ Performance
We've made several optimizations to reduce bundle size and improve runtime performance:
- **Better URL encoding** ([#1813](https://github.com/nuxt/image/pull/1813)) - Switched to `URLSearchParams` for more reliable parameter handling
- **Reduced runtime utilities** ([#1816](https://github.com/nuxt/image/pull/1816)) - Removed unused code and simplified implementations
- **Streamlined screen sizes** ([#1931](https://github.com/nuxt/image/pull/1931)) - Aligned default breakpoints with Tailwind CSS
## 🎯 Better layer support
Nuxt Image now properly supports custom image directories within Nuxt layers ([#1880](https://github.com/nuxt/image/pull/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:
```diff
- export const getImage = (src, { modifiers }) => { ... }
+ export default defineProvider({
+ 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](https://image.nuxt.com/get-started/migration#url-formatter-changes) 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/get-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](https://image.nuxt.com/get-started/migration) for step-by-step upgrade instructions.
The quick version:
```bash [Terminal]
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](https://image.nuxt.com/get-started/migration#custom-provider-updates) for examples.
## 🐛 Bug fixes
This release includes several fixes:
- **Preload links**: Fixed preload for multiple densities with single size ([#1851](https://github.com/nuxt/image/pull/1851))
- **Crossorigin attributes**: Correct crossorigin on preload links ([#1836](https://github.com/nuxt/image/pull/1836))
- **Provider-specific formats**: AWS Amplify and Vercel providers now have proper format allow lists ([#1996](https://github.com/nuxt/image/pull/1996))
- **Hygraph**: Prevented broken image URLs ([#1999](https://github.com/nuxt/image/pull/1999))
- **Preset sizes**: Fixed preset size application when component sizes prop is undefined ([#1919](https://github.com/nuxt/image/pull/1919))
- **Cloudflare**: Don't add baseURL if there are no operations ([#1790](https://github.com/nuxt/image/pull/1790))
- **IPX**: Always use IPX provider if external baseURL is provided ([#1800](https://github.com/nuxt/image/pull/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.
## 📚 Resources
- [Documentation](https://image.nuxt.com)
- [GitHub Repository](https://github.com/nuxt/image)
- [Migration Guide](https://image.nuxt.com/get-started/migration)
## 👉 Full release notes
Read the full release notes of Nuxt Image `v2.0.0`.
Happy optimizing! 🖼️✨
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-img.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-img.md
#
> Nuxt provides a component to handle automatic image optimization.
`` is a drop-in replacement for the native `` tag.
- Uses built-in provider to optimize local and remote images
- Converts `src` to provider-optimized URLs
- Automatically resizes images based on `width` and `height`
- Generates responsive sizes when providing `sizes` option
- Supports native lazy loading as well as other `` attributes
## Setup
In order to use `` you should install and enable the Nuxt Image module:
```bash [Terminal]
npx nuxt module add image
```
## Usage
`` outputs a native `img` tag directly (without any wrapper around it). Use it like you would use the `` tag:
```html
```
Will result in:
```html
```
Read more about the `` component.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-island.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-island.md
#
> Nuxt provides the component to render a non-interactive component without any client JS.
When rendering an island component, the content of the island component is static, thus no JS is downloaded client-side.
Changing the island component props triggers a refetch of the island component to re-render it again.
Global styles of your application are sent with the response.
Server only components use `` under the hood
## Props
- `name` : Name of the component to render.
- **type**: `string`
- **required**
- `lazy`: Make the component non-blocking.
- **type**: `boolean`
- **default**: `false`
- `props`: Props to send to the component to render.
- **type**: `Record`
- `source`: Remote source to call the island to render.
- **type**: `string`
- **dangerouslyLoadClientComponents**: Required to load client components from a remote source.
- **type**: `boolean`
- **default**: `false`
Remote islands need `experimental.componentIslands` to be `'local+remote'` in your `nuxt.config`.
Using the `source` prop to render content from a remote server is inherently dangerous. When you specify a remote `source`, you are fully trusting that server to provide safe HTML content that will be rendered directly in your application.
This is similar to using `v-html` with external content - the remote server can inject any HTML, including potentially malicious content. **Only use source with servers you fully trust and control.**
The `dangerouslyLoadClientComponents` prop controls an additional layer of risk: whether to also download and execute client components from the remote source. Even with `dangerouslyLoadClientComponents` disabled (the default), you are still trusting the remote server's HTML output.
By default, component islands are scanned from the `~/components/islands/` directory. So the `~/components/islands/MyIsland.vue` component could be rendered with ``.
## Slots
Slots can be passed to an island component if declared.
Every slot is interactive since the parent component is the one providing it.
Some slots are reserved to `NuxtIsland` for special cases.
- `#fallback`: Specify the content to be rendered before the island loads (if the component is lazy) or if `NuxtIsland` fails to fetch the component.
## Ref
- `refresh()`
- **type**: `() => Promise`
- **description**: force refetch the server component by refetching it.
## Events
- `error`
- **parameters**:
- **error**:
- **type**: `unknown`
- **description**: emitted when when `NuxtIsland` fails to fetch the new island.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-layout.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-layout.md
#
> Nuxt provides the component to show layouts on pages and error pages.
You can use `` component to activate the `default` layout on `app.vue` or `error.vue`.
```vue [app/app.vue]
some page content
```
## Props
- `name`: Specify a layout name to be rendered, can be a string, reactive reference or a computed property. It **must** match the name of the corresponding layout file in the [`app/layouts/`](/docs/4.x/directory-structure/app/layouts) directory, or `false` to disable the layout.
- **type**: `string | false`
- **default**: `default`
```vue [app/pages/index.vue]
```
Please note the layout name is normalized to kebab-case, so if your layout file is named `errorLayout.vue`, it will become `error-layout` when passed as a `name` property to ``.
```vue [error.vue]
```
Read more about dynamic layouts.
- `fallback`: If an invalid layout is passed to the `name` prop, no layout will be rendered. Specify a `fallback` layout to be rendered in this scenario. It **must** match the name of the corresponding layout file in the [`app/layouts/`](/docs/4.x/directory-structure/app/layouts) directory.
- **type**: `string`
- **default**: `null`
## Additional Props
`NuxtLayout` also accepts any additional props that you may need to pass to the layout. These custom props are then made accessible as attributes.
```vue [app/pages/some-page.vue]
```
In the above example, the value of `title` will be available using `$attrs.title` in the template or `useAttrs().title` in `
```
## Transitions
`` renders incoming content via ``, which is then wrapped around Vue’s `` component to activate layout transition. For this to work as expected, it is recommended that `` is **not** the root element of the page component.
```vue [app/pages/index.vue]
Some header template content.
```
```vue [app/layouts/custom.vue]
```
## Layout's Ref
To get the ref of a layout component, access it through `ref.value.layoutRef`.
```vue [app/app.vue]
default layout
```
```vue [app/layouts/default.vue]
default layout
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/nuxt-lifecycle.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/nuxt-lifecycle.md
# Nuxt Lifecycle
> Understanding the lifecycle of Nuxt applications can help you gain deeper insights into how the framework operates, especially for both server-side and client-side rendering.
The goal of this chapter is to provide a high-level overview of the different parts of the framework, their execution order, and how they work together.
## Server lifecycle
On the server, the following steps are executed for every initial request to your application:
### Server plugins once
Nuxt is powered by [Nitro](https://nitro.build/), a modern server engine.
When Nitro starts, it initializes and executes the plugins under the [`/server/plugins`](/docs/4.x/directory-structure/server#server-plugins) directory. These plugins can:
- Capture and handle application-wide errors.
- Register hooks that execute when Nitro shuts down.
- Register hooks for request lifecycle events, such as modifying responses.
Nitro plugins are executed only once when the server starts. In a serverless environment, the server boots on each incoming request, and so do the Nitro plugins. However, they are not awaited.
### Server middleware
After initializing the Nitro server, middleware under `server/middleware/` is executed for every request. Middleware can be used for tasks such as authentication, logging, or request transformation.
Returning a value from middleware will terminate the request and send the returned value as the response. This behavior should generally be avoided to ensure proper request handling!
### App plugins
The Vue and Nuxt instances are created first. Afterward, Nuxt executes its app plugins. This includes:
- Built-in plugins, such as Vue Router and `unhead`.
- Custom plugins located in the `app/plugins/` directory, including those without a suffix (e.g., `myPlugin.ts`) and those with the `.server` suffix (e.g., `myServerPlugin.server.ts`).
Plugins execute in a specific order and may have dependencies on one another. For more details, including execution order and parallelism, refer to the [Plugins documentation](/docs/4.x/directory-structure/app/plugins).
After this step, Nuxt calls the [`app:created`](/docs/4.x/api/advanced/hooks#app-hooks-runtime) hook, which can be used to execute additional logic.
### Route validation
After initializing plugins and before executing middleware, Nuxt calls the `validate` method if it is defined in the `definePageMeta` function. The `validate` method, which can be synchronous or asynchronous, is often used to validate dynamic route parameters.
- The `validate` function should return `true` if the parameters are valid.
- If validation fails, it should return `false` or an object containing a `status` and/or `statusText` to terminate the request.
For more information, see the [Route Validation documentation](/docs/4.x/getting-started/routing#route-validation).
### App middleware
Middleware allows you to run code before navigating to a particular route. It is often used for tasks such as authentication, redirection, or logging.
In Nuxt, there are three types of middleware:
- **Global route middleware**
- **Named route middleware**
- **Anonymous (or inline) route middleware**
Nuxt executes all global middleware on the initial page load (both on server and client) and then again before any client-side navigation. Named and anonymous middleware are executed only on the routes specified in the middleware property of the page(route) meta defined in the corresponding page components.
For details about each type and examples, see the [Middleware documentation](/docs/4.x/directory-structure/app/middleware).
Any redirection on the server will result in a `Location:` header being sent to the browser; the browser then makes a fresh request to this new location. All application state will be reset when this happens, unless persisted in a cookie.
### Page and components
Nuxt renders the page and its components and fetches any required data with `useFetch` and `useAsyncData` during this step. Since there are no dynamic updates and no DOM operations occur on the server, Vue lifecycle hooks such as `onBeforeMount`, `onMounted`, and subsequent hooks are **NOT** executed during SSR.
By default, Vue pauses dependency tracking during SSR for better performance.
There is no reactivity on the server side because Vue SSR renders the app top-down as static HTML, making it impossible to go back and modify content that has already been rendered.
You should avoid code that produces side effects that need cleanup in root scope of `
{{ data }}
```
One important thing to note when we created [useFetch](/docs/api/composables/use-fetch) and [$fetch](/docs/api/utils/dollarfetch) is that during server-side rendering, if you call your API routes, it will emulate the request and call the function code directly: **avoiding an HTTP request and reducing page’s rendering time**.
In terms of developer experience, you will notice that when creating server files, the Nuxt server keeps running without rebuilding the Vue app. **This is because Nuxt 3 supports Hot Module Replacement (HMR) when creating API and server routes.**
Furthermore, by leveraging Object Relational Mapping (ORM) like [drizzle-orm](https://orm.drizzle.team/), developers can connect Edge & Serverless databases such as [D1](https://developers.cloudflare.com/d1/), [Turso](https://turso.tech/), [Neon](https://neon.tech), [Planetscale](https://planetscale.com/) and more.
I created [Atidone](https://todos.nuxt.dev/), an open source demo to showcase a full-stack application with authentication and a database running on the edge. The source code is available on GitHub under the MIT license at [atinux/atidone](https://github.com/atinux/atidone).
## Conclusion
We are excited about edge-side rendering and what it unlocks. Our team at Nuxt can’t wait to see what you will build on top of this!
Feel free to join our [Discord server](https://discord.com/invite/nuxt) or mention [@nuxt_js](https://x.com/nuxt_js) on Twitter to share your work.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-page.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-page.md
#
> The component is required to display pages located in the pages/ directory.
`` is a built-in component that comes with Nuxt. It lets you display top-level or nested pages located in the [`app/pages/`](/docs/4.x/directory-structure/app/pages) directory.
`` is a wrapper around [``](https://router.vuejs.org/api/interfaces/routerviewprops) from Vue Router. It should be used instead of `` because the former takes additional care of internal states. Otherwise, `useRoute()` may return incorrect paths.
`` includes the following components:
```vue
```
By default, Nuxt does not enable `` and ``. You can enable them in the nuxt.config file or by setting the `transition` and `keepalive` properties on ``. If you want to define a specific page, you can set it in `definePageMeta` in the page component.
If you enable `` in your page component, ensure that the page has a single root element.
Since `` uses `` under the hood, the component lifecycle behavior during page changes differs from that of a typical Vue application.
In a typical Vue application, a new page component is mounted **only after** the previous one has been fully unmounted. However, in Nuxt, due to how Vue `` is implemented, the new page component is mounted **before** the previous one is unmounted.
## Props
- `name`: tells `` to render the component with the corresponding name in the matched route record's components option.
- type: `string`
- `route`: route location that has all of its components resolved.
- type: `RouteLocationNormalized`
- `pageKey`: control when the `NuxtPage` component is re-rendered.
- type: `string` or `function`
- `transition`: define global transitions for all pages rendered with the `NuxtPage` component.
- type: `boolean` or [`TransitionProps`](https://vuejs.org/api/built-in-components#transition)
- `keepalive`: control state preservation of pages rendered with the `NuxtPage` component.
- type: `boolean` or [`KeepAliveProps`](https://vuejs.org/api/built-in-components#keepalive)
Nuxt automatically resolves the `name` and `route` by scanning and rendering all Vue component files found in the `/pages` directory.
## Example
For example, if you pass a key that never changes, the `` component will be rendered only once - when it is first mounted.
```vue [app/app.vue]
```
You can also use a dynamic key based on the current route:
```html
```
Don't use `$route` object here as it can cause problems with how `` renders pages with ``.
Alternatively, `pageKey` can be passed as a `key` value via [`definePageMeta`](/docs/4.x/api/utils/define-page-meta) from the `
```
## Page's Ref
To get the `ref` of a page component, access it through `ref.value.pageRef`
```vue [app/app.vue]
```
```vue [my-page.vue]
```
## Custom Props
`` also accepts custom props that you may need to pass further down the hierarchy.
For example, in the below example, the value of `foobar` will be passed to the `NuxtPage` component and then to the page components.
```vue [app/app.vue]
```
We can access the `foobar` prop in the page component:
```vue [app/pages/page.vue]
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-picture.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-picture.md
#
> Nuxt provides a component to handle automatic image optimization.
`` is a drop-in replacement for the native `` tag.
Usage of `` is almost identical to [``](/docs/4.x/api/components/nuxt-img) but it also allows serving modern formats like `webp` when possible.
Learn more about the [`` tag on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/picture).
## Setup
In order to use `` you should install and enable the Nuxt Image module:
```bash [Terminal]
npx nuxt module add image
```
Read more about the `` component.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-route-announcer.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-route-announcer.md
#
> The component adds a hidden element with the page title to announce route changes to assistive technologies.
This component is available in Nuxt v3.12+.
## Usage
Add `` in your [`app.vue`](/docs/4.x/directory-structure/app/app) or [`app/layouts/`](/docs/4.x/directory-structure/app/layouts) to enhance accessibility by informing assistive technologies about page title changes. This ensures that navigational changes are announced to users relying on screen readers.
```vue [app/app.vue]
```
## Slots
You can pass custom HTML or components through the route announcer's default slot.
```vue
{{ message }} was loaded.
```
## Props
- `atomic`: Controls if screen readers only announce changes or the entire content. Set to true for full content readouts on updates, false for changes only. (default `false`)
- `politeness`: Sets the urgency for screen reader announcements: `off` (disable the announcement), `polite` (waits for silence), or `assertive` (interrupts immediately). (default `polite`)
This component is optional.
To achieve full customization, you can implement your own one based on [its source code](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/components/nuxt-route-announcer.ts).
You can hook into the underlying announcer instance using [the `useRouteAnnouncer` composable](/docs/4.x/api/composables/use-route-announcer), which allows you to set a custom announcement message.
---
# Source: https://nuxt.com/raw/blog/nuxt-scripts.md
# Introducing Nuxt Scripts
> Nuxt Scripts provides better performance, privacy, security, and developer experience for third-party scripts.
The Nuxt team, in collaboration with the [Chrome Aurora](https://developer.chrome.com/aurora) team at Google, is excited to announce the public beta release of [Nuxt Scripts](https://scripts.nuxt.com).
Nuxt Scripts is a better way to work with third-party scripts, providing improved performance, privacy, security, and developer experience.

## Getting to Nuxt Scripts
Over a year ago, Daniel published the initial [Nuxt Scripts RFC](https://github.com/nuxt/nuxt/discussions/22016). The RFC proposed a module that would "allow third-party scripts to be managed and optimized, following best practices for performant and compliant websites".
Having [personal experience](https://github.com/harlan-zw/nuxt-delay-hydration) with solving performance issues related to third-party scripts, I knew how difficult these performance optimizations could be. Nonetheless, I was keen to tackle the problem and took over the project.
With the RFC as the seed of the idea, I started prototyping what it could [look like](https://github.com/nuxt/nuxt/discussions/22016#discussioncomment-6527001) using [Unhead](https://unhead.unjs.io/).
Thinking about what I wanted to build exactly, I found that the real issue wasn't just how to load "optimized" third-party scripts but how to make working with third-party scripts a better experience overall.
## Why Build a Third-Party Script Module?
[94% of sites use at least one third-party provider](https://almanac.httparchive.org/en/2022/third-parties#prevalence), with the average site having [five third-party providers](https://docs.google.com/spreadsheets/d/1YqoRRsyiNsrEabVLu2nRU98JIG_0zLLuoQhC2nX8xbM/edit?gid=1428106498#gid=1428106498).
We know that third-party scripts aren't perfect; they [slow down the web](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript#), cause privacy and security issues, and are a pain to work with.
However, they are fundamentally useful and aren't going anywhere soon.
By exploring the issues with third-party scripts, we can see where improvements can be made.
### 😒 Developer Experience: A Full-Stack Headache
Let's walk through adding a third-party script to your Nuxt app using a fictional `tracker.js` script that adds a `track` function to the window.
We start by loading the script using `useHead`.
```ts
useHead({ script: [{ src: '/tracker.js', defer: true }] })
```
However, let's now try to get the script functionality working in our app.
The following steps are common when working with third-party scripts in Nuxt:
- Everything has to be wrapped for SSR safety.
- Flaky checks for if the script has loaded.
- Augmenting the window object for types.
```vue [1: SSR Safety]
```
```vue [2: Script Timing]
```
```vue [3: Broken types]
```
```vue [4: It works?]
```
### 🐌 Performance: "Why can't I get 100 on Lighthouse?"
For a visitor to start interacting with your Nuxt site, the app bundle needs to be downloaded and Vue needs to hydrate the app instance.
Loading third-party scripts can interfere with this hydration process, even when using `async` or `defer`. This slows down the network and blocks the main thread, leading to a degraded user experience and poor [Core Web Vitals](https://web.dev/vitals/).
The [Chrome User Experience Report](https://developer.chrome.com/docs/crux) shows Nuxt sites with numerous third-party resources typically have poorer [Interaction to Next Paint (INP)](https://web.dev/articles/inp) and [Largest Contentful Paint (LCP)](https://web.dev/articles/lcp) scores.
To see how third-party scripts degrade performance, we can look at the [Web Almanac 2022](https://almanac.httparchive.org/en/2022/third-parties#impact-on-performance). The report shows that the top 10 third-party scripts **average median blocking time is 1.4 seconds**.
### 🛡️ Privacy & Security: Do *no* evil?
Of the top 10,000 sites, 58% of them have third-party scripts that [exchange tracking IDs stored in external cookies](https://www3.cs.stonybrook.edu/~mikepo/papers/firstparty.www21.pdf), meaning they can track users across sites even with third-party cookies disabled.
While in many cases our hands are tied with the providers we use, we should try to minimize the amount of our end-users' data that we're leaking where possible.
When we do take on the privacy implications, it can then be difficult to accurately convey these in our privacy policies and build the consent management required to comply with regulations such as GDPR.
Security when using third-party scripts is also a concern. Third-party scripts are common attack vectors for malicious actors, most do not provide `integrity` hashes for their scripts, meaning they can be compromised and inject malicious code into your app at any time.
## What does Nuxt Scripts do about these issues?
### Composable: useScript
This composable sits between the `
```
### Consent Management & Element Event Triggers
The `useScript` composable gives you full control over how and when your scripts are loaded, by either providing a custom `trigger` or manually calling the `load()` function.
Building on top of this, Nuxt Scripts provides advanced triggers to make it even easier.
- [Consent Management](https://scripts.nuxt.com/docs/guides/consent) - Load scripts only after the user has given consent such as with a cookie banner.
- [Element Event Triggers](https://scripts.nuxt.com/docs/guides/script-triggers#element-event-triggers) - Load scripts based on user interactions such as scrolling, clicking, or form submissions.
```ts
const cookieConsentTrigger = useScriptTriggerConsent()
const { proxy } = useScript<{ greeting: () => void }>('/hello.js', {
// script will only be loaded once the consent has been accepted
trigger: cookieConsentTrigger
})
// ...
function acceptCookies() {
cookieConsentTrigger.accept()
}
// greeting() is queued until the user accepts cookies
proxy.greeting()
```
### Bundling Scripts
In many cases, we're loading third-party scripts from a domain that we don't control. This can lead to a number of issues:
- Privacy: The third-party script can track users across sites.
- Security: The third-party script can be compromised and inject malicious code.
- Performance: Extra DNS lookups will slow down the page load.
- Developer Experience: Consented scripts may be blocked by ad blockers.
To mitigate this, Nuxt Scripts provides a way to bundle third-party scripts into your public directory without any extra work.
```ts
useScript('https://cdn.jsdelivr.net/npm/js-confetti@latest/dist/js-confetti.browser.js', {
bundle: true,
})
```
The script will now be served from `/_scripts/{hash}` on your own domain.
## To be continued
As we saw, there are many opportunities to improve third-party scripts for developers and end-users.
The initial release of Nuxt Scripts has solved *some* of these issues, but there's still a lot of work ahead of us.
The next items on the roadmap are:
- [Add web worker support (Partytown)](https://github.com/nuxt/scripts/issues/182)
- [More Live Chat Facade Components](https://github.com/nuxt/scripts/issues/44)
- [Offload Scripts To Nuxt Server Proxy](https://github.com/nuxt/scripts/issues/87)
- [Iframe Script Sandboxing](https://github.com/nuxt/scripts/issues/131)
We'd love to have your contribution and support.
## Getting started
To get started with Nuxt Scripts, we've created a [tutorial](https://scripts.nuxt.com/docs/getting-started/confetti-tutorial) to help you get up and running.
## Credits
- [Harlan Wilton - Nuxt](https://github.com/harlan-zw) (author)
- [Julien Huang - Nuxt](https://github.com/huang-julien) (contributor)
- [Daniel Roe - Nuxt](https://github.com/danielroe) (contributor)
- [Chrome Aurora - Google](https://developer.chrome.com/aurora) (contributor)
And a big thank you to the early contributors.

---
# Source: https://nuxt.com/raw/blog/nuxt-static-improvements.md
# Nuxt 2 Static Improvements
> With Nuxt version 2.13, the full-static mode has been introduced. In addition, a new command nuxt export was added to pre-render your pages without triggering a webpack build with the goal to separate the rendering and build process. The only issue was that most Nuxt users weren't able to unleash the full potential of the separation... until now.
## Introduction
With Nuxt version 2.13, the [full-static mode](/blog/going-full-static) has been introduced. In addition, a new command `nuxt export` was added to pre-render your pages without triggering a webpack build with the goal to separate the rendering and build process. The only issue was that most Nuxt users weren't able to unleash the full potential of the separation... **until now.**
## Faster Static Deployments
With v2.14, `nuxt generate` will **automagically skip webpack build step when no code has been changed** and use the previous build using cache. This will help to drastically improve static deployments time by avoiding unnecessary builds which is usually the most time-consuming part of generation process. Cache support is **platform-agnostic** and works on Netlify, Vercel, or any other CI/CD setup that is caching `node_modules`.
## Generate time: cache vs full webpack build
See the comparison in seconds between two `nuxt generate`:
- `Build` is when a webpack build is required
- `Cache` is only when the content has changed (webpack build skipped)

The static site generation of our projects on content changes are now **~3.6x times** faster 🚀
Project links: [Basic](https://github.com/pi0/nuxt-static-demo), [Strapi Module Docs](https://github.com/nuxt-community/strapi-module/tree/master/docs), [Content Module Docs](https://github.com/nuxt/content/tree/master/docs) and [Nuxt 2 Docs](https://github.com/nuxt/website-v2).
## Using in your projects
1. Update `nuxt` to the latest minor version, which is v2.14.
```bash [npm]
npm update
```
```bash [yarn]
yarn upgrade nuxt
```
1. Ensure `target` is `static` inside your `nuxt.config.js`
```js [nuxt.config.js]
export default {
target: 'static'
// ...
}
```
`nuxt generate` will behave as before to avoid breaking changes and provide legacy compatibility if you keep `target: ‘server’` or don't specify target.
1. That’s it 🙌
Now, the `nuxt generate` command will build the project only if necessary, which is the case when files inside the project have been changed. It will always re-render your routes to static HTML files, like `nuxt export` is doing already.
Now you only have to change your build command back from `nuxt build && nuxt export` to `nuxt generate` on the platform you are using. If you are using a CI, ensure that you are properly caching `node_modules`.
### Excluding Files from Cache
By default, nuxt ignores these directories so if any change happens inside them, build will not be triggered:
- Build directory (`.nuxt/`)
- Static directory (`static/`)
- Generate dist (`dist/`)
- `node_modules`
- `README.md`
- Hidden dotfiles (like `.npmrc`)
You can add more patterns using [generate.cache.ignore](https://v2.nuxt.com/docs/configuration-glossary/configuration-generate/#cache) option in `nuxt.config`:
```js [nuxt.config.js]
export default {
generate: {
cache: {
ignore: [
// When something changed in the docs folder, do not re-build via webpack
'docs'
]
}
}
}
```
It is also possible to use a function for `ignore` option to override default ignore entries.
### Module Authors
What if you are developing a nuxt module that is working with files that should not trigger a rebuild? The best example is for [@nuxt/content](https://content.nuxt.com) module that reads markdown files from the repository. In this case, these files are used within a runtime module, which is the case when using `@nuxt/content`, the module itself can tell nuxt to ignore these files for you already so you don't have to do anything! Module authors can use the new `generate:cache:ignore` hook to do so:
```js
nuxt.hook('generate:cache:ignore', ignore => ignore.push('content'))
```
## How it works
When using the new `nuxt generate` with `static` target, a snapshot including checksum of non-ignored project files as well as nuxt version and some other configuration will be written `.nuxt/build.json`. In addition, we also move the build directory to `node_modules/.cache/nuxt`. Because `node_modules` is cached by all major platforms (Netlify, Vercel, ...) and common CI/CD scripts, this solution works out of the box without additional configuration.
When `nuxt generate` is called subsequently, it will again create a checksum based on your project files and then compare it to the existing one inside `node_modules/.cache/nuxt/build.json`.
If they match, it means that nothing is changed that needs rebuild so we can directly start rendering pages.
If a mismatch is detected, it means that a full rebuild would be necessary. You can also see what file caused rebuild by checking console logs. After the build, nuxt generate will save the new checksum inside `.nuxt/build.json`. You can check full implementation [here](https://github.com/nuxt/nuxt.js/pull/7712).
### Back to old school commands
With Nuxt v2.13, we introduced `nuxt export` and `nuxt serve` specially designed for the static target. With Nuxt v2.14, they are deprecated as `nuxt generate` and `nuxt start` is smart to detect the target and build when necessary.
Server target:
- `nuxt dev` = development server
- `nuxt build` = build your application for production
- `nuxt start` = start the production server (use it for Node.js hosting like Heroku, DigitalOcean, etc)
Static target:
- `nuxt dev` = development server
- `nuxt generate` = build if needed and statically export to `dist/`
- `nuxt start` = serve the `dist/` directory like your static hosting would do (Netlify, Vercel, Surge, etc), great for testing before deploying
## What to do next
- Upgrade your project to [nuxt@2.14.0](https://github.com/nuxt/nuxt.js/releases/tag/v2.14.0)
- Use `nuxt generate` instead of `nuxt export`
- Use `nuxt start` instead of `nuxt serve`
- Enjoy fast deployments 🤙
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/nuxt-time.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/nuxt-time.md
#
> The component displays time in a locale-friendly format with server-client consistency.
This component is available in Nuxt v3.17+.
The `` component lets you display dates and times in a locale-friendly format with proper `
```
It's suggested to wrap your components in either a `
` or `` components as tags will be deduped more intuitively.
If you need to duplicate tags across client-server boundaries, apply a `key` attribute on the `` component.
## Types
Below are the non-reactive types used for [`useHead`](/docs/4.x/api/composables/use-head), [`app.head`](/docs/4.x/api/nuxt-config#head) and components.
```ts
interface MetaObject {
title?: string
titleTemplate?: string | ((title?: string) => string)
templateParams?: Record>
base?: Base
link?: Link[]
meta?: Meta[]
style?: Style[]
script?: Script[]
noscript?: Noscript[]
htmlAttrs?: HtmlAttributes
bodyAttrs?: BodyAttributes
}
```
See [@unhead/vue](https://github.com/unjs/unhead/blob/main/packages/vue/src/types/schema.ts) for more detailed types.
## Features
### Reactivity
Reactivity is supported on all properties, by providing a computed value, a getter, or a reactive object.
```vue [useHead]twoslash
```
```vue [useSeoMeta]twoslash
```
```vue [app/Components]
```
### Title Template
You can use the `titleTemplate` option to provide a dynamic template for customizing the title of your site. For example, you could add the name of your site to the title of every page.
The `titleTemplate` can either be a string, where `%s` is replaced with the title, or a function.
If you want to use a function (for full control), then this cannot be set in your `nuxt.config`. It is recommended instead to set it within your `app.vue` file where it will apply to all pages on your site:
```vue [useHead]twoslash
```
Now, if you set the title to `My Page` with [`useHead`](/docs/4.x/api/composables/use-head) on another page of your site, the title would appear as 'My Page - Site Title' in the browser tab. You could also pass `null` to default to 'Site Title'.
### Template Params
You can use `templateParams` to provide additional placeholders in your `titleTemplate` besides the default `%s`. This allows for more dynamic title generation.
```vue [useHead]twoslash
```
### Body Tags
You can use the `tagPosition: 'bodyClose'` option on applicable tags to append them to the end of the `` tag.
For example:
```vuetwoslash
```
## Examples
### With `definePageMeta`
Within your [`app/pages/` directory](/docs/4.x/directory-structure/app/pages), you can use `definePageMeta` along with [`useHead`](/docs/4.x/api/composables/use-head) to set metadata based on the current route.
For example, you can first set the current page title (this is extracted at build time via a macro, so it can't be set dynamically):
```vue [pages/some-page.vue]twoslash
```
And then in your layout file, you might use the route's metadata you have previously set:
```vue [layouts/default.vue]twoslash
```
### Dynamic Title
In the example below, `titleTemplate` is set either as a string with the `%s` placeholder or as a `function`, which allows greater flexibility in setting the page title dynamically for each route of your Nuxt app:
```vue [app/app.vue]twoslash
```
```vue [app/app.vue]twoslash
```
`nuxt.config` is also used as an alternative way of setting the page title. However, `nuxt.config` does not allow the page title to be dynamic. Therefore, it is recommended to use `titleTemplate` in the `app.vue` file to add a dynamic title, which is then applied to all routes of your Nuxt app.
### External CSS
The example below shows how you might enable Google Fonts using either the `link` property of the [`useHead`](/docs/4.x/api/composables/use-head) composable or using the `` component:
```vue [useHead]twoslash
```
```vue [app/Components]
```
---
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/server-engine.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/server-engine.md
# Server Engine
> Nuxt is powered by a new server engine: Nitro.
While building Nuxt, we created a new server engine: [Nitro](https://nitro.build/).
It is shipped with many features:
- Cross-platform support for Node.js, browsers, service workers and more.
- Serverless support out-of-the-box.
- API routes support.
- Automatic code-splitting and async-loaded chunks.
- Hybrid mode for static + serverless sites.
- Development server with hot module reloading.
## API Layer
Server [API endpoints](/docs/4.x/directory-structure/server#server-routes) and [Middleware](/docs/4.x/directory-structure/server#server-middleware) are added by Nitro that internally uses [h3](https://github.com/h3js/h3).
Key features include:
- Handlers can directly return objects/arrays for an automatically-handled JSON response
- Handlers can return promises, which will be awaited (`res.end()` and `next()` are also supported)
- Helper functions for body parsing, cookie handling, redirects, headers and more
Check out [the h3 docs](https://github.com/h3js/h3) for more information.
Learn more about the API layer in the `server/` directory.
## Direct API Calls
Nitro allows 'direct' calling of routes via the globally-available [`$fetch`](/docs/4.x/api/utils/dollarfetch) helper. This will make an API call to the server if run on the browser, but will directly call the relevant function if run on the server, **saving an additional API call**.
[`$fetch`](/docs/4.x/api/utils/dollarfetch) API is using [ofetch](https://github.com/unjs/ofetch), with key features including:
- Automatic parsing of JSON responses (with access to raw response if needed)
- Request body and params are automatically handled, with correct `Content-Type` headers
For more information on `$fetch` features, check out [ofetch](https://github.com/unjs/ofetch).
## Typed API Routes
When using API routes (or middleware), Nitro will generate typings for these routes as long as you are returning a value instead of using `res.end()` to send a response.
You can access these types when using [`$fetch()`](/docs/4.x/api/utils/dollarfetch) or [`useFetch()`](/docs/4.x/api/composables/use-fetch).
## Standalone Server
Nitro produces a standalone server dist that is independent of `node_modules`.
The server in Nuxt 2 is not standalone and requires part of Nuxt core to be involved by running `nuxt start` (with the [`nuxt-start`](https://www.npmjs.com/package/nuxt-start) or [`nuxt`](https://www.npmjs.com/package/nuxt) distributions) or custom programmatic usage, which is fragile and prone to breakage and not suitable for serverless and service worker environments.
Nuxt generates this dist when running `nuxt build` into a [`.output`](/docs/4.x/directory-structure/output) directory.
The output contains runtime code to run your Nuxt server in any environment (including experimental browser service workers!) and serve your static files, making it a true hybrid framework for the JAMstack. In addition, Nuxt implements a native storage layer, supporting multi-source drivers and local assets.
Read more about Nitro engine on GitHub.
---
# Source: https://nuxt.com/raw/docs/3.x/migration/server.md
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/server.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/server.md
# Source: https://nuxt.com/raw/docs/4.x/migration/server.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/server.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/server.md
# Server
> Build full-stack applications with Nuxt's server framework. You can fetch data from your database or another server, create APIs, or even generate static server-side content like a sitemap or a RSS feed - all from a single codebase.
## Powered by Nitro

Nuxt's server is [Nitro](https://github.com/nitrojs/nitro). It was originally created for Nuxt but is now part of [UnJS](https://unjs.io) and open for other frameworks - and can even be used on its own.
Using Nitro gives Nuxt superpowers:
- Full control of the server-side part of your app
- Universal deployment on any provider (many zero-config)
- Hybrid rendering
Nitro is internally using [h3](https://github.com/h3js/h3), a minimal H(TTP) framework built for high performance and portability.
## Server Endpoints & Middleware
You can easily manage the server-only part of your Nuxt app, from API endpoints to middleware.
Both endpoints and middleware can be defined like this:
```ts [server/api/test.ts]twoslash
export default defineEventHandler(async (event) => {
// ... Do whatever you want here
})
```
And you can directly return `text`, `json`, `html` or even a `stream`.
Out-of-the-box, it supports **hot module replacement** and **auto-import** like the other parts of your Nuxt application.
## Universal Deployment
Nitro offers the ability to deploy your Nuxt app anywhere, from a bare metal server to the edge network, with a start time of just a few milliseconds. That's fast!
There are more than 15 presets to build your Nuxt app for different cloud providers and servers, including:
- [Cloudflare Workers](https://workers.cloudflare.com)
- [Netlify Functions](https://www.netlify.com/platform/core/functions/)
- [Vercel Cloud](https://vercel.com/home)
Or for other runtimes:
## Hybrid Rendering
Nitro has a powerful feature called `routeRules` which allows you to define a set of rules to customize how each route of your Nuxt app is rendered (and more).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
routeRules: {
// Generated at build time for SEO purpose
'/': { prerender: true },
// Cached for 1 hour
'/api/*': { cache: { maxAge: 60 * 60 } },
// Redirection to avoid 404
'/old-page': {
redirect: { to: '/new-page', statusCode: 302 },
},
// ...
},
})
```
Learn about all available route rules are available to customize the rendering mode of your routes.
In addition, there are some route rules (for example, `ssr`, `appMiddleware`, and `noScripts`) that are Nuxt specific to change the behavior when rendering your pages to HTML.
Some route rules (`appMiddleware`, `redirect` and `prerender`) also affect client-side behavior.
Nitro is used to build the app for server side rendering, as well as pre-rendering.
---
# Source: https://nuxt.com/raw/docs/3.x/guide/recipes/sessions-and-authentication.md
# Source: https://nuxt.com/raw/docs/4.x/guide/recipes/sessions-and-authentication.md
# Sessions and Authentication
> Authentication is an extremely common requirement in web apps. This recipe will show you how to implement basic user registration and authentication in your Nuxt app.
## Introduction
In this recipe we'll be setting up authentication in a full-stack Nuxt app using [Nuxt Auth Utils](https://github.com/Atinux/nuxt-auth-utils) which provides convenient utilities for managing client-side and server-side session data.
The module uses secured & sealed cookies to store session data, so you don't need to setup a database to store session data.
## Install nuxt-auth-utils
Install the `nuxt-auth-utils` module using the `nuxt` CLI.
```bash [Terminal]
npx nuxt module add auth-utils
```
This command will install `nuxt-auth-utils` as dependency and push it in the `modules` section of our `nuxt.config.ts`
## Cookie Encryption Key
As `nuxt-auth-utils` uses sealed cookies to store session data, session cookies are encrypted using a secret key from the `NUXT_SESSION_PASSWORD` environment variable.
If not set, this environment variable will be added to your `.env` automatically when running in development mode.
```ini [.env]
NUXT_SESSION_PASSWORD=a-random-password-with-at-least-32-characters
```
You'll need to add this environment variable to your production environment before deploying.
## Login API Route
For this recipe, we'll create a simple API route to sign-in a user based on static data.
Let's create a `/api/login` API route that will accept a POST request with the email and password in the request body.
```ts [server/api/login.post.ts]
import { z } from 'zod'
const bodySchema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
export default defineEventHandler(async (event) => {
const { email, password } = await readValidatedBody(event, bodySchema.parse)
if (email === 'admin@admin.com' && password === 'iamtheadmin') {
// set the user session in the cookie
// this server util is auto-imported by the auth-utils module
await setUserSession(event, {
user: {
name: 'John Doe',
},
})
return {}
}
throw createError({
status: 401,
message: 'Bad credentials',
})
})
```
Make sure to install the `zod` dependency in your project (`npm i zod`).
Read more about the `setUserSession` server helper exposed by `nuxt-auth-utils`.
## Login Page
The module exposes a Vue composable to know if a user is authenticated in our application:
```vue
```
Let's create a login page with a form to submit the login data to our `/api/login` route.
```vue [app/pages/login.vue]
```
## Protect API Routes
Protecting server routes is key to making sure your data is safe. Client-side middleware is helpful for the user, but without server-side protection your data can still be accessed. It is critical to protect any routes with sensitive data, we should return a 401 error if the user is not logged in on those.
The `auth-utils` module provides the `requireUserSession` utility function to help make sure that users are logged in and have an active session.
Let's create an example of a `/api/user/stats` route that only authenticated users can access.
```ts [server/api/user/stats.get.ts]
export default defineEventHandler(async (event) => {
// make sure the user is logged in
// This will throw a 401 error if the request doesn't come from a valid user session
const { user } = await requireUserSession(event)
// TODO: Fetch some stats based on the user
return {}
})
```
## Protect App Routes
Our data is safe with the server-side route in place, but without doing anything else, unauthenticated users would probably get some odd data when trying to access the `/users` page. We should create a [client-side middleware](https://nuxt.com/docs/4.x/directory-structure/app/middleware) to protect the route on the client side and redirect users to the login page.
`nuxt-auth-utils` provides a convenient `useUserSession` composable which we'll use to check if the user is logged in, and redirect them if they are not.
We'll create a middleware in the `/middleware` directory. Unlike on the server, client-side middleware is not automatically applied to all endpoints, and we'll need to specify where we want it applied.
```typescript [app/middleware/authenticated.ts]
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()
// redirect the user to the login screen if they're not authenticated
if (!loggedIn.value) {
return navigateTo('/login')
}
})
```
## Home Page
Now that we have our app middleware to protect our routes, we can use it on our home page that display our authenticated user information. If the user is not authenticated, they will be redirected to the login page.
We'll use [`definePageMeta`](/docs/4.x/api/utils/define-page-meta) to apply the middleware to the route that we want to protect.
```vue [app/pages/index.vue]
Welcome {{ user.name }}
```
We also added a logout button to clear the session and redirect the user to the login page.
## Conclusion
We've successfully set up a very basic user authentication and session management in our Nuxt app. We've also protected sensitive routes on the server and client side to ensure that only authenticated users can access them.
As next steps, you can:
- Add authentication using the [20+ supported OAuth providers](https://github.com/atinux/nuxt-auth-utils?tab=readme-ov-file#supported-oauth-providers)
- Add a database to store users, see [Nitro SQL Database](https://nitro.build/guide/database) or [NuxtHub SQL Database](https://hub.nuxt.com/docs/features/database)
- Let user signup with email & password using [password hashing](https://github.com/atinux/nuxt-auth-utils?tab=readme-ov-file#password-hashing)
- Add support for [WebAuthn / Passkeys](https://github.com/atinux/nuxt-auth-utils?tab=readme-ov-file#webauthn-passkey)
Checkout the open source [atidone repository](https://github.com/atinux/atidone) for a full example of a Nuxt app with OAuth authentication, database and CRUD operations.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/set-page-layout.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/set-page-layout.md
# setPageLayout
> setPageLayout allows you to dynamically change the layout of a page.
`setPageLayout` allows you to dynamically change the layout of a page. It relies on access to the Nuxt context and therefore can only be called within the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context).
```ts [app/middleware/custom-layout.ts]
export default defineNuxtRouteMiddleware((to) => {
// Set the layout on the route you are navigating _to_
setPageLayout('other')
})
```
## Passing Props to Layouts
You can pass props to the layout by providing an object as the second argument:
```ts [app/middleware/admin-layout.ts]
export default defineNuxtRouteMiddleware((to) => {
setPageLayout('admin', {
sidebar: true,
title: 'Dashboard',
})
})
```
The layout can then receive these props:
```vue [app/layouts/admin.vue]
{{ title }}
```
If you choose to set the layout dynamically on the server side, you *must* do so before the layout is rendered by Vue (that is, within a plugin or route middleware) to avoid a hydration mismatch.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/set-response-status.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/set-response-status.md
# setResponseStatus
> setResponseStatus sets the status (and optionally the statusText) of the response.
Nuxt provides composables and utilities for first-class server-side-rendering support.
`setResponseStatus` sets the status (and optionally the statusText) of the response.
`setResponseStatus` can only be called in the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context).
```ts
const event = useRequestEvent()
// event will be undefined in the browser
if (event) {
// Set the status code to 404 for a custom 404 page
setResponseStatus(event, 404)
// Set the status message as well
setResponseStatus(event, 404, 'Page Not Found')
}
```
In the browser, `setResponseStatus` will have no effect.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/shared.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/shared.md
# shared
> Use the shared/ directory to share functionality between the Vue app and the Nitro server.
The `shared/` directory allows you to share code that can be used in both the Vue app and the Nitro server.
The `shared/` directory is available in Nuxt v3.14+.
Code in the `shared/` directory cannot import any Vue or Nitro code.
## Usage
**Method 1:** Named export
```ts [shared/utils/capitalize.ts]twoslash
export const capitalize = (input: string) => {
return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}
```
**Method 2:** Default export
```ts [shared/utils/capitalize.ts]twoslash
export default function (input: string) {
return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}
```
You can now use [auto-imported](/docs/4.x/directory-structure/shared) utilities in your Nuxt app and `server/` directory.
```vue [app/app.vue]
{{ hello }}
```
```ts [server/api/hello.get.ts]
export default defineEventHandler((event) => {
return {
hello: capitalize('hello'),
}
})
```
## How Files Are Scanned
Only files in the `shared/utils/` and `shared/types/` directories will be auto-imported. Files nested within subdirectories of these directories will not be auto-imported unless you add these directories to `imports.dirs` and `nitro.imports.dirs`.
The way `shared/utils` and `shared/types` auto-imports work and are scanned is identical to the [`app/composables/`](/docs/4.x/directory-structure/app/composables) and [`app/utils/`](/docs/4.x/directory-structure/app/utils) directories.
```bash [Directory Structure]
-| shared/
---| capitalize.ts # Not auto-imported
---| formatters
-----| lower.ts # Not auto-imported
---| utils/
-----| lower.ts # Auto-imported
-----| formatters
-------| upper.ts # Not auto-imported
---| types/
-----| bar.ts # Auto-imported
```
Any other files you create in the `shared/` folder must be manually imported using the `#shared` alias (automatically configured by Nuxt):
```ts
// For files directly in the shared directory
import capitalize from '#shared/capitalize'
// For files in nested directories
import lower from '#shared/formatters/lower'
// For files nested in a folder within utils
import upper from '#shared/utils/formatters/upper'
```
This alias ensures consistent imports across your application, regardless of the importing file's location.
---
# Source: https://nuxt.com/raw/blog/shiki-v1.md
# The Evolution of Shiki v1.0
> Shiki v1.0 came with many improvements and features - see how Nuxt drives the evolution of Shiki!
[Shiki](https://github.com/shikijs/shiki) is a syntax highlighter that uses [TextMate grammars and themes](https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide#textmate-grammars), the same engine that powers VS Code. It provides one of the most accurate and beautiful syntax highlighting for your code snippets. It was created by [Pine Wu](https://github.com/octref) back in 2018, when he was part of the VS Code team. It started as an experiment to use [Oniguruma](https://github.com/microsoft/vscode-oniguruma) to do syntax highlighting.
Different from existing syntax highlighters like [Prism](https://prismjs.com/) and [Highlight.js](https://highlightjs.org/) that designed to run in the browser, Shiki took a different approach by **highlighting ahead of time**. It ships the highlighted HTML to the client, producing accurate and beautiful syntax highlighting with **zero JavaScript**. It soon took off and became a very popular choice, especially for static site generators and documentation sites.
For example, with the code snippet below:
```ts
export default defineNuxtConfig({
modules: [
'@nuxt/content',
],
})
```
Shiki will generate the following HTML:
```html
```
It might look a bit overwhelming if you read it, but **this piece of HTML works everywhere without any JavaScript or CSS**. TextMate grammars has a very rich representation of the types of every token (TextMate scopes). Since Shiki flattens all the tokens into styled spans, it achieves accurate results that most traditional CSS-based highlighters have difficulties achieving.
While Shiki is awesome, it's still a library that is designed to run on Node.js. This means it is limited to highlighting static code only and would have trouble with dynamic code, because Shiki doesn't work in the browser. In addition, Shiki relies on the WASM binary of Oniguruma, as well as a bunch of heavy grammar and theme files in JSON. It uses Node.js filesystem and path resolution to load these files, which is not accessible in the browser.
To improve that situation, I [started this RFC](https://github.com/shikijs/shiki/issues/91) that later landed with [this PR](https://github.com/shikijs/shiki/pull/109) and shipped in Shiki v0.9. While it abstracted the file loading layer to use fetch or filesystem based on the environment, it's still quite complicated to use as you need to serve the grammars and theme files somewhere in your bundle or CDN manually, then call the `setCDN` method to tell Shiki where to load these files.
The solution is not perfect but at least it made it possible to run Shiki in the browser to highlight dynamic content. We have been using that approach since then - until the story of this article began.
## The Start
Nuxt is putting a lot effort in pushing the [web to the edge](/blog/nuxt-on-the-edge), making the web more accessible with lower latency and better performance. Like CDN servers, edge hosting services such as [CloudFlare Workers](https://workers.cloudflare.com/) are deployed all over the world. Users get the content from the nearest edge server without the round trips to the origin server which could be thousands of miles away. With the awesome benefits it provides, it also comes with some trade-offs. For example, edge servers use a restricted runtime environment. CloudFlare Workers also does not support file system access and usually don't preserve the state between requests. While Shiki's main overhead is loading the grammars and themes upfront, that wouldn't work well in the edge environment.
It all started with a chat between [Sébastien](https://x.com/Atinux) and me. We were trying to make [Nuxt Content](https://github.com/nuxt/content) which uses Shiki to highlight the code blocks, to work on the edge.

I started the experiments by patching [`shiki-es`](https://github.com/pi0/shiki-es) (a ESM build of Shiki by [Pooya Parsa](https://github.com/pi0)) locally, to convert the grammars and themes files into [ECMAScript Module (ESM)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) so that it could be understood and bundled by the build tools. This was done to create the code bundle for CloudFlare Workers to consume without using the filesystem nor making network requests.
```ts [Before - Read JSON assets from filesystem]
import fs from 'fs/promises'
const cssGrammar = JSON.parse(await fs.readFile('../langs/css.json', 'utf-8'))
```
```ts [After - Using ESM import]
const cssGrammar = await import('../langs/css.mjs').then(m => m.default)
```
We need to wrap the JSON files into ESM as inline literal so that we can use [`import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) to dynamically import them. The difference is that `import()` is a standard JavaScript feature that works everywhere, while `fs.readFile` is a Node.js specific API that only works in Node.js. Having `import()` statically would also make bundlers like [Rollup](https://rollupjs.org/) and [webpack](https://webpack.js.org/) able to construct the module relationship graph and [emit the bundled code as chunks](https://rollupjs.org/tutorial/#code-splitting).
Then, I realized that it actually takes more than that to make it work on edge runtimes. Since bundlers expect imports to be resolvable at build time (meaning that in order to support all the languages and themes), we need to list all the import statements in every single grammar and theme file in the codebase. This would end up with a huge bundle size with a bunch of grammars and themes that you might not actually use. This problem is particularly important in the edge environment, where the bundle size is critical for performance.
So, we needed to figure out a better middle ground to make it work better.
## The Fork - Shikiji
Knowing this might fundamentally change the way Shiki works, and since we don't want to risk breaking the existing Shiki users with our experiments, I started a fork of Shiki called [Shikiji](https://github.com/antfu/shikiji). I rewrote the code from scratch while keeping the previous API design decisions in mind. The goal is to make Shiki runtime-agnostic, performant and efficient, like the philosophy we have at [UnJS](https://github.com/unjs).
To make that happen, we need to make Shikiji completely ESM-friendly, pure and [tree-shakable](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking). This goes all the way up to the dependencies of Shiki such as [`vscode-oniguruma`](https://github.com/microsoft/vscode-oniguruma) and [`vscode-textmate`](https://github.com/microsoft/vscode-textmate), which are provided in [Common JS (CJS)](https://requirejs.org/docs/commonjs.html) format. `vscode-oniguruma` also contains a WASM binding generated by [`emscripten`](https://github.com/emscripten-core/emscripten) that contains [dangling promises](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-floating-promises.md) that will make CloudFlare Workers fail to finish the request. We ended up by embedding the WASM binary into a [base64 string](https://en.wikipedia.org/wiki/Base64) and shipping it as an ES module, manually rewriting the WASM binding to avoid dangling promises, and [vendored `vscode-textmate`](https://github.com/shikijs/shiki/blob/main/CONTRIBUTING.md#clone) to compile from its source code and produce the efficient ESM output.
The end result was very promising. We managed to get Shikiji working on any runtime environment, with even the possibility to [import it from CDN and run in the browser](https://shiki.style/guide/install#cdn-usage) with a single line of code.
We also took the chance to improve the API and the internal architecture of Shiki. We switched from simple string concatenation to use [`hast`](https://github.com/syntax-tree/hast), creating an Abstract Syntax Tree (AST) for generating the HTML output. This opens up the possibility of exposing a [Transformers API](https://shiki.style/guide/transformers) to allow users to modify the intermediate HAST and do many cool integrations that would be very hard to achieve previously.
Dark/Light mode support [was a frequently requested feature](https://github.com/shikijs/shiki/issues/33). Because of the static approach Shiki takes, it won't be possible to change the theme on the fly at rendering. The solution in the past was to generate the highlighted HTML twice, and toggle their visibility based on the user's preference - it wasn't efficient as it duplicate the payload, or used [CSS variables theme](https://github.com/shikijs/shiki/pull/212) which lost the granular highlighting Shiki is great for. With the new architecture that Shikiji has, I took a step back and rethought the problem, and [came up with the idea](https://github.com/shikijs/shiki/issues/33#issuecomment-1676362336) of breaking down the common tokens and merge multiple themes as inlined CSS variables, which provide efficient output while aligning with the Shiki's philosophy. You can learn more about it in [Shiki's documentation](https://shiki.style/guide/dual-themes).
To make the migration easier, we also created the [`shikiji-compat` compatibility layer](https://shikiji.netlify.app/guide/compat), which uses Shikiji's new foundation and provides backward compatibility API.
To get Shikiji to work on Cloudflare Workers, we had one last challenge as they don't support [initiating WASM instance](https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/instantiate_static)s from inlined binary data. Instead it requires importing the static `.wasm` assets for security reasons. This means that our "All-in-ESM" approach does not work well on CloudFlare. This would require extra work for users to provide different WASM sources, which makes the experience more difficult than we intended. At this moment, [Pooya Parsa](https://github.com/pi0) stepped in and made the universal layer [`unjs/unwasm`](https://github.com/unjs/unwasm), which supports the upcoming [WebAssembly/ES Module Integration](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration) proposal. It has been integrated into [Nitro to have automated WASM targets](https://github.com/unjs/nitro/pull/2037). We hope that `unwasm` will help developers to have a better experience when working with WASM.
Overall, the Shikiji rewrite works well. [Nuxt Content](https://github.com/nuxt/content), [VitePress](https://vitepress.dev/) and [Astro](https://astro.build/) have been migrated to it. The feedback we have received has also been very positive.
## Merging Back
I am a team member of Shiki and have helped to do releases from time to time. While [Pine](https://github.com/octref) is the lead of Shiki, he was busy on other stuff and Shiki's iterations slowed down. During the experiments in Shikiji, I [proposed a few improvements](https://github.com/shikijs/shiki/issues/510) that could help Shiki acquire a modern structure. While generally everyone agreed with that direction, there would have been quite a lot of work to do and no one started to work on that.
While we were happy to use Shikiji to solve the problems we had, we certainly didn't want to see the community split by two different versions of Shiki. After a call with Pine, we made the consensus to merge the two projects into one:
feat!: merge Shikiji back into Shiki for v1.0
#557
We are really happy to see that our work in Shikiji has been merged back to Shiki, that not only works for ourselves, but also benefits the entire community. With this merge, it **solves around 95% of the open issues** we have had in Shiki for years:

Shiki now also got [a brand new documentation site](https://shiki.style/) where you can also play it right in your browser (thanks to the agnostic approach!). Many frameworks now has built-in integration with Shiki, maybe you are already using it somewhere!
## Twoslash
[Twoslash](https://github.com/twoslashes/twoslash) is an integration tool to retrieve type information from [TypeScript Language Services](https://github.com/microsoft/TypeScript/wiki/Using-the-Language-Service-API) and generated to your code snippet. It essentially make your static code snippet to have hover type information similar to your VS Code editor. It's made by [Orta Therox](https://github.com/orta) for the [TypeScript documentation site](https://github.com/microsoft/TypeScript-Website), there you can find [the original source code here](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ts-twoslasher). Orta also created the [Twoslash integration for Shiki v0.x versions](https://github.com/shikijs/twoslash). Back then, Shiki [did not have proper plugin system](https://github.com/shikijs/shiki/issues/380), that makes the `shiki-twoslash` had to be built as a wrapper over Shiki, make it a bit hard to set up as the existing Shiki integrations won't directly work with Twoslash.
We also took the chance to revise the Twoslash integrations when we were rewriting Shikiji, also a way to [dog-fooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) and verify the extensibility. With the new HAST internal, we are able to [integrate Twoslash as a transformer plugin](https://shiki.style/packages/twoslash), making it works everywhere that Shiki works and also in a composable way to be used with other transformers.
With this, we started to think that we could probably get Twoslash to work on [nuxt.com](/), the website you are looking at. nuxt.com uses [Nuxt Content](https://github.com/nuxt/content) under the hood, and different from other documentation tools like VitePress, one of the benefits Nuxt Content provides is that it's able to handle dynamic content and runs on the edge. Since Twoslash is relying on TypeScript as well as the giant types modules graph from your dependencies, that would be not ideal to ship all those things to the edge or browser. Sounds tricky, but challenge accepted!
We first come up of fetching the types on-demand from CDN, using the [Auto-Type-Acquisition](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ata) technique that you will see on the [TypeScript playground](https://www.typescriptlang.org/play). We made the [`twoslash-cdn`](https://github.com/antfu/twoslash-cdn) that allows Twoslash to run in any runtime. However, still, it sounds like not the most optimal solution, as it would still require to make many network requests that might defeat the purpose of running on the edge.
After a few iterations on the underlying tools (e.g. on [`@nuxtjs/mdc`](https://github.com/nuxt-modules/mdc/pull/129), the markdown compiler used by Nuxt Content), we managed to take the hybrid approach and made [`nuxt-content-twoslash`](https://github.com/antfu/nuxt-content-twoslash) that runs Twoslash on build time and caches the results for edge rendering. This way we could avoid shipping any extra dependencies to the final bundle, but still have the rich interactive code snippets on the website:
```vuetwoslash
Double is: {{ double }}
```
During that, we also took the chance to refactor [Twoslash](https://github.com/twoslashes/twoslash) with Orta to have a more efficient and modern structure. It also allows us have [`twoslash-vue`](https://github.com/twoslashes/twoslash/tree/main/packages/twoslash-vue) that provides the [Vue SFC](https://vuejs.org/guide/scaling-up/sfc.html) support as you are playing above. It's powered by [Volar.js](https://github.com/volarjs/volar.js) and [`vuejs/language-tools`](https://github.com/vuejs/language-tools). With Volar growing to be framework agnostic and frameworks to work together, we are looking forward to see such integrations to expand to more syntaxes like Astro and Svelte components files in the future.
## Integrations
If you want to give Shiki a try in your own website, here you can find some integrations that we have made:
- [Nuxt](https://shiki.style/packages/nuxt)
- If using [Nuxt Content](https://content.nuxt.com/), Shiki is [build-in](https://content.nuxt.com/get-started/configuration#highlight). For Twoslash, you can add [`nuxt-content-twoslash`](https://github.com/antfu/nuxt-content-twoslash) on top.
- If not, you can use [`nuxt-shiki`](https://github.com/pi0/nuxt-shiki) to use Shiki as Vue component or composibles.
- [VitePress](https://shiki.style/packages/vitepress)
- Shiki is [built-in](https://vitepress.dev/guide/markdown#syntax-highlighting-in-code-blocks). For Twoslash, you can use [`vitepress-twoslash`](https://shiki.style/packages/vitepress#twoslash).
- Low-level integrations - Shiki provides official integrations for markdown compilers:
- [`markdown-it`](https://shiki.style/packages/markdown-it) - Plugin for [`markdown-it`](https://github.com/markdown-it/markdown-it)
- [`rehype`](https://shiki.style/packages/rehype) - Plugin for [`rehype`](https://github.com/rehypejs/rehype)
Check out more integrations on [Shiki's Documentation](https://shiki.style/)
## Conclusions
**Our mission at Nuxt is not only to make a better framework for developers, but also to make the entire frontend and web ecosystem a better place.** We are keeping pushing the boundaries and endorse the modern web standards and best practices. We hope you enjoy the new [Shiki](https://github.com/shikijs/shiki), [unwasm](https://github.com/unjs/unwasm), [Twoslash](https://github.com/twoslashes/twoslash) and many other tools we made in the process of making Nuxt and the web better.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/show-error.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/show-error.md
# showError
> Nuxt provides a quick and simple way to show a full screen error page if needed.
Within the [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context) you can use `showError` to show an error.
**Parameters:**
- `error`: `string | Error | Partial<{ cause, data, message, name, stack, status, statusText }>`
```ts
showError('😱 Oh no, an error has been thrown.')
showError({
status: 404,
statusText: 'Page Not Found',
})
```
The error is set in the state using [`useError()`](/docs/4.x/api/composables/use-error) to create a reactive and SSR-friendly shared error state across components.
`showError` calls the `app:error` hook.
---
# Source: https://nuxt.com/raw/deploy/sst.md
# SST
> Deploy your Nuxt Application to AWS with SST.
Nuxt supports deploying on [SST](https://sst.dev/) with minimal configuration.
## Quick start
1. Create a Nuxt project.
2. Init SST in your project.
```bash
npx sst@latest init
```
3. It should detect that your are using Nuxt and ask you to update your `nuxt.config.ts` file.
```ts
nitro: {
preset: 'aws-lambda'
}
```
4. Once you are ready to deploy, run.
```bash
npx sst deploy --stage production
```
You can [read the full Nuxt on SST tutorial here](https://sst.dev/docs/start/aws/nuxt).
## More options
You can also deploy Nuxt to a container using SST. Head over to the [SST docs to learn more](https://sst.dev/docs/start/aws/nuxt).
---
# Source: https://nuxt.com/raw/docs/3.x/examples/features/state-management.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/state-management.md
# Source: https://nuxt.com/raw/docs/4.x/examples/features/state-management.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/state-management.md
# State Management
> Nuxt provides powerful state management libraries and the useState composable to create a reactive and SSR-friendly shared state.
Nuxt provides the [`useState`](/docs/4.x/api/composables/use-state) composable to create a reactive and SSR-friendly shared state across components.
[`useState`](/docs/4.x/api/composables/use-state) is an SSR-friendly [`ref`](https://vuejs.org/api/reactivity-core#ref) replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
Because the data inside [`useState`](/docs/4.x/api/composables/use-state) will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols.
Read more about `useState` composable.
## Best Practices
Never define `const state = ref()` outside of `
Counter: {{ counter }}
```
To globally invalidate cached state, see [`clearNuxtState`](/docs/4.x/api/utils/clear-nuxt-state) util.
### Initializing State
Most of the time, you will want to initialize your state with data that resolves asynchronously. You can use the [`app.vue`](/docs/4.x/directory-structure/app/app) component with the [`callOnce`](/docs/4.x/api/utils/call-once) util to do so.
```vue [app/app.vue]twoslash
```
This is similar to the [`nuxtServerInit` action](https://v2.nuxt.com/docs/directory-structure/store/#the-nuxtserverinit-action) in Nuxt 2, which allows filling the initial state of your store server-side before rendering the page.
### Usage with Pinia
In this example, we leverage the [Pinia module](/modules/pinia) to create a global store and use it across the app.
Make sure to install the Pinia module with `npx nuxt module add pinia` or follow the [module's installation steps](https://pinia.vuejs.org/ssr/nuxt.html#Installation).
```ts [app/stores/website.ts]
export const useWebsiteStore = defineStore('websiteStore', {
state: () => ({
name: '',
description: '',
}),
actions: {
async fetch () {
const infos = await $fetch('https://api.nuxt.com/modules/pinia')
this.name = infos.name
this.description = infos.description
},
},
})
```
```vue [app/app.vue]
```
## Shared State
By using [auto-imported composables](/docs/4.x/directory-structure/app/composables) we can define global type-safe states and import them across the app.
```ts [composables/states.ts]twoslash
export const useColor = () => useState('color', () => 'pink')
```
```vue [app/app.vue]
Current color: {{ color }}
```
## Using third-party libraries
Nuxt **used to rely** on the Vuex library to provide global state management. If you are migrating from Nuxt 2, please head to [the migration guide](/docs/4.x/migration/configuration#vuex).
Nuxt is not opinionated about state management, so feel free to choose the right solution for your needs. There are multiple integrations with the most popular state management libraries, including:
- [Pinia](/modules/pinia) - the official Vue recommendation
- [Harlem](/modules/harlem) - immutable global state management
- [XState](/modules/xstate) - state machine approach with tools for visualizing and testing your state logic
---
# Source: https://nuxt.com/raw/deploy/stormkit.md
# Stormkit
> Deploy your Nuxt Application to Stormkit infrastructure.
**Zero Configuration ✨**
Integration with [Stormkit](https://www.stormkit.io/) is possible with zero configuration, [learn more](https://nitro.unjs.io/deploy#zero-config-providers).
## Setup
Follow the steps to [create a new app](https://app.stormkit.io/apps/new) on Stormkit.
## Deployment
By default, Stormkit will deploy your apps automatically when you push changes to your main branch. But to trigger a manual deploy (for example, you might do this for the very first deployment), you may click `Deploy now`.
Head over **Nitro documentation** to learn more about the stormkit deployment preset.
---
# Source: https://nuxt.com/raw/docs/3.x/getting-started/styling.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/styling.md
# Styling
> Learn how to style your Nuxt application.
Nuxt is highly flexible when it comes to styling. Write your own styles, or reference local and external stylesheets.
You can use CSS preprocessors, CSS frameworks, UI libraries and Nuxt modules to style your application.
## Local Stylesheets
If you're writing local stylesheets, the natural place to put them is the [`app/assets/` directory](/docs/4.x/directory-structure/app/assets).
### Importing Within Components
You can import stylesheets in your pages, layouts and components directly.
You can use a JavaScript import, or a CSS [`@import` statement](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@import).
```vue [app/pages/index.vue]
```
The stylesheets will be inlined in the HTML rendered by Nuxt.
### The CSS Property
You can also use the `css` property in the Nuxt configuration.
The natural place for your stylesheets is the [`app/assets/` directory](/docs/4.x/directory-structure/app/assets). You can then reference its path and Nuxt will include it to all the pages of your application.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
css: ['~/assets/css/main.css'],
})
```
The stylesheets will be inlined in the HTML rendered by Nuxt, injected globally and present in all pages.
### Working With Fonts
Place your local fonts files in your `public/` directory, for example in `public/fonts`. You can then reference them in your stylesheets using `url()`.
```css [assets/css/main.css]
@font-face {
font-family: 'FarAwayGalaxy';
src: url('/fonts/FarAwayGalaxy.woff') format('woff');
font-weight: normal;
font-style: normal;
font-display: swap;
}
```
Then reference your fonts by name in your stylesheets, pages or components:
```vue
```
### Stylesheets Distributed Through NPM
You can also reference stylesheets that are distributed through npm. Let's use the popular `animate.css` library as an example.
```bash [npm]
npm install animate.css
```
```bash [yarn]
yarn add animate.css
```
```bash [pnpm]
pnpm install animate.css
```
```bash [bun]
bun install animate.css
```
```bash [deno]
deno install npm:animate.css
```
Then you can reference it directly in your pages, layouts and components:
```vue [app/app.vue]
```
The package can also be referenced as a string in the css property of your Nuxt configuration.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
css: ['animate.css'],
})
```
## External Stylesheets
You can include external stylesheets in your application by adding a link element in the head section of your nuxt.config file. You can achieve this result using different methods. Note that local stylesheets can also be included this way.
You can manipulate the head with the [`app.head`](/docs/4.x/api/nuxt-config#head) property of your Nuxt configuration:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
app: {
head: {
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }],
},
},
})
```
### Dynamically Adding Stylesheets
You can use the useHead composable to dynamically set a value in your head in your code.
```tstwoslash
useHead({
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }],
})
```
Nuxt uses `unhead` under the hood, and you can refer to [its full documentation](https://unhead.unjs.io).
### Modifying The Rendered Head With A Nitro Plugin
If you need more advanced control, you can intercept the rendered html with a hook and modify the head programmatically.
Create a plugin in `~/server/plugins/my-plugin.ts` like this:
```ts [server/plugins/my-plugin.ts]
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('render:html', (html) => {
html.head.push('')
})
})
```
External stylesheets are render-blocking resources: they must be loaded and processed before the browser renders the page. Web pages that contain unnecessarily large styles take longer to render. You can read more about it on [web.dev](https://web.dev/articles/defer-non-critical-css).
## Using Preprocessors
To use a preprocessor like SCSS, Sass, Less or Stylus, install it first.
```bash [Sass & SCSS]
npm install -D sass
```
```bash [Less]
npm install -D less
```
```bash [Stylus]
npm install -D stylus
```
The natural place to write your stylesheets is the `app/assets` directory.
You can then import your source files in your `app.vue` (or layouts files) using your preprocessor's syntax.
```vue [app/pages/app.vue]
```
Alternatively, you can use the `css` property of your Nuxt configuration.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
css: ['~/assets/scss/main.scss'],
})
```
In both cases, the compiled stylesheets will be inlined in the HTML rendered by Nuxt.
If you need to inject code in pre-processed files, like a [Sass partial](https://sass-lang.com/documentation/at-rules/use/#partials) with color variables, you can do so with the Vite [preprocessors options](https://vite.dev/config/shared-options#css-preprocessoroptions).
Create some partials in your `app/assets` directory:
```scss [assets/_colors.scss]
$primary: #49240F;
$secondary: #E4A79D;
```
```sass [assets/_colors.sass]
$primary: #49240F
$secondary: #E4A79D
```
Then in your `nuxt.config` :
```ts [SCSS]twoslash
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "~/assets/_colors.scss" as *;',
},
},
},
},
})
```
```ts [SASS]twoslash
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
sass: {
additionalData: '@use "~/assets/_colors.sass" as *\n',
},
},
},
},
})
```
Nuxt uses Vite by default. If you wish to use webpack instead, refer to each preprocessor loader [documentation](https://webpack.js.org/loaders/sass-loader/).
### Preprocessor Workers (Experimental)
Vite has made available an [experimental option](https://vite.dev/config/shared-options#css-preprocessormaxworkers) which can speed up using preprocessors.
You can enable this in your `nuxt.config`:
```ts
export default defineNuxtConfig({
vite: {
css: {
preprocessorMaxWorkers: true, // number of CPUs minus 1
},
},
})
```
This is an experimental option and you should refer to the Vite documentation and [provide feedback](https://github.com/vitejs/vite/discussions/15835).
## Single File Components (SFC) Styling
One of the best things about Vue and SFC is how great it is at naturally dealing with styling. You can directly write CSS or preprocessor code in the style block of your components file, therefore you will have fantastic developer experience without having to use something like CSS-in-JS. However if you wish to use CSS-in-JS, you can find 3rd party libraries and modules that support it, such as [pinceau](https://github.com/Tahul/pinceau).
You can refer to the [Vue docs](https://vuejs.org/api/sfc-css-features) for a comprehensive reference about styling components in SFC.
### Class And Style Bindings
You can leverage Vue SFC features to style your components with class and style attributes.
```vue [Ref and Reactive]
```
```vue [Computed]
```
```vue [Array]
```
```vue [Style]
```
Refer to the [Vue docs](https://vuejs.org/guide/essentials/class-and-style) for more information.
### Dynamic Styles With `v-bind`
You can reference JavaScript variable and expression within your style blocks with the v-bind function.
The binding will be dynamic, meaning that if the variable value changes, the style will be updated.
```vue
hello
```
### Scoped Styles
The scoped attribute allows you to style components in isolation. The styles declared with this attribute will only apply to this component.
```vue
hi
```
### CSS Modules
You can use [CSS Modules](https://github.com/css-modules/css-modules) with the module attribute. Access it with the injected `$style` variable.
```vue
This should be red
```
### Preprocessors Support
SFC style blocks support preprocessor syntax. Vite comes with built-in support for .scss, .sass, .less, .styl and .stylus files without configuration. You just need to install them first, and they will be available directly in SFC with the lang attribute.
```vue [SCSS]
```
```vue [Sass]
```
```vue [LESS]
```
```vue [Stylus]
```
You can refer to the [Vite CSS docs](https://vite.dev/guide/features#css) and the [@vitejs/plugin-vue docs](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue).
For webpack users, refer to the [vue loader docs](https://vue-loader.vuejs.org).
## Using PostCSS
Nuxt comes with postcss built-in. You can configure it in your `nuxt.config` file.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
postcss: {
plugins: {
'postcss-nested': {},
'postcss-custom-media': {},
},
},
})
```
For proper syntax highlighting in SFC, you can use the postcss lang attribute.
```vue
```
By default, Nuxt comes with the following plugins already pre-configured:
- [postcss-import](https://github.com/postcss/postcss-import): Improves the `@import` rule
- [postcss-url](https://github.com/postcss/postcss-url): Transforms `url()` statements
- [autoprefixer](https://github.com/postcss/autoprefixer): Automatically adds vendor prefixes
- [cssnano](https://cssnano.github.io/cssnano/): Minification and purge
## Leveraging Layouts For Multiple Styles
If you need to style different parts of your application completely differently, you can use layouts.
Use different styles for different layouts.
```vue
Default Layout
```
## Third Party Libraries And Modules
Nuxt isn't opinionated when it comes to styling and provides you with a wide variety of options. You can use any styling tool that you want, such as popular libraries like [UnoCSS](https://unocss.dev) or [Tailwind CSS](https://tailwindcss.com).
The community and the Nuxt team have developed plenty of Nuxt modules to make the integration easier.
You can discover them on the [modules section](/modules) of the website.
Here are a few modules to help you get started:
- [UnoCSS](/modules/unocss): Instant on-demand atomic CSS engine
- [Tailwind CSS](/modules/tailwindcss): Utility-first CSS framework
- [Fontaine](https://github.com/nuxt-modules/fontaine): Font metric fallback
- [Pinceau](https://github.com/Tahul/pinceau): Adaptable styling framework
- [Nuxt UI](https://ui.nuxt.com): A UI Library for Modern Web Apps
- [Panda CSS](https://panda-css.com/docs/installation/nuxt): CSS-in-JS engine that generates atomic CSS at build time
Nuxt modules provide you with a good developer experience out of the box, but remember that if your favorite tool doesn't have a module, it doesn't mean that you can't use it with Nuxt! You can configure it yourself for your own project. Depending on the tool, you might need to use a [Nuxt plugin](/docs/4.x/directory-structure/app/plugins) and/or [make your own module](/docs/4.x/guide/modules). Share them with the [community](/modules) if you do!
### Easily Load Webfonts
You can use [the Nuxt Google Fonts module](https://github.com/nuxt-modules/google-fonts) to load Google Fonts.
If you are using [UnoCSS](https://unocss.dev/integrations/nuxt), note that it comes with a [web fonts presets](https://unocss.dev/presets/web-fonts) to conveniently load fonts from common providers, including Google Fonts and more.
## Advanced
### Transitions
Nuxt comes with the same `` element that Vue has, and also has support for the experimental [View Transitions API](/docs/4.x/getting-started/transitions#view-transitions-api-experimental).
### Font Advanced Optimization
We would recommend using [Fontaine](https://github.com/nuxt-modules/fontaine) to reduce your [CLS](https://web.dev/articles/cls). If you need something more advanced, consider creating a Nuxt module to extend the build process or the Nuxt runtime.
Always remember to take advantage of the various tools and techniques available in the Web ecosystem at large to make styling your application easier and more efficient. Whether you're using native CSS, a preprocessor, postcss, a UI library or a module, Nuxt has got you covered. Happy styling!
### LCP Advanced Optimizations
You can do the following to speed-up the download of your global CSS files:
- Use a CDN so the files are physically closer to your users
- Compress your assets, ideally using Brotli
- Use HTTP2/HTTP3 for delivery
- Host your assets on the same domain (do not use a different subdomain)
Most of these things should be done for you automatically if you're using modern platforms like Cloudflare, Netlify or Vercel.
You can find an LCP optimization guide on [web.dev](https://web.dev/articles/optimize-lcp).
If all of your CSS is inlined by Nuxt, you can (experimentally) completely stop external CSS files from being referenced in your rendered HTML.
You can achieve that with a hook, that you can place in a module, or in your Nuxt configuration file.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
hooks: {
'build:manifest': (manifest) => {
// find the app entry, css list
const css = Object.values(manifest).find(options => options.isEntry)?.css
if (css) {
// start from the end of the array and go to the beginning
for (let i = css.length - 1; i >= 0; i--) {
// if it starts with 'entry', remove it from the list
if (css[i].startsWith('entry')) {
css.splice(i, 1)
}
}
}
},
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/teleport.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/teleport.md
# Teleport
> This example shows how to use the with client-side and server-side rendering.
Vue 3 provides the [`` component](https://vuejs.org/guide/built-ins/teleport.html) which allows content to be rendered elsewhere in the DOM, outside of the Vue application.
This example shows how to use the `` with client-side and server-side rendering.
---
# Source: https://nuxt.com/raw/docs/3.x/api/components/teleports.md
# Source: https://nuxt.com/raw/docs/4.x/api/components/teleports.md
#
> The component teleports a component to a different location in the DOM.
The `to` target of [``](https://vuejs.org/guide/built-ins/teleport) expects a CSS selector string or an actual DOM node. Nuxt currently has SSR support for teleports to `#teleports` only, with client-side support for other targets using a `` wrapper.
## Body Teleport
```vue
Hello from the modal!
```
## Client-side Teleport
```vue
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/kit/templates.md
# Source: https://nuxt.com/raw/docs/4.x/api/kit/templates.md
# Templates
> Nuxt Kit provides a set of utilities to help you work with templates. These functions allow you to generate extra files during development and build time.
Templates allow you to generate extra files during development and build time. These files will be available in virtual filesystem and can be used in plugins, layouts, components, etc. `addTemplate` and `addTypeTemplate` allow you to add templates to the Nuxt application. `updateTemplates` allows you to regenerate templates that match the filter.
## `addTemplate`
Renders given template during build into the virtual file system, and optionally to disk in the project `buildDir`
### Usage
```tstwoslash
import { addTemplate, defineNuxtModule } from '@nuxt/kit'
import { defu } from 'defu'
export default defineNuxtModule({
setup (options, nuxt) {
const globalMeta = defu(nuxt.options.app.head, {
charset: options.charset,
viewport: options.viewport,
})
addTemplate({
filename: 'meta.config.mjs',
getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: 'setup' }),
})
},
})
```
### Type
```tstwoslash
// @errors: 2391
import type { NuxtTemplate, ResolvedNuxtTemplate } from '@nuxt/schema'
// ---cut---
function addTemplate (template: NuxtTemplate | string): ResolvedNuxtTemplate
```
### Parameters
**template**: A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties:
Property
Type
Required
Description
src
string
false
Path to the template. If
src
is not provided,
getContents
must be provided instead.
filename
string
false
Filename of the template. If
filename
is not provided, it will be generated from the
src
path. In this case, the
src
option is required.
dst
string
false
Path to the destination file. If
dst
is not provided, it will be generated from the
filename
path and nuxt
buildDir
option.
options
Options
false
Options to pass to the template.
getContents
(
data
:
Options
)
=>
string
|
Promise
<
string
>
false
A function that will be called with the
options
object. It should return a string or a promise that resolves to a string. If
src
is provided, this function will be ignored.
write
boolean
false
If set to
true
, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem.
### Examples
#### Creating a Virtual File for Runtime Plugin
In this example, we merge an object inside a module and consume the result in a runtime plugin.
```ts [module.ts]twoslash
import { addTemplate, defineNuxtModule } from '@nuxt/kit'
import { defu } from 'defu'
export default defineNuxtModule({
setup (options, nuxt) {
const globalMeta = defu(nuxt.options.app.head, {
charset: options.charset,
viewport: options.viewport,
})
addTemplate({
filename: 'meta.config.mjs',
getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: 'setup' }),
})
},
})
```
In the module above, we generate a virtual file named `meta.config.mjs`. In the runtime plugin, we can import it using the `#build` alias:
```ts [runtime/plugin.ts]
import { createHead as createServerHead } from '@unhead/vue/server'
import { createHead as createClientHead } from '@unhead/vue/client'
import { defineNuxtPlugin } from '#imports'
// @ts-expect-error - virtual file
import metaConfig from '#build/meta.config.mjs'
export default defineNuxtPlugin((nuxtApp) => {
const createHead = import.meta.server ? createServerHead : createClientHead
const head = createHead()
head.push(metaConfig.globalMeta)
nuxtApp.vueApp.use(head)
})
```
## `addTypeTemplate`
Renders given template during build into the project buildDir, then registers it as types.
### Usage
```tstwoslash
import { addTypeTemplate, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
addTypeTemplate({
filename: 'types/markdown.d.ts',
getContents: () => `declare module '*.md' {
import type { ComponentOptions } from 'vue'
const Component: ComponentOptions
export default Component
}`,
})
},
})
```
### Type
```ts
function addTypeTemplate (template: NuxtTypeTemplate | string, context?: { nitro?: boolean, nuxt?: boolean }): ResolvedNuxtTemplate
```
### Parameters
**template**: A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties:
Property
Type
Required
Description
src
string
false
Path to the template. If
src
is not provided,
getContents
must be provided instead.
filename
string
false
Filename of the template. If
filename
is not provided, it will be generated from the
src
path. In this case, the
src
option is required.
dst
string
false
Path to the destination file. If
dst
is not provided, it will be generated from the
filename
path and nuxt
buildDir
option.
options
Options
false
Options to pass to the template.
getContents
(
data
:
Options
)
=>
string
|
Promise
<
string
>
false
A function that will be called with the
options
object. It should return a string or a promise that resolves to a string. If
src
is provided, this function will be ignored.
**context**: An optional context object can be passed to control where the type is added. If omitted, the type will only be added to the Nuxt context. This object supports the following properties:
Property
Type
Required
Description
nuxt
boolean
false
If set to
true
, the type will be added to the Nuxt context.
nitro
boolean
false
If set to
true
, the type will be added to the Nitro context.
### Examples
#### Adding Type Templates to the Nitro Context
By default, -- only adds the type declarations to the Nuxt context. To also add them to the Nitro context, set nitro to true.
```tstwoslash
import { addTypeTemplate, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
addTypeTemplate({
filename: 'types/auth.d.ts',
getContents: () => `declare module '#auth-utils' {
interface User {
id: string;
name: string;
}
}`,
}, {
nitro: true,
})
},
})
```
This allows the `#auth-utils` module to be used within the Nitro context.
```ts [server/api/auth.ts]
import type { User } from '#auth-utils'
export default eventHandler(() => {
const user: User = {
id: '123',
name: 'John Doe',
}
// do something with the user
return user
})
```
## `addServerTemplate`
Adds a virtual file that can be used within the Nuxt Nitro server build.
### Usage
```tstwoslash
import { addServerTemplate, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
addServerTemplate({
filename: '#my-module/test.mjs',
getContents () {
return 'export const test = 123'
},
})
},
})
```
### Type
```tstwoslash
// @errors: 2391
import type { NuxtServerTemplate } from '@nuxt/schema'
// ---cut---
function addServerTemplate (template: NuxtServerTemplate): NuxtServerTemplate
```
### Parameters
**template**: A template object. It must have the following properties:
Property
Type
Required
Description
filename
string
true
Filename of the template.
getContents
()
=>
string
|
Promise
<
string
>
true
A function that will be called with the
options
object. It should return a string or a promise that resolves to a string.
### Examples
### Creating a Virtual File for Nitro
In this example, we create a virtual file that can be used within the Nuxt Nitro server build.
```tstwoslash
import { addServerTemplate, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
addServerTemplate({
filename: '#my-module/test.mjs',
getContents () {
return 'export const test = 123'
},
})
},
})
```
And then in a runtime file
```ts [server/api/test.ts]
import { test } from '#my-module/test.js'
export default eventHandler(() => {
return test
})
```
## `updateTemplates`
Regenerate templates that match the filter. If no filter is provided, all templates will be regenerated.
### Usage
```ts
import { defineNuxtModule, updateTemplates } from '@nuxt/kit'
import { resolve } from 'pathe'
export default defineNuxtModule({
setup (options, nuxt) {
const updateTemplatePaths = [
resolve(nuxt.options.srcDir, 'pages'),
]
// watch and rebuild routes template list when one of the pages changes
nuxt.hook('builder:watch', async (event, relativePath) => {
if (event === 'change') {
return
}
const path = resolve(nuxt.options.srcDir, relativePath)
if (updateTemplatePaths.some(dir => path.startsWith(dir))) {
await updateTemplates({
filter: template => template.filename === 'routes.mjs',
})
}
})
},
})
```
### Type
```ts
async function updateTemplates (options: UpdateTemplatesOptions): void
```
### Parameters
**options**: Options to pass to the template. This object can have the following property:
Property
Type
Required
Description
filter
(
template
:
ResolvedNuxtTemplate
)
=>
boolean
false
A function that will be called with the
template
object. It should return a boolean indicating whether the template should be regenerated. If
filter
is not provided, all templates will be regenerated.
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/test.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/test.md
# nuxt test
> The test command runs tests using @nuxt/test-utils.
```bash [Terminal]
npx nuxt test [ROOTDIR] [--cwd=] [--logLevel=] [--dev] [--watch]
```
The `test` command runs tests using [`@nuxt/test-utils`](/docs/4.x/getting-started/testing). This command sets `process.env.NODE_ENV` to `test` if not already set.
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--dev
Run in dev mode
--watch
Watch mode
This command sets `process.env.NODE_ENV` to `test`.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/testing.md
# Source: https://nuxt.com/raw/docs/3.x/guide/modules/testing.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/testing.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/testing.md
# Source: https://nuxt.com/raw/docs/4.x/guide/modules/testing.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/testing.md
# Testing
> How to test your Nuxt application.
If you are a module author, you can find more specific information in the [Module Author's guide](/docs/4.x/guide/modules/testing).
Nuxt offers first-class support for end-to-end and unit testing of your Nuxt application via `@nuxt/test-utils`, a library of test utilities and configuration that currently powers the [tests we use on Nuxt itself](https://github.com/nuxt/nuxt/tree/main/test) and tests throughout the module ecosystem.
## Installation
In order to allow you to manage your other testing dependencies, `@nuxt/test-utils` ships with various optional peer dependencies. For example:
- you can choose between `happy-dom` and `jsdom` for a runtime Nuxt environment
- you can choose between `vitest`, `cucumber`, `jest` and `playwright` for end-to-end test runners
- `playwright-core` is only required if you wish to use the built-in browser testing utilities (and are not using `@playwright/test` as your test runner)
```bash [npm]
npm i --save-dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
```
```bash [yarn]
yarn add --dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
```
```bash [pnpm]
pnpm add -D @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
```
```bash [bun]
bun add --dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
```
## Unit Testing
We currently ship an environment for unit testing code that needs a [Nuxt](https://nuxt.com) runtime environment. It currently *only has support for vitest* (although contribution to add other runtimes would be welcome).
### Setup
1. Add `@nuxt/test-utils/module` to your `nuxt.config` file (optional). It adds a Vitest integration to your Nuxt DevTools which supports running your unit tests in development.```tstwoslash
export default defineNuxtConfig({
modules: [
'@nuxt/test-utils/module',
],
})
```
2. Create a `vitest.config.ts` with the following content:```tstwoslash
import { defineConfig } from 'vitest/config'
import { defineVitestProject } from '@nuxt/test-utils/config'
export default defineConfig({
test: {
projects: [
{
test: {
name: 'unit',
include: ['test/unit/*.{test,spec}.ts'],
environment: 'node',
},
},
{
test: {
name: 'e2e',
include: ['test/e2e/*.{test,spec}.ts'],
environment: 'node',
},
},
await defineVitestProject({
test: {
name: 'nuxt',
include: ['test/nuxt/*.{test,spec}.ts'],
environment: 'nuxt',
},
}),
],
},
})
```
When importing `@nuxt/test-utils` in your vitest config, It is necessary to have `"type": "module"` specified in your `package.json` or rename your vitest config file appropriately.
> i.e., `vitest.config.m{ts,js}`.
It is possible to set environment variables for testing by using the `.env.test` file.
### Using a Nuxt Runtime Environment
Using [Vitest projects](https://vitest.dev/guide/projects.html#test-projects), you have fine-grained control over which tests run in which environment:
- **Unit tests**: Place regular unit tests in `test/unit/` - these run in a Node environment for speed
- **Nuxt tests**: Place tests that rely on the Nuxt runtime environment in `test/nuxt/` - these will run within a Nuxt runtime environment
#### Alternative: Simple Setup
If you prefer a simpler setup and want all tests to run in the Nuxt environment, you can use the basic configuration:
```tstwoslash
import { defineVitestConfig } from '@nuxt/test-utils/config'
export default defineVitestConfig({
test: {
environment: 'nuxt',
// you can optionally set Nuxt-specific environment options
// environmentOptions: {
// nuxt: {
// rootDir: fileURLToPath(new URL('./playground', import.meta.url)),
// domEnvironment: 'happy-dom', // 'happy-dom' (default) or 'jsdom'
// overrides: {
// // other Nuxt config you want to pass
// }
// }
// }
},
})
```
If you're using the simple setup with `environment: 'nuxt'` by default, you can opt *out* of the [Nuxt environment](https://vitest.dev/guide/environment.html#test-environment) per test file as needed.
```tstwoslash
// @vitest-environment node
import { test } from 'vitest'
test('my test', () => {
// ... test without Nuxt environment!
})
```
This approach is not recommended as it creates a hybrid environment where Nuxt Vite plugins run but the Nuxt entry and `nuxtApp` are not initialized. This can lead to hard-to-debug errors.
### Organizing Your Tests
With the project-based setup, you might organize your tests as follows:
```bash [Directory structure]
test/
├── e2e/
│ └── ssr.test.ts
├── nuxt/
│ ├── components.test.ts
│ └── composables.test.ts
├── unit/
│ └── utils.test.ts
```
You can of course opt for any test structure, but keeping the Nuxt runtime environment separated from Nuxt end-to-end tests is important for test stability.
#### TypeScript Support in Tests
By default, test files in `test/nuxt/` and `tests/nuxt/` directories are included in the [Nuxt app TypeScript context](/docs/4.x/guide/concepts/typescript#how-nuxt-uses-project-references). That means they will recognise Nuxt aliases (like `~/`, `@/`, `#imports`) and TypeScript will be aware of auto-imports that work in your Nuxt app.
This matches the recommended structure where only tests that need the Nuxt runtime environment are placed in these directories. Unit tests in other directories like `test/unit/` can be added manually if needed.
##### Adding other test directories
If you have tests in other directories that you will be running in the Nuxt Vitest environment, you can include them in the Nuxt app TypeScript context by adding them to your configuration:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
typescript: {
tsConfig: {
include: [
// this path is relative to the generated .nuxt/tsconfig.json
'../test/other-nuxt-context/**/*',
],
},
},
})
```
Unit tests should not depend on Nuxt runtime features like auto-imports or composables. Only add TypeScript path alias support if your tests import from your source files (e.g., `~/utils/helpers`), not for Nuxt-specific features.
#### Running Tests
With the project setup, you can run different test suites:
```bash
# Run all tests
npx vitest
# Run only unit tests
npx vitest --project unit
# Run only Nuxt tests
npx vitest --project nuxt
# Run tests in watch mode
npx vitest --watch
```
When you run your tests within the Nuxt environment, they will be running in a [`happy-dom`](https://github.com/capricorn86/happy-dom) or [`jsdom`](https://github.com/jsdom/jsdom) environment. Before your tests run, a global Nuxt app will be initialized (including, for example, running any plugins or code you've defined in your `app.vue`).
This means you should take particular care not to mutate the global state in your tests (or, if you need to, to reset it afterwards).
### 🎭 Built-In Mocks
`@nuxt/test-utils` provides some built-in mocks for the DOM environment.
#### `intersectionObserver`
Default `true`, creates a dummy class without any functionality for the IntersectionObserver API
#### `indexedDB`
Default `false`, uses [`fake-indexeddb`](https://github.com/dumbmatter/fakeIndexedDB) to create a functional mock of the IndexedDB API
These can be configured in the `environmentOptions` section of your `vitest.config.ts` file:
```tstwoslash
import { defineVitestConfig } from '@nuxt/test-utils/config'
export default defineVitestConfig({
test: {
environmentOptions: {
nuxt: {
mock: {
intersectionObserver: true,
indexedDb: true,
},
},
},
},
})
```
### 🛠️ Helpers
`@nuxt/test-utils` provides a number of helpers to make testing Nuxt apps easier.
#### `mountSuspended`
`mountSuspended` allows you to mount any Vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins.
Under the hood, `mountSuspended` wraps `mount` from `@vue/test-utils`, so you can check out [the Vue Test Utils documentation](https://test-utils.vuejs.org/guide/) for more on the options you can pass, and how to use this utility.
For example:
```tstwoslash
// @noErrors
import { expect, it } from 'vitest'
import type { Component } from 'vue'
declare module '#components' {
export const SomeComponent: Component
}
// ---cut---
// tests/components/SomeComponents.nuxt.spec.ts
import { mountSuspended } from '@nuxt/test-utils/runtime'
import { SomeComponent } from '#components'
it('can mount some component', async () => {
const component = await mountSuspended(SomeComponent)
expect(component.text()).toMatchInlineSnapshot(
'"This is an auto-imported component"',
)
})
```
```tstwoslash
// @noErrors
import { expect, it } from 'vitest'
// ---cut---
// tests/components/SomeComponents.nuxt.spec.ts
import { mountSuspended } from '@nuxt/test-utils/runtime'
import App from '~/app.vue'
// tests/App.nuxt.spec.ts
it('can also mount an app', async () => {
const component = await mountSuspended(App, { route: '/test' })
expect(component.html()).toMatchInlineSnapshot(`
"
This is an auto-imported component
I am a global component
/
Test link "
`)
})
```
#### `renderSuspended`
`renderSuspended` allows you to render any Vue component within the Nuxt environment using `@testing-library/vue`, allowing async setup and access to injections from your Nuxt plugins.
This should be used together with utilities from Testing Library, e.g. `screen` and `fireEvent`. Install [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro/) in your project to use these.
Additionally, Testing Library also relies on testing globals for cleanup. You should turn these on in your [Vitest config](https://vitest.dev/config/globals).
The passed in component will be rendered inside a ``.
Examples:
```tstwoslash
// @noErrors
import { expect, it } from 'vitest'
import type { Component } from 'vue'
declare module '#components' {
export const SomeComponent: Component
}
// ---cut---
// tests/components/SomeComponents.nuxt.spec.ts
import { renderSuspended } from '@nuxt/test-utils/runtime'
import { SomeComponent } from '#components'
import { screen } from '@testing-library/vue'
it('can render some component', async () => {
await renderSuspended(SomeComponent)
expect(screen.getByText('This is an auto-imported component')).toBeDefined()
})
```
```tstwoslash
// @noErrors
import { expect, it } from 'vitest'
// ---cut---
// tests/App.nuxt.spec.ts
import { renderSuspended } from '@nuxt/test-utils/runtime'
import App from '~/app.vue'
it('can also render an app', async () => {
const html = await renderSuspended(App, { route: '/test' })
expect(html).toMatchInlineSnapshot(`
"
"
`)
})
```
#### `mockNuxtImport`
`mockNuxtImport` allows you to mock Nuxt's auto import functionality. For example, to mock `useStorage`, you can do so like this:
```tstwoslash
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
mockNuxtImport('useStorage', () => {
return () => {
return { value: 'mocked storage' }
}
})
// your tests here
```
`mockNuxtImport` can only be used once per mocked import per test file. It is actually a macro that gets transformed to `vi.mock` and `vi.mock` is hoisted, as described [in the Vitest docs](https://vitest.dev/api/vi#vi-mock).
If you need to mock a Nuxt import and provide different implementations between tests, you can do it by creating and exposing your mocks using [`vi.hoisted`](https://vitest.dev/api/vi#vi-hoisted), and then use those mocks in `mockNuxtImport`. You then have access to the mocked imports, and can change the implementation between tests. Be careful to [restore mocks](https://vitest.dev/api/mock#mockrestore) before or after each test to undo mock state changes between runs.
```tstwoslash
import { vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
const { useStorageMock } = vi.hoisted(() => {
return {
useStorageMock: vi.fn(() => {
return { value: 'mocked storage' }
}),
}
})
mockNuxtImport('useStorage', () => {
return useStorageMock
})
// Then, inside a test
useStorageMock.mockImplementation(() => {
return { value: 'something else' }
})
```
#### `mockComponent`
`mockComponent` allows you to mock Nuxt's component.
The first argument can be the component name in PascalCase, or the relative path of the component.
The second argument is a factory function that returns the mocked component.
For example, to mock `MyComponent`, you can:
```tstwoslash
import { mockComponent } from '@nuxt/test-utils/runtime'
mockComponent('MyComponent', {
props: {
value: String,
},
setup (props) {
// ...
},
})
// relative path or alias also works
mockComponent('~/components/my-component.vue', () => {
// or a factory function
return defineComponent({
setup (props) {
// ...
},
})
})
// or you can use SFC for redirecting to a mock component
mockComponent('MyComponent', () => import('./MockComponent.vue'))
// your tests here
```
> **Note**: You can't reference local variables in the factory function since they are hoisted. If you need to access Vue APIs or other variables, you need to import them in your factory function.
```tstwoslash
import { mockComponent } from '@nuxt/test-utils/runtime'
mockComponent('MyComponent', async () => {
const { ref, h } = await import('vue')
return defineComponent({
setup (props) {
const counter = ref(0)
return () => h('div', null, counter.value)
},
})
})
```
#### `registerEndpoint`
`registerEndpoint` allows you create Nitro endpoint that returns mocked data. It can come in handy if you want to test a component that makes requests to API to display some data.
The first argument is the endpoint name (e.g. `/test/`).
The second argument is a factory function that returns the mocked data.
For example, to mock `/test/` endpoint, you can do:
```tstwoslash
import { registerEndpoint } from '@nuxt/test-utils/runtime'
registerEndpoint('/test/', () => ({
test: 'test-field',
}))
```
By default, your request will be made using the `GET` method. You may use another method by setting an object as the second argument instead of a function.
```tstwoslash
import { registerEndpoint } from '@nuxt/test-utils/runtime'
registerEndpoint('/test/', {
method: 'POST',
handler: () => ({ test: 'test-field' }),
})
```
> **Note**: If your requests in a component go to an external API, you can use `baseURL` and then make it empty using [Nuxt Environment Override Config](/docs/4.x/getting-started/configuration#environment-overrides) (`$test`) so all your requests will go to Nitro server.
#### Conflict with End-To-End Testing
`@nuxt/test-utils/runtime` and `@nuxt/test-utils/e2e` need to run in different testing environments and so can't be used in the same file.
If you would like to use both the end-to-end and unit testing functionality of `@nuxt/test-utils`, you can split your tests into separate files. You then either specify a test environment per-file with the special `// @vitest-environment nuxt` comment, or name your runtime unit test files with the `.nuxt.spec.ts` extension.
`app.nuxt.spec.ts`
```tstwoslash
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
mockNuxtImport('useStorage', () => {
return () => {
return { value: 'mocked storage' }
}
})
```
`app.e2e.spec.ts`
```tstwoslash
import { $fetch, setup } from '@nuxt/test-utils/e2e'
await setup({
setupTimeout: 10000,
})
// ...
```
### Using `@vue/test-utils`
If you prefer to use `@vue/test-utils` on its own for unit testing in Nuxt, and you are only testing components which do not rely on Nuxt composables, auto-imports or context, you can follow these steps to set it up.
1. Install the needed dependencies
```bash [npm]
npm i --save-dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
```
```bash [yarn]
yarn add --dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
```
```bash [pnpm]
pnpm add -D vitest @vue/test-utils happy-dom @vitejs/plugin-vue
```
```bash [bun]
bun add --dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
```
2. Create a `vitest.config.ts` with the following content:```ts
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
test: {
environment: 'happy-dom',
},
})
```
3. Add a new command for test in your `package.json````json
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
...
"test": "vitest"
},
```
4. Create a simple `` component `app/components/HelloWorld.vue` with the following content:```vue
Hello world
```
5. Create a simple unit test for this newly created component `~/components/HelloWorld.spec.ts````tstwoslash
import { describe, expect, it } from 'vitest'
import { mount } from '@vue/test-utils'
import HelloWorld from './HelloWorld.vue'
describe('HelloWorld', () => {
it('component renders Hello world properly', () => {
const wrapper = mount(HelloWorld)
expect(wrapper.text()).toContain('Hello world')
})
})
```
6. Run vitest command
```bash [npm]
npm run test
```
```bash [yarn]
yarn test
```
```bash [pnpm]
pnpm run test
```
```bash [bun]
bun run test
```
Congratulations, you're all set to start unit testing with `@vue/test-utils` in Nuxt! Happy testing!
## End-To-End Testing
For end-to-end testing, we support [Vitest](https://github.com/vitest-dev/vitest), [Jest](https://jestjs.io), [Cucumber](https://cucumber.io/) and [Playwright](https://playwright.dev/) as test runners.
### Setup
In each `describe` block where you are taking advantage of the `@nuxt/test-utils/e2e` helper methods, you will need to set up the test context before beginning.
```ts [test/my-test.spec.ts]twoslash
import { describe, test } from 'vitest'
import { $fetch, setup } from '@nuxt/test-utils/e2e'
describe('My test', async () => {
await setup({
// test context options
})
test('my test', () => {
// ...
})
})
```
Behind the scenes, `setup` performs a number of tasks in `beforeAll`, `beforeEach`, `afterEach` and `afterAll` to set up the Nuxt test environment correctly.
Please use the options below for the `setup` method.
#### Nuxt Config
- `rootDir`: Path to a directory with a Nuxt app to be put under test.
- Type: `string`
- Default: `'.'`
- `configFile`: Name of the configuration file.
- Type: `string`
- Default: `'nuxt.config'`
#### Timings
- `setupTimeout`: The amount of time (in milliseconds) to allow for `setupTest` to complete its work (which could include building or generating files for a Nuxt application, depending on the options that are passed).
- Type: `number`
- Default: `120000` or `240000` on windows
- `teardownTimeout`: The amount of time (in milliseconds) to allow tearing down the test environment, such as closing the browser.
- Type: `number`
- Default: `30000`
#### Features
- `build`: Whether to run a separate build step.
- Type: `boolean`
- Default: `true` (`false` if `browser` or `server` is disabled, or if a `host` is provided)
- `server`: Whether to launch a server to respond to requests in the test suite.
- Type: `boolean`
- Default: `true` (`false` if a `host` is provided)
- `port`: If provided, set the launched test server port to the value.
- Type: `number | undefined`
- Default: `undefined`
- `host`: If provided, a URL to use as the test target instead of building and running a new server. Useful for running "real" end-to-end tests against a deployed version of your application, or against an already running local server (which may provide a significant reduction in test execution timings). See the [target host end-to-end example below](/docs/4.x/getting-started/testing#target-host-end-to-end-example).
- Type: `string`
- Default: `undefined`
- `browser`: Under the hood, Nuxt test utils uses [`playwright`](https://playwright.dev) to carry out browser testing. If this option is set, a browser will be launched and can be controlled in the subsequent test suite.
- Type: `boolean`
- Default: `false`
- `browserOptions`
- Type: `object` with the following properties
- `type`: The type of browser to launch - either `chromium`, `firefox` or `webkit`
- `launch`: `object` of options that will be passed to playwright when launching the browser. See [full API reference](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
- `runner`: Specify the runner for the test suite. Currently, [Vitest](https://vitest.dev) is recommended.
- Type: `'vitest' | 'jest' | 'cucumber'`
- Default: `'vitest'`
##### Target `host` end-to-end example
A common use-case for end-to-end testing is running the tests against a deployed application running in the same environment typically used for Production.
For local development or automated deploy pipelines, testing against a separate local server can be more efficient and is typically faster than allowing the test framework to rebuild between tests.
To utilize a separate target host for end-to-end tests, simply provide the `host` property of the `setup` function with the desired URL.
```ts
import { createPage, setup } from '@nuxt/test-utils/e2e'
import { describe, expect, it } from 'vitest'
describe('login page', async () => {
await setup({
host: 'http://localhost:8787',
})
it('displays the email and password fields', async () => {
const page = await createPage('/login')
expect(await page.getByTestId('email').isVisible()).toBe(true)
expect(await page.getByTestId('password').isVisible()).toBe(true)
})
})
```
### APIs
#### `$fetch(url)`
Get the HTML of a server-rendered page.
```tstwoslash
import { $fetch } from '@nuxt/test-utils/e2e'
const html = await $fetch('/')
```
#### `fetch(url)`
Get the response of a server-rendered page.
```tstwoslash
import { fetch } from '@nuxt/test-utils/e2e'
const res = await fetch('/')
const { body, headers } = res
```
#### `url(path)`
Get the full URL for a given page (including the port the test server is running on.)
```tstwoslash
import { url } from '@nuxt/test-utils/e2e'
const pageUrl = url('/page')
// 'http://localhost:6840/page'
```
### Testing in a Browser
We provide built-in support using Playwright within `@nuxt/test-utils`, either programmatically or via the Playwright test runner.
#### `createPage(url)`
Within `vitest`, `jest` or `cucumber`, you can create a configured Playwright browser instance with `createPage`, and (optionally) point it at a path from the running server. You can find out more about the API methods available from [in the Playwright documentation](https://playwright.dev/docs/api/class-page).
```tstwoslash
import { createPage } from '@nuxt/test-utils/e2e'
const page = await createPage('/page')
// you can access all the Playwright APIs from the `page` variable
```
#### Testing with Playwright Test Runner
We also provide first-class support for testing Nuxt within [the Playwright test runner](https://playwright.dev/docs/intro).
```bash [npm]
npm i --save-dev @playwright/test @nuxt/test-utils
```
```bash [yarn]
yarn add --dev @playwright/test @nuxt/test-utils
```
```bash [pnpm]
pnpm add -D @playwright/test @nuxt/test-utils
```
```bash [bun]
bun add --dev @playwright/test @nuxt/test-utils
```
```bash [deno]
deno add --dev npm:@playwright/test npm:@nuxt/test-utils
```
You can provide global Nuxt configuration, with the same configuration details as the `setup()` function mentioned earlier in this section.
```ts [playwright.config.ts]
import { fileURLToPath } from 'node:url'
import { defineConfig, devices } from '@playwright/test'
import type { ConfigOptions } from '@nuxt/test-utils/playwright'
export default defineConfig({
use: {
nuxt: {
rootDir: fileURLToPath(new URL('.', import.meta.url)),
},
},
// ...
})
```
Your test file should then use `expect` and `test` directly from `@nuxt/test-utils/playwright`:
```ts [tests/example.test.ts]
import { expect, test } from '@nuxt/test-utils/playwright'
test('test', async ({ page, goto }) => {
await goto('/', { waitUntil: 'hydration' })
await expect(page.getByRole('heading')).toHaveText('Welcome to Playwright!')
})
```
You can alternatively configure your Nuxt server directly within your test file:
```ts [tests/example.test.ts]
import { expect, test } from '@nuxt/test-utils/playwright'
test.use({
nuxt: {
rootDir: fileURLToPath(new URL('..', import.meta.url)),
},
})
test('test', async ({ page, goto }) => {
await goto('/', { waitUntil: 'hydration' })
await expect(page.getByRole('heading')).toHaveText('Welcome to Playwright!')
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/getting-started/transitions.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/transitions.md
# Transitions
> Apply transitions between pages and layouts with Vue or native browser View Transitions.
Nuxt leverages Vue's [``](https://vuejs.org/guide/built-ins/transition#the-transition-component) component to apply transitions between pages and layouts.
## Page Transitions
You can enable page transitions to apply an automatic transition for all your [pages](/docs/4.x/directory-structure/app/pages).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
app: {
pageTransition: { name: 'page', mode: 'out-in' },
},
})
```
If you are changing layouts as well as page, the page transition you set here will not run. Instead, you should set a [layout transition](/docs/4.x/getting-started/transitions#layout-transitions).
To start adding transition between your pages, add the following CSS to your [`app.vue`](/docs/4.x/directory-structure/app/app):
```vue [app/app.vue]
```
```vue [app/pages/index.vue]
Home page
About page
```
```vue [app/pages/about.vue]
About page
Home page
```
This produces the following result when navigating between pages:
To set a different transition for a page, set the `pageTransition` key in [`definePageMeta`](/docs/4.x/api/utils/define-page-meta) of the page:
```vue [pages/about.vue]twoslash
```
```vue [app/app.vue]
```
Moving to the about page will add the 3d rotation effect:
## Layout Transitions
You can enable layout transitions to apply an automatic transition for all your [layouts](/docs/4.x/directory-structure/app/layouts).
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
app: {
layoutTransition: { name: 'layout', mode: 'out-in' },
},
})
```
To start adding transition between your pages and layouts, add the following CSS to your [`app.vue`](/docs/4.x/directory-structure/app/app):
```vue [app/app.vue]
```
```vue [app/layouts/default.vue]
default layout
```
```vue [app/layouts/orange.vue]
orange layout
```
```vue [app/pages/index.vue]
Home page
About page
```
```vue [app/pages/about.vue]
About page
Home page
```
This produces the following result when navigating between pages:
Similar to `pageTransition`, you can apply a custom `layoutTransition` to the page component using `definePageMeta`:
```vue [pages/about.vue]twoslash
```
## Global Settings
You can customize these default transition names globally using `nuxt.config`.
Both `pageTransition` and `layoutTransition` keys accept [`TransitionProps`](https://vuejs.org/api/built-in-components#transition) as JSON serializable values where you can pass the `name`, `mode` and other valid transition-props of the custom CSS transition.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
app: {
pageTransition: {
name: 'fade',
mode: 'out-in', // default
},
layoutTransition: {
name: 'slide',
mode: 'out-in', // default
},
},
})
```
If you change the `name` property, you also have to rename the CSS classes accordingly.
To override the global transition property, use the `definePageMeta` to define page or layout transitions for a single Nuxt page and override any page or layout transitions that are defined globally in `nuxt.config` file.
```vue [pages/some-page.vue]twoslash
```
## Disable Transitions
`pageTransition` and `layoutTransition` can be disabled for a specific route:
```vue [pages/some-page.vue]twoslash
```
Or globally in the `nuxt.config`:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
app: {
pageTransition: false,
layoutTransition: false,
},
})
```
## JavaScript Hooks
For advanced use-cases, you can use JavaScript hooks to create highly dynamic and custom transitions for your Nuxt pages.
This way presents perfect use-cases for JavaScript animation libraries such as [GSAP](https://gsap.com).
```vue [pages/some-page.vue]twoslash
```
Learn more about additional [JavaScript hooks](https://vuejs.org/guide/built-ins/transition#javascript-hooks) available in the `Transition` component.
## Dynamic Transitions
To apply dynamic transitions using conditional logic, you can leverage inline [middleware](/docs/4.x/directory-structure/app/middleware) to assign a different transition name to `to.meta.pageTransition`.
```vue [pages/[id].vue]twoslash
#{{ $route.params.id }}
```
```vue [app/layouts/default.vue]
⬅️ |
➡️
```
The page now applies the `slide-left` transition when going to the next id and `slide-right` for the previous:
## Transition with NuxtPage
When `` is used in `app.vue`, transitions can be configured with the `transition` prop to activate transitions globally.
```vue [app/app.vue]
```
Remember, this page transition cannot be overridden with `definePageMeta` on individual pages.
## View Transitions API (experimental)
Nuxt ships with an experimental implementation of the [**View Transitions API**](https://developer.chrome.com/docs/web-platform/view-transitions) (see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API)). This is an exciting new way to implement native browser transitions which (among other things) have the ability to transition between unrelated elements on different pages.
You can check a demo [on StackBlitz](https://stackblitz.com/edit/nuxt-view-transitions).
The Nuxt integration can be enabled with the `experimental.viewTransition` option in your configuration file:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
viewTransition: true,
},
})
```
The possible values are: `false`, `true`, or `'always'`.
If set to true, Nuxt will not apply transitions if the user's browser matches `prefers-reduced-motion: reduce` (recommended). If set to `always`, Nuxt will always apply the transition and it is up to you to respect the user's preference.
By default, view transitions are enabled for all [pages](/docs/4.x/directory-structure/app/pages), but you can set a different global default.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
app: {
// Disable view transitions globally, and opt-in on a per page basis
viewTransition: false,
},
})
```
It is possible to override the default `viewTransition` value for a page by setting the `viewTransition` key in [`definePageMeta`](/docs/4.x/api/utils/define-page-meta) of the page:
```vue [pages/about.vue]twoslash
```
Overriding view transitions on a per-page basis will only have an effect if you have enabled the `experimental.viewTransition` option.
If you are also using Vue transitions like `pageTransition` and `layoutTransition` (see above) to achieve the same result as the new View Transitions API, then you may wish to *disable* Vue transitions if the user's browser supports the newer, native web API. You can do this by creating `~/middleware/disable-vue-transitions.global.ts` with the following contents:
```ts
export default defineNuxtRouteMiddleware((to) => {
if (import.meta.server || !document.startViewTransition) {
return
}
// Disable built-in Vue transitions
to.meta.pageTransition = false
to.meta.layoutTransition = false
})
```
### Known Issues
- If you perform data fetching within your page setup functions, you may wish to reconsider using this feature for the moment. (By design, View Transitions completely freeze DOM updates whilst they are taking place.) We're looking at restricting the View Transition to the final moments before `` resolves, but in the interim you may want to consider carefully whether to adopt this feature if this describes you.
---
# Source: https://nuxt.com/raw/docs/3.x/directory-structure/tsconfig.md
# Source: https://nuxt.com/raw/docs/4.x/directory-structure/tsconfig.md
# tsconfig.json
> Learn how Nuxt manages TypeScript configuration across different parts of your project.
Nuxt [automatically generates](/docs/4.x/guide/concepts/typescript#auto-generated-types) multiple TypeScript configuration files (`.nuxt/tsconfig.app.json`, `.nuxt/tsconfig.server.json`, `.nuxt/tsconfig.node.json` and `.nuxt/tsconfig.shared.json`) that include recommended basic TypeScript configuration for your project, references to [auto-imports](/docs/4.x/guide/concepts/auto-imports), [API route types](/docs/4.x/guide/concepts/server-engine#typed-api-routes), path aliases, and more.
Your Nuxt project should include the following `tsconfig.json` file at the root of the project:
```json [tsconfig.json]
{
"files": [],
"references": [
{
"path": "./.nuxt/tsconfig.app.json"
},
{
"path": "./.nuxt/tsconfig.server.json"
},
{
"path": "./.nuxt/tsconfig.shared.json"
},
{
"path": "./.nuxt/tsconfig.node.json"
}
]
}
```
We do not recommend modifying the contents of this file directly, as doing so could overwrite important settings that Nuxt or other modules rely on. Instead, extend it via `nuxt.config.ts`.
Read more about the different type contexts of a Nuxt project here.
## Extending TypeScript Configuration
You can customize the TypeScript configuration of your Nuxt project for each context (`app`, `shared`, `node`, and `server`) in the `nuxt.config.ts` file.
```ts [nuxt.config.ts]twoslash
// @errors: 2353
export default defineNuxtConfig({
typescript: {
// customize tsconfig.app.json
tsConfig: {
// ...
},
// customize tsconfig.shared.json
sharedTsConfig: {
// ...
},
// customize tsconfig.node.json
nodeTsConfig: {
// ...
},
},
nitro: {
typescript: {
// customize tsconfig.server.json
tsConfig: {
// ...
},
},
},
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/typecheck.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/typecheck.md
# nuxt typecheck
> The typecheck command runs vue-tsc to check types throughout your app.
```bash [Terminal]
npx nuxt typecheck [ROOTDIR] [--cwd=] [--logLevel=] [--dotenv] [-e, --extends=]
```
The `typecheck` command runs [`vue-tsc`](https://github.com/vuejs/language-tools/tree/master/packages/tsc) to check types throughout your app.
## Arguments
Argument
Description
ROOTDIR="."
Specifies the working directory (default:
.
)
## Options
Option
Default
Description
--cwd=
Specify the working directory, this takes precedence over ROOTDIR (default:
.
)
--logLevel=
Specify build-time log level
--dotenv
Path to
.env
file to load, relative to the root directory
-e, --extends=
Extend from a Nuxt layer
This command sets `process.env.NODE_ENV` to `production`. To override, define `NODE_ENV` in a [`.env`](/docs/4.x/directory-structure/env) file or as a command-line argument.
Read more on how to enable type-checking at build or development time.
---
# Source: https://nuxt.com/raw/docs/3.x/bridge/typescript.md
# Source: https://nuxt.com/raw/docs/3.x/guide/concepts/typescript.md
# Source: https://nuxt.com/raw/docs/4.x/bridge/typescript.md
# Source: https://nuxt.com/raw/docs/4.x/guide/concepts/typescript.md
# TypeScript
> Nuxt is fully typed and provides helpful shortcuts to ensure you have access to accurate type information when you are coding.
## Type-checking
By default, Nuxt doesn't check types when you run [`nuxt dev`](/docs/4.x/api/commands/dev) or [`nuxt build`](/docs/4.x/api/commands/build), for performance reasons.
To enable type-checking at build or development time, install `vue-tsc` and `typescript` as development dependency:
```bash [npm]
npm install --save-dev vue-tsc typescript
```
```bash [yarn]
yarn add --dev vue-tsc typescript
```
```bash [pnpm]
pnpm add -D vue-tsc typescript
```
```bash [bun]
bun add -D vue-tsc typescript
```
```bash [deno]
deno add -D npm:vue-tsc npm:typescript
```
Then, run [`nuxt typecheck`](/docs/4.x/api/commands/typecheck) command to check your types:
```bash [Terminal]
npx nuxt typecheck
```
To enable type-checking at build or development time, you can also use the [`typescript.typeCheck`](/docs/4.x/api/nuxt-config#typecheck) option in your `nuxt.config` file:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
typescript: {
typeCheck: true,
},
})
```
## Auto-generated Types
Nuxt projects rely on auto-generated types to work properly. These types are stored in the [`.nuxt`](/docs/4.x/directory-structure/nuxt) directory and are generated when you run the dev server or build your application. You can also generate these files manually by running `nuxt prepare`.
The generated `tsconfig.json` files inside the [`.nuxt`](/docs/4.x/directory-structure/nuxt) directory include **recommended basic TypeScript configuration** for your project, references to [auto-imports](/docs/4.x/guide/concepts/auto-imports), [API route types](/docs/4.x/guide/concepts/server-engine#typed-api-routes), path aliases like `#imports`, `~/file`, or `#build/file`, and more.
Nuxt relies on this configuration, and [Nuxt modules](/docs/4.x/guide/modules) can extend it as well. For this reason, it is not recommended to modify your `tsconfig.json` file directly, as doing so could overwrite important settings. Instead, extend it via `nuxt.config.ts`. [Learn more about extending the configuration here](/docs/4.x/directory-structure/tsconfig).
Watch a video from Daniel Roe explaining built-in Nuxt aliases.
## Project References
Nuxt uses [TypeScript project references](https://www.typescriptlang.org/docs/handbook/project-references.html) to improve type-checking performance and provide better IDE support. This feature allows TypeScript to break up your codebase into smaller, more manageable pieces.
### How Nuxt Uses Project References
When you run `nuxt dev`, `nuxt build` or `nuxt prepare`, Nuxt will generate multiple `tsconfig.json` files for different parts of your application.
- **.nuxt/tsconfig.app.json** - Configuration for your application code within the `app/` directory
- **.nuxt/tsconfig.node.json** - Configuration for your `nuxt.config.ts` and files outside the other contexts
- **.nuxt/tsconfig.server.json** - Configuration for server-side code (when applicable)
- **.nuxt/tsconfig.shared.json** - For code shared between app and server contexts (like types and non-environment specific utilities)
Each of these files is configured to reference the appropriate dependencies and provide optimal type-checking for their specific context.
For backward compatibility, Nuxt still generates `.nuxt/tsconfig.json`. However, we recommend using [TypeScript project references](/docs/4.x/directory-structure/tsconfig) with the new configuration files (`.nuxt/tsconfig.app.json`, `.nuxt/tsconfig.server.json`, etc.) for better type safety and performance. This legacy file will be removed in a future version of Nuxt.
### Benefits of Project References
- **Faster builds**: TypeScript can skip rebuilding unchanged projects
- **Better IDE performance**: Your IDE can provide faster IntelliSense and error checking
- **Isolated compilation**: Errors in one part of your application don't prevent compilation of other parts
- **Clearer dependency management**: Each project explicitly declares its dependencies
### Augmenting Types with Project References
Since the project is divided into **multiple type contexts**, it's important to **augment types within the correct context** to ensure they're properly recognized. TypeScript will not recognize augmentations placed outside these directories unless they are explicitly included in the appropriate context.
For example, if you want to augment types for the `app` context, the augmentation file should be placed in the `app/` directory.
Similarly:
- For the `server` context, place the augmentation file in the `server/` directory.
- For types that are **shared between the app and server**, place the file in the `shared/` directory.
Read more about augmenting specific type contexts from **files outside those contexts** in the Module Author Guide.
## Strict Checks
TypeScript comes with certain checks to give you more safety and analysis of your program.
[Strict checks](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks) are enabled by default in Nuxt when the [`typescript.typeCheck`](/docs/4.x/guide/concepts/typescript#type-checking) option is enabled to give you greater type safety.
If you are currently converting your codebase to TypeScript, you may want to temporarily disable strict checks by setting `strict` to `false` in your `nuxt.config`:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
typescript: {
strict: false,
},
})
```
---
# Source: https://nuxt.com/raw/blog/understanding-how-fetch-works-in-nuxt-2-12.md
# Understanding how fetch works in Nuxt 2.12
> Explore different features of the fetch hook and learn a brand new way to bring data into Nuxt applications.
Nuxt introduces a new `fetch` with the latest release of version 2.12. Fetch provides a brand new way to bring data into Nuxt applications.
In this post, we will explore different features of the fetch hook and try to understand how it works.
## Fetch Hook and Nuxt Lifecycle
In terms of Nuxt lifecycle hooks, `fetch` sits within Vue lifecycle after `created` hook. As we already know that, all Vue lifecycle hooks are called with their `this` context. The same applies to `fetch` hook as well.

Fetch hook is called after the component instance is created on the server-side. That makes `this` context available inside the `fetch`.
```js
export default {
fetch() {
console.log(this)
}
}
```
Let’s see what this could mean for page components.
### Page Components
With the help of `this` context, fetch is able to mutate component’s data directly. It means we can set the component’s local data without having to dispatch Vuex store action or committing mutation from the page component.
As a result, Vuex becomes optional, but not impossible. We can still use `this.$store` as usual to access Vuex store if required.
## Availability of fetch hook
With `fetch`, we can prefetch the data asynchronously **in any Vue components**. It means, other than page components found in `/pages` directory, every other `.vue` components found in `/layouts` and `/components` directories can also benefit from the fetch hook.
Let's see what this could mean for layout and building-block components.
### Layout Components
Using new `fetch`, now we can make API calls directly from the layout components. This was impossible prior to the release of v2.12.
**Possible use cases**
- Fetch config data from the back-end in Nuxt layouts to generate footer and navbar dynamically
- Fetch user related data (i.e. user profile, shopping-cart item count) in the navbar
- Fetch site relevant data on `layouts/error.vue`
### Building-block (Child/Nested) Components
With `fetch` hook available in child components as well, we can off-load some of the data-fetching tasks from page-level components, and delegate them over to nested components. This was also impossible prior to the release of v2.12.
This reduces the responsibility of route-level components to a great extent.
**Possible use case -** We can still pass props to child components, but if the child components need to have their own data-fetching logic, now they can!
## Call order of multiple fetch hooks
Since each component can have its own data-fetching logic, you may ask what would be the order in which each of them are called?
Fetch hook is called on server-side once (on the first request to the Nuxt app) and then on client-side when navigating to further routes. But since we can define one fetch hook for each component, fetch hooks are called in sequence of their hierarchy.
### Disabling fetch on server-side
In addition, we can even disable fetch on the server-side if required.
```js
export default {
fetchOnServer: false
}
```
And this way, the fetch hook will only be called on client-side. When `fetchOnServer` is set to false, `$fetchState.pending` becomes `true` when the component is rendered on server-side.
## Error Handling
New `fetch` handles error at component level. Let’s see how.
Because we’re fetching data asynchronously, the new fetch() provides a `$fetchState` object to check whether the request has finished and progressed successfully.
Below is what the `$fetchState` object looks like.
```text
$fetchState = {
pending: true | false,
error: null | {},
timestamp: Integer
};
```
We have three keys,
1. **Pending -** lets you display a placeholder when fetch is being called on client-side
2. **Error -** lets you show an error message
3. **Timestamp -** shows timestamp of the last fetch which is useful for caching with `keep-alive`
These keys are then used directly in the template area of the component to show relevant placeholders during the process of fetching data from the API.
```html
Fetching posts...
Error while fetching posts
…
```
When error occurs at **component-level**, we can set HTTP status code on server-side by checking `process.server` in fetch hook and follow it up with `throw new Error()` statement.
```js
async fetch() {
const post = await fetch(`https://jsonplaceholder.typicode.com/posts/${this.$route.params.id}`)
.then((res) => res.json())
if (post.id === this.$route.params.id) {
this.post = post
} else {
// set status code on server and
if (process.server) {
this.$nuxt.context.res.statusCode = 404
}
// use throw new Error()
throw new Error('Post not found')
}
}
```
Setting the HTTP status code this way **is useful for correct SEO**.
## Fetch as a method
New fetch hook also acts as a method that can be invoked upon user interaction or invoked programmatically from the component methods.
```html
```
```js
// from component methods in script section
export default {
methods: {
refresh() {
this.$fetch()
}
}
}
```
## Making Nuxt pages more performant
We can use `:keep-alive-props` prop and `activated` hook to make Nuxt page components more performant using a new fetch hook.
Nuxt allows **caching a certain number of pages** in the memory along with their fetched data. And also allows **adding a number of seconds** before we can re-fetch the data.
For any of the above methods to work, we have to use the `keep-alive` prop in generic `` and ` components.
```html [layouts/default.vue]
```
In addition, we can pass `:keep-alive-props` to `` component to cache a number of pages along with their fetched data.
`:keep-alive-props` prop allow us to indicate the maximum number of pages that should be kept in the memory while we navigate elsewhere within the site.
```html [layouts/default.vue]
```
Above is one way to boost page performance which is more high-level and generic, while the next one drills down to optimize the fetch request calls by using the `timestamp` property of `$fetchState` and comparing it against the number of seconds delay before it re-fetches the data.
Vue’s `activated` hook is used here with Nuxt's `keep-alive` prop to re-fetch the data.
```js
export default {
activated() {
// Call fetch again if last fetch more than a minute ago
if (this.$fetchState.timestamp <= Date.now() - 60000) {
this.$fetch()
}
}
}
```
## asyncData vs Fetch
As far as page components are concerned, new `fetch` seems way too similar to `asyncData()` because they both deal with the local data. But there are some key differences worth taking note of as below.
As of Nuxt 2.12, `asyncData` method is still an active feature. Let’s examine some of the key differences between `asyncData` and new `fetch`.
### asyncData
1. `asyncData` is limited to only page-level components
2. `this` context is unavailable
3. Adds payload by **returning** the data
```js
export default {
async asyncData(context) {
const data = await context.$axios.$get(
`https://jsonplaceholder.typicode.com/todos`
)
// `todos` does not have to be declared in data()
return { todos: data.Item }
// `todos` is merged with local data
}
}
```
### New Fetch
1. `fetch` is available in all Vue components
2. `this` context is available
3. Simply **mutates** the local data
```js
export default {
data() {
return {
todos: []
}
},
async fetch() {
const { data } = await axios.get(
`https://jsonplaceholder.typicode.com/todos`
)
// `todos` has to be declared in data()
this.todos = data
}
}
```
## Fetch before Nuxt 2.12
If you have been working with Nuxt for a while, then you’ll know that the previous version of `fetch` was significantly different.
> **Is this a breaking change?**
> No, it isn't. Actually, the old fetch can still be used by passing the `context` as the first argument to avoid any breaking changes in your existing Nuxt applications.
Here’s the list of notable changes in `fetch` hook compared with **before** and **after** v2.12.
### 1. Call order of `fetch` hook
**Before -** `fetch` hook was called before initiating the component, hence `this` wasn’t available inside the fetch hook.
**After -** `fetch` is called after the component instance is created on the server-side when the route is accessed.
### 2. `this` vs `context`
**Before -** We had access to the Nuxt `context` on page-level components, given that the `context` is passed as a first parameter.
```js
export default {
fetch(context) {
// …
}
}
```
**After -** We can access `this` context just like Vue client-side hooks without passing any parameters.
```js
export default {
fetch() {
console.log(this)
}
}
```
### 3. Availability of `fetch` hook
**Before -** Only page (route-level) components were allowed to fetch data on the server-side.
**After -** Now, we can prefetch the data asynchronously in any Vue components.
### 4. Call order of `fetch` hook
**Before -** `fetch` could be called server-side once (on the first request to the Nuxt app) and client-side when navigating to further routes.
**After -** New `fetch` is the same as an old fetch, but…
…since we can have one `fetch` for each component, `fetch` hooks are called in sequence of their hierarchy.
### 5. Error Handling
**Before -** We used the `context.error` function that showed a custom error page when an error occurred during API calls.
**After -** New `fetch` uses the `$fetchState` object to handle errors in the template area during API calls.
Error handling is performed at component level.
> **Does this mean we cannot show users a custom error page like we did prior to Nuxt 2.12?**
Yes we can, but only with `asyncData()` when it's about page-level component data. When using `fetch`, we can utilize `this.$nuxt.error({ statusCode: 404, message: 'Data not found' })` to show a custom error page.
## Conclusion
New fetch hook brings a lot of improvements and provides more flexibility in fetching data and organizing route-level & building-block components in a whole new way!
It will certainly make you think a little differently when you plan and design your new Nuxt project that requires multiple API calls within the same route.
I hope this article has helped you get acquainted with the new `fetch` feature. I'd love to see what you build with it.
---
# Source: https://nuxt.com/raw/docs/3.x/examples/routing/universal-router.md
# Source: https://nuxt.com/raw/docs/4.x/examples/routing/universal-router.md
# Universal Router
> This example demonstrates Nuxt universal routing utilities without depending on `pages/` and `vue-router`.
---
# Source: https://nuxt.com/raw/docs/3.x/api/utils/update-app-config.md
# Source: https://nuxt.com/raw/docs/4.x/api/utils/update-app-config.md
# updateAppConfig
> Update the App Config at runtime.
Updates the [`app.config`](/docs/4.x/directory-structure/app/app-config) using deep assignment. Existing (nested) properties will be preserved.
## Usage
```js
import { updateAppConfig, useAppConfig } from '#imports'
const appConfig = useAppConfig() // { foo: 'bar' }
const newAppConfig = { foo: 'baz' }
updateAppConfig(newAppConfig)
console.log(appConfig) // { foo: 'baz' }
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/commands/upgrade.md
# Source: https://nuxt.com/raw/docs/3.x/getting-started/upgrade.md
# Source: https://nuxt.com/raw/docs/4.x/api/commands/upgrade.md
# Source: https://nuxt.com/raw/docs/4.x/getting-started/upgrade.md
# Upgrade Guide
> Learn how to upgrade to the latest Nuxt version.
## Upgrading Nuxt
### Latest release
To upgrade Nuxt to the [latest release](https://github.com/nuxt/nuxt/releases), use the `nuxt upgrade` command.
```bash [npm]
npx nuxt upgrade
```
```bash [yarn]
yarn nuxt upgrade
```
```bash [pnpm]
pnpm nuxt upgrade
```
```bash [bun]
bun x nuxt upgrade
```
```bash [deno]
deno x nuxt upgrade
```
### Nightly Release Channel
To use the latest Nuxt build and test features before their release, read about the [nightly release channel](/docs/4.x/guide/going-further/nightly-release-channel) guide.
## Testing Nuxt 5
Nuxt 5 is **currently in development**. Until the release, it is possible to test many of Nuxt 5's breaking changes from Nuxt version 4.2+.
### Opting in to Nuxt 5
First, upgrade Nuxt to the [latest release](https://github.com/nuxt/nuxt/releases).
Then you can set your `future.compatibilityVersion` to match Nuxt 5 behavior:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
future: {
compatibilityVersion: 5,
},
})
```
When you set your `future.compatibilityVersion` to `5`, defaults throughout your Nuxt configuration will change to opt in to Nuxt v5 behavior, including:
- **Vite Environment API**: Automatically enables the new [Vite Environment API](/docs/4.x/getting-started/upgrade#migration-to-vite-environment-api) for improved build configuration
- Other Nuxt 5 improvements and changes as they become available
This section is subject to change until the final release, so please check back here regularly if you are testing Nuxt 5 using `future.compatibilityVersion: 5`.
Breaking or significant changes will be noted below along with migration steps for backward/forward compatibility.
### Migration to Vite Environment API
🚦 **Impact Level**: Medium
#### What Changed
Nuxt 5 migrates to Vite 6's new [Environment API](https://vite.dev/guide/api-environment), which formalizes the concept of environments and provides better control over configuration per environment.
Previously, Nuxt used separate client and server Vite configurations. Now, Nuxt uses a shared Vite configuration with environment-specific plugins that use the `applyToEnvironment()` method to target specific environments.
You can test this feature early by setting `future.compatibilityVersion: 5` (see [Testing Nuxt 5](/docs/4.x/getting-started/upgrade#testing-nuxt-5)) or by enabling it explicitly with `experimental.viteEnvironmentApi: true`.
**Key changes:**
1. **Deprecated environment-specific extendViteConfig()**: The `server` and `client` options in `extendViteConfig()` are deprecated and will show warnings when used.
2. **Changed plugin registration**: Vite plugins registered with `addVitePlugin()` and only targeting one environment (by passing `server: false` or `client: false`) will not have their `config` or `configResolved` hooks called.
3. **Shared configuration**: The `vite:extendConfig` and `vite:configResolved` hooks now work with a shared configuration rather than separate client/server configs.
#### Reasons for Change
The Vite Environment API provides:
- Better consistency between development and production builds
- More granular control over environment-specific configuration
- Improved performance and plugin architecture
- Support for custom environments beyond just client and server
#### Migration Steps
##### 1. Migrate to use Vite plugins
We would recommend you use a Vite plugin instead of `extendViteConfig`, `vite:configResolved` and `vite:extendConfig`.
```ts
// Before
extendViteConfig((config) => {
config.optimizeDeps.include.push('my-package')
}, { server: false })
nuxt.hook('vite:extendConfig' /* or vite:configResolved */, (config, { isClient }) => {
if (isClient) {
config.optimizeDeps.include.push('my-package')
}
})
// After
addVitePlugin(() => ({
name: 'my-plugin',
config (config) {
// you can set global vite configuration here
},
configResolved (config) {
// you can access the fully resolved vite configuration here
},
configEnvironment (name, config) {
// you can set environment-specific vite configuration here
if (name === 'client') {
config.optimizeDeps ||= {}
config.optimizeDeps.include ||= []
config.optimizeDeps.include.push('my-package')
}
},
applyToEnvironment (environment) {
return environment.name === 'client'
},
}))
```
##### 2. Migrate Vite plugins to use environments
Instead of using `addVitePlugin` with `server: false` or `client: false`, you can instead use the new `applyToEnvironment` hook within your plugin.
```ts
// Before
addVitePlugin(() => ({
name: 'my-plugin',
config (config) {
config.optimizeDeps.include.push('my-package')
},
}), { client: false })
// After
addVitePlugin(() => ({
name: 'my-plugin',
config (config) {
// you can set global vite configuration here
},
configResolved (config) {
// you can access the fully resolved vite configuration here
},
configEnvironment (name, config) {
// you can set environment-specific vite configuration here
if (name === 'client') {
config.optimizeDeps ||= {}
config.optimizeDeps.include ||= []
config.optimizeDeps.include.push('my-package')
}
},
applyToEnvironment (environment) {
return environment.name === 'client'
},
}))
```
Learn more about Vite's Environment API
## Migrating to Nuxt 4
Nuxt 4 includes significant improvements and changes. This guide will help you migrate your existing Nuxt 3 application to Nuxt 4.
First, upgrade to Nuxt 4:
```bash [npm]
npm install nuxt@^4.0.0
```
```bash [yarn]
yarn add nuxt@^4.0.0
```
```bash [pnpm]
pnpm add nuxt@^4.0.0
```
```bash [bun]
bun add nuxt@^4.0.0
```
```bash [deno]
deno add npm:nuxt@^4.0.0
```
After upgrading, most Nuxt 4 behaviors are now the default. However, some features can still be configured if you need to maintain backward compatibility during your migration.
The following sections detail the key changes and migrations needed when upgrading to Nuxt 4.
Breaking or significant changes are documented below along with migration steps and available configuration options.
### Migrating Using Codemods
To facilitate the upgrade process, we have collaborated with the [Codemod](https://github.com/codemod/codemod) team to automate many migration steps with some open-source codemods.
If you encounter any issues, please report them to the Codemod team with `npx codemod feedback` 🙏
For a complete list of Nuxt 4 codemods, detailed information on each, their source, and various ways to run them, visit the [Codemod Registry](https://app.codemod.com/registry).
You can run all the codemods mentioned in this guide using the following `codemod` recipe:
```bash [npm]
# Using pinned version due to https://github.com/codemod/codemod/issues/1710
npx codemod@0.18.7 nuxt/4/migration-recipe
```
```bash [yarn]
# Using pinned version due to https://github.com/codemod/codemod/issues/1710
yarn dlx codemod@0.18.7 nuxt/4/migration-recipe
```
```bash [pnpm]
# Using pinned version due to https://github.com/codemod/codemod/issues/1710
pnpm dlx codemod@0.18.7 nuxt/4/migration-recipe
```
```bash [bun]
# Using pinned version due to https://github.com/codemod/codemod/issues/1710
bun x codemod@0.18.7 nuxt/4/migration-recipe
```
```bash [deno]
# Using pinned version due to https://github.com/codemod/codemod/issues/1710
deno x codemod@0.18.7 nuxt/4/migration-recipe
```
This command will execute all codemods in sequence, with the option to deselect any that you do not wish to run. Each codemod is also listed below alongside its respective change and can be executed independently.
### New Directory Structure
🚦 **Impact Level**: Significant
Nuxt now defaults to a new directory structure, with backwards compatibility (so if Nuxt detects you are using the old structure, such as with a top-level `app/pages/` directory, this new structure will not apply).
👉 [See full RFC](https://github.com/nuxt/nuxt/issues/26444)
#### What Changed
- the new Nuxt default `srcDir` is `app/` by default, and most things are resolved from there.
- `serverDir` now defaults to `/server` rather than `/server`
- `layers/`, `modules/` and `public/` are resolved relative to `` by default
- if using [Nuxt Content v2.13+](https://github.com/nuxt/content/pull/2649), `content/` is resolved relative to ``
- a new `dir.app` is added, which is the directory we look for `router.options.ts` and `spa-loading-template.html` - this defaults to `/`
An example v4 folder structure.
```sh
.output/
.nuxt/
app/
assets/
components/
composables/
layouts/
middleware/
pages/
plugins/
utils/
app.config.ts
app.vue
router.options.ts
content/
layers/
modules/
node_modules/
public/
shared/
server/
api/
middleware/
plugins/
routes/
utils/
nuxt.config.ts
```
With this new structure, the `~` alias now points to the `app/` directory by default (your `srcDir`). This means `~/components` resolves to `app/components/`, `~/pages` to `app/pages/`, etc.
👉 For more details, see the [PR implementing this change](https://github.com/nuxt/nuxt/pull/27029).
#### Reasons for Change
1. **Performance** - placing all your code in the root of your repo causes issues with `.git/` and `node_modules/` folders being scanned/included by FS watchers which can significantly delay startup on non-Mac OSes.
2. **IDE type-safety** - `server/` and the rest of your app are running in two entirely different contexts with different global imports available, and making sure `server/` isn't *inside* the same folder as the rest of your app is a big first step to ensuring you get good auto-completes in your IDE.
#### Migration Steps
1. Create a new directory called `app/`.
2. Move your `assets/`, `components/`, `composables/`, `app/layouts/`, `app/middleware/`, `app/pages/`, `app/plugins/` and `utils/` folders under it, as well as `app.vue`, `error.vue`, `app.config.ts`. If you have an `app/router-options.ts` or `app/spa-loading-template.html`, these paths remain the same.
3. Make sure your `nuxt.config.ts`, `content/`, `layers/`, `modules/`, `public/` and `server/` folders remain outside the `app/` folder, in the root of your project.
4. Remember to update any third-party configuration files to work with the new directory structure, such as your `tailwindcss` or `eslint` configuration (if required - `@nuxtjs/tailwindcss` should automatically configure `tailwindcss` correctly).
You can automate this migration by running `npx codemod@latest nuxt/4/file-structure`
However, migration is *not required*. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) The one exception is that if you *already* have a custom `srcDir`. In this case, you should be aware that your `modules/`, `public/` and `server/` folders will be resolved from your `rootDir` rather than from your custom `srcDir`. You can override this by configuring `dir.modules`, `dir.public` and `serverDir` if you need to.
You can also force a v3 folder structure with the following configuration:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
// This reverts the new srcDir default from `app` back to your root directory
srcDir: '.',
// This specifies the directory prefix for `router.options.ts` and `spa-loading-template.html`
dir: {
app: 'app',
},
})
```
### Singleton Data Fetching Layer
🚦 **Impact Level**: Moderate
#### What Changed
Nuxt's data fetching system (`useAsyncData` and `useFetch`) has been significantly reorganized for better performance and consistency:
1. **Shared refs for the same key**: All calls to `useAsyncData` or `useFetch` with the same key now share the same `data`, `error` and `status` refs. This means that it is important that all calls with an explicit key must not have conflicting `deep`, `transform`, `pick`, `getCachedData` or `default` options.
2. **More control over getCachedData**: The `getCachedData` function is now called every time data is fetched, even if this is caused by a watcher or calling `refreshNuxtData`. (Previously, new data was always fetched and this function was not called in these cases.) To allow more control over when to use cached data and when to refetch, the function now receives a context object with the cause of the request.
3. **Reactive key support**: You can now use computed refs, plain refs or getter functions as keys, which enables automatic data refetching (and stores data separately).
4. **Data cleanup**: When the last component using data fetched with `useAsyncData` is unmounted, Nuxt will remove that data to avoid ever-growing memory usage.
#### Reasons for Change
These changes have been made to improve memory usage and increase consistency with loading states across calls of `useAsyncData`.
#### Migration Steps
1. **Check for inconsistent options**: Review any components using the same key with different options or fetch functions.```ts
// This will now trigger a warning
const { data: users1 } = useAsyncData('users', () => $fetch('/api/users'), { deep: false })
const { data: users2 } = useAsyncData('users', () => $fetch('/api/users'), { deep: true })
```
It may be beneficial to extract any calls to `useAsyncData` that share an explicit key (and have custom options) into their own composable:```ts [app/composables/useUserData.ts]
export function useUserData (userId: string) {
return useAsyncData(
`user-${userId}`,
() => fetchUser(userId),
{
deep: true,
transform: user => ({ ...user, lastAccessed: new Date() }),
},
)
}
```
2. **Update getCachedData implementations**:```diff
useAsyncData('key', fetchFunction, {
- getCachedData: (key, nuxtApp) => {
- return cachedData[key]
- }
+ getCachedData: (key, nuxtApp, ctx) => {
+ // ctx.cause - can be 'initial' | 'refresh:hook' | 'refresh:manual' | 'watch'
+
+ // Example: Don't use cache on manual refresh
+ if (ctx.cause === 'refresh:manual') return undefined
+
+ return cachedData[key]
+ }
})
```
Alternatively, for now, you can disable this behaviour with:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
granularCachedData: false,
purgeCachedData: false,
},
})
```
### Corrected Module Loading Order in Layers
🚦 **Impact Level**: Minimal
#### What Changed
The order in which modules are loaded when using [Nuxt layers](/docs/4.x/guide/going-further/layers) has been corrected. Previously, modules from the project root were loaded before modules from extended layers, which was the reverse of the expected behavior.
Now modules are loaded in the correct order:
1. **Layer modules first** (in extend order - deeper layers first)
2. **Project modules last** (highest priority)
This affects both:
- Modules defined in the `modules` array in `nuxt.config.ts`
- Auto-discovered modules from the `modules/` directory
#### Reasons for Change
This change ensures that:
- Extended layers have lower priority than the consuming project
- Module execution order matches the intuitive layer inheritance pattern
- Module configuration and hooks work as expected in multi-layer setups
#### Migration Steps
**Most projects will not need changes**, as this corrects the loading order to match expected behavior.
However, if your project was relying on the previous incorrect order, you may need to:
1. **Review module dependencies**: Check if any modules depend on specific loading order
2. **Adjust module configuration**: If modules were configured to work around the incorrect order
3. **Test thoroughly**: Ensure all functionality works as expected with the corrected order
Example of the new correct order:
```ts
// Layer: my-layer/nuxt.config.ts
export default defineNuxtConfig({
modules: ['layer-module-1', 'layer-module-2'],
})
// Project: nuxt.config.ts
export default defineNuxtConfig({
extends: ['./my-layer'],
modules: ['project-module-1', 'project-module-2'],
})
// Loading order (corrected):
// 1. layer-module-1
// 2. layer-module-2
// 3. project-module-1 (can override layer modules)
// 4. project-module-2 (can override layer modules)
```
If you encounter issues with module order dependencies due to needing to register a hook, consider using the [`modules:done` hook](/docs/4.x/guide/modules/recipes-advanced) for modules that need to call a hook. This is run after all other modules have been loaded, which means it is safe to use.
👉 See [PR #31507](https://github.com/nuxt/nuxt/pull/31507) and [issue #25719](https://github.com/nuxt/nuxt/issues/25719) for more details.
### Deduplication of Route Metadata
🚦 **Impact Level**: Minimal
#### What Changed
It's possible to set some route metadata using `definePageMeta`, such as the `name`, `path`, and so on. Previously these were available both on the route and on route metadata (for example, `route.name` and `route.meta.name`).
Now, they are only accessible on the route object.
#### Reasons for Change
This is a result of enabling `experimental.scanPageMeta` by default, and is a performance optimization.
#### Migration Steps
The migration should be straightforward:
```diff
const route = useRoute()
- console.log(route.meta.name)
+ console.log(route.name)
```
### Normalized Component Names
🚦 **Impact Level**: Moderate
Vue will now generate component names that match the Nuxt pattern for component naming.
#### What Changed
By default, if you haven't set it manually, Vue will assign a component name that matches
the filename of the component.
```bash [Directory structure]
├─ components/
├─── SomeFolder/
├───── MyComponent.vue
```
In this case, the component name would be `MyComponent`, as far as Vue is concerned. If you wanted to use `` with it, or identify it in the Vue DevTools, you would need to use this name.
But in order to auto-import it, you would need to use `SomeFolderMyComponent`.
With this change, these two values will match, and Vue will generate a component name that matches the Nuxt pattern for component naming.
#### Migration Steps
Ensure that you use the updated name in any tests which use `findComponent` from `@vue/test-utils` and in any `` which depends on the name of your component.
Alternatively, for now, you can disable this behaviour with:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: false,
},
})
```
### Unhead v2
🚦 **Impact Level**: Minimal
#### What Changed
[Unhead](https://unhead.unjs.io/), used to generate `` tags, has been updated to version 2. While mostly compatible it includes several breaking changes
for lower-level APIs.
- Removed props: `vmid`, `hid`, `children`, `body`.
- Promise input no longer supported.
- Tags are now sorted using Capo.js by default.
#### Migration Steps
The above changes should have minimal impact on your app.
If you have issues you should verify:
- You're not using any of the removed props.
```diff
useHead({
meta: [{
name: 'description',
// meta tags don't need a vmid, or a key
- vmid: 'description'
- hid: 'description'
}]
})
```
- If you're using [Template Params](https://unhead.unjs.io/docs/head/guides/plugins/template-params) or [Alias Tag Sorting](https://unhead.unjs.io/docs/head/guides/plugins/alias-sorting), you will need to explicitly opt in to these features now.
```ts
import { AliasSortingPlugin, TemplateParamsPlugin } from '@unhead/vue/plugins'
export default defineNuxtPlugin({
setup () {
const unhead = injectHead()
unhead.use(TemplateParamsPlugin)
unhead.use(AliasSortingPlugin)
},
})
```
While not required it's recommended to update any imports from `@unhead/vue` to `#imports` or `nuxt/app`.
```diff
-import { useHead } from '@unhead/vue'
+import { useHead } from '#imports'
```
If you still have issues you may revert to the v1 behavior by enabling the `head.legacy` config.
```ts
export default defineNuxtConfig({
unhead: {
legacy: true,
},
})
```
### New DOM Location for SPA Loading Screen
🚦 **Impact Level**: Minimal
#### What Changed
When rendering a client-only page (with `ssr: false`), we optionally render a loading screen (from `~/app/spa-loading-template.html` - note that this has also changed to `~/spa-loading-template.html` in Nuxt 4), within the Nuxt app root:
```html
```
Now, we default to rendering the template alongside the Nuxt app root:
```html
```
#### Reasons for Change
This allows the spa loading template to remain in the DOM until the Vue app suspense resolves, preventing a flash of white.
#### Migration Steps
If you were targeting the spa loading template with CSS or `document.queryElement` you will need to update your selectors. For this purpose you can use the new `app.spaLoaderTag` and `app.spaLoaderAttrs` configuration options.
Alternatively, you can revert to the previous behaviour with:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
spaLoadingTemplateLocation: 'within',
},
})
```
### Parsed `error.data`
🚦 **Impact Level**: Minimal
It was possible to throw an error with a `data` property, but this was not parsed. Now, it is parsed and made available in the `error` object. Although a fix, this is technically a breaking change if you were relying on the previous behavior and parsing it manually.
#### Migration Steps
Update your custom `error.vue` to remove any additional parsing of `error.data`:
```diff
```
### More Granular Inline Styles
🚦 **Impact Level**: Moderate
Nuxt will now only inline styles for Vue components, not global CSS.
#### What Changed
Previously, Nuxt would inline all CSS, including global styles, and remove `` elements to separate CSS files. Now, Nuxt will only do this for Vue components (which previously produced separate chunks of CSS). We think this is a better balance of reducing separate network requests (just as before, there will not be separate requests for individual `.css` files per-page or per-component on the initial load), as well as allowing caching of a single global CSS file and reducing the document download size of the initial request.
#### Migration Steps
This feature is fully configurable and you can revert to the previous behavior by setting `inlineStyles: true` to inline global CSS as well as per-component CSS.
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
features: {
inlineStyles: true,
},
})
```
### Scan Page Meta After Resolution
🚦 **Impact Level**: Minimal
#### What Changed
We now scan page metadata (defined in `definePageMeta`) *after* calling the `pages:extend` hook rather than before.
#### Reasons for Change
This was to allow scanning metadata for pages that users wanted to add in `pages:extend`. We still offer an opportunity to change or override page metadata in a new `pages:resolved` hook.
#### Migration Steps
If you want to override page metadata, do that in `pages:resolved` rather than in `pages:extend`.
```diff
export default defineNuxtConfig({
hooks: {
- 'pages:extend'(pages) {
+ 'pages:resolved'(pages) {
const myPage = pages.find(page => page.path === '/')
myPage.meta ||= {}
myPage.meta.layout = 'overridden-layout'
}
}
})
```
Alternatively, you can revert to the previous behaviour with:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
scanPageMeta: true,
},
})
```
### Shared Prerender Data
🚦 **Impact Level**: Medium
#### What Changed
We enabled a previously experimental feature to share data from `useAsyncData` and `useFetch` calls, across different pages. See [original PR](https://github.com/nuxt/nuxt/pull/24894).
#### Reasons for Change
This feature automatically shares payload *data* between pages that are prerendered. This can result in a significant performance improvement when prerendering sites that use `useAsyncData` or `useFetch` and fetch the same data in different pages.
For example, if your site requires a `useFetch` call for every page (for example, to get navigation data for a menu, or site settings from a CMS), this data would only be fetched once when prerendering the first page that uses it, and then cached for use when prerendering other pages.
#### Migration Steps
Make sure that any unique key of your data is always resolvable to the same data. For example, if you are using `useAsyncData` to fetch data related to a particular page, you should provide a key that uniquely matches that data. (`useFetch` should do this automatically for you.)
```ts [app/pages/test/[slug].vue]
// This would be unsafe in a dynamic page (e.g. `[slug].vue`) because the route slug makes a difference
// to the data fetched, but Nuxt can't know that because it's not reflected in the key.
const route = useRoute()
const { data } = await useAsyncData(async () => {
return await $fetch(`/api/my-page/${route.params.slug}`)
})
// Instead, you should use a key that uniquely identifies the data fetched.
const { data } = await useAsyncData(route.params.slug, async () => {
return await $fetch(`/api/my-page/${route.params.slug}`)
})
```
Alternatively, you can disable this feature with:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
sharedPrerenderData: false,
},
})
```
### Default `data` and `error` values in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Minimal
#### What Changed
`data` and `error` objects returned from `useAsyncData` will now default to `undefined`.
#### Reasons for Change
Previously `data` was initialized to `null` but reset in `clearNuxtData` to `undefined`. `error` was initialized to `null`. This change is to bring greater consistency.
#### Migration Steps
If you were checking if `data.value` or `error.value` were `null`, you can update these checks to check for `undefined` instead.
You can automate this step by running `npx codemod@latest nuxt/4/default-data-error-value`
### Removal of deprecated `boolean` values for `dedupe` option when calling `refresh` in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Minimal
#### What Changed
Previously it was possible to pass `dedupe: boolean` to `refresh`. These were aliases of `cancel` (`true`) and `defer` (`false`).
```ts [app/app.vue]twoslash
// @errors: 2322
const { refresh } = await useAsyncData(() => Promise.resolve({ message: 'Hello, Nuxt!' }))
async function refreshData () {
await refresh({ dedupe: true })
}
```
#### Reasons for Change
These aliases were removed, for greater clarity.
The issue came up when adding `dedupe` as an option to `useAsyncData`, and we removed the boolean values as they ended up being *opposites*.
`refresh({ dedupe: false })` meant **do not cancel existing requests in favour of this new one**. But passing `dedupe: true` within the options of `useAsyncData` means **do not make any new requests if there is an existing pending request.** (See [PR](https://github.com/nuxt/nuxt/pull/24564#pullrequestreview-1764584361).)
#### Migration Steps
The migration should be straightforward:
```diff
const { refresh } = await useAsyncData(async () => ({ message: 'Hello, Nuxt 3!' }))
async function refreshData () {
- await refresh({ dedupe: true })
+ await refresh({ dedupe: 'cancel' })
- await refresh({ dedupe: false })
+ await refresh({ dedupe: 'defer' })
}
```
You can automate this step by running `npx codemod@latest nuxt/4/deprecated-dedupe-value`
### Respect defaults when clearing `data` in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Minimal
#### What Changed
If you provide a custom `default` value for `useAsyncData`, this will now be used when calling `clear` or `clearNuxtData` and it will be reset to its default value rather than simply unset.
#### Reasons for Change
Often users set an appropriately empty value, such as an empty array, to avoid the need to check for `null`/`undefined` when iterating over it. This should be respected when resetting/clearing the data.
### Alignment of `pending` value in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Medium
The `pending` object returned from `useAsyncData`, `useFetch`, `useLazyAsyncData` and `useLazyFetch` is now a computed property that is `true` only when `status` is also pending.
#### What Changed
Now, when `immediate: false` is passed, `pending` will be `false` until the first request is made. This is a change from the previous behavior, where `pending` was always `true` until the first request was made.
#### Reasons for Change
This aligns the meaning of `pending` with the `status` property, which is also `pending` when the request is in progress.
#### Migration Steps
If you rely on the `pending` property, ensure that your logic accounts for the new behavior where `pending` will only be `true` when the status is also pending.
```diff
-
+
Data: {{ data }}
Loading...
```
Alternatively, you can temporarily revert to the previous behavior with:
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
pendingWhenIdle: true,
},
})
```
### Key Change Behavior in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Medium
#### What Changed
When using reactive keys in `useAsyncData` or `useFetch`, Nuxt automatically refetches data when the key changes. When `immediate: false` is set, `useAsyncData` will only fetch data when the key changes if the data has already been fetched once.
Previously, `useFetch` had slightly different behavior. It would always fetch data when the key changed.
Now, `useFetch` and `useAsyncData` behave consistently - by only fetch data when the key changes if the data has already been fetched once.
#### Reasons for Change
This ensures consistent behavior between `useAsyncData` and `useFetch`, and prevents unexpected fetches. If you have set `immediate: false`, then you must call `refresh` or `execute` or data will never be fetched in `useFetch` or `useAsyncData`.
#### Migration Steps
This change should generally improve the expected behavior, but if you were expecting changing the key or options of a non-immediate `useFetch`, you now will need to trigger it manually the first time.
```diff
const id = ref('123')
const { data, execute } = await useFetch('/api/test', {
query: { id },
immediate: false
)
+ watch(id, () => execute(), { once: true })
```
To opt out of this behavior:
```ts
// Or globally in your Nuxt config
export default defineNuxtConfig({
experimental: {
alwaysRunFetchOnKeyChange: true,
},
})
```
### Shallow Data Reactivity in `useAsyncData` and `useFetch`
🚦 **Impact Level**: Minimal
The `data` object returned from `useAsyncData`, `useFetch`, `useLazyAsyncData` and `useLazyFetch` is now a `shallowRef` rather than a `ref`.
#### What Changed
When new data is fetched, anything depending on `data` will still be reactive because the entire object is replaced. But if your code changes a property *within* that data structure, this will not trigger any reactivity in your app.
#### Reasons for Change
This brings a **significant** performance improvement for deeply nested objects and arrays because Vue does not need to watch every single property/array for modification. In most cases, `data` should also be immutable.
#### Migration Steps
In most cases, no migration steps are required, but if you rely on the reactivity of the data object then you have two options:
1. You can granularly opt in to deep reactivity on a per-composable basis:
```diff
- const { data } = useFetch('/api/test')
+ const { data } = useFetch('/api/test', { deep: true })
```
2. You can change the default behavior on a project-wide basis (not recommended):
```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
experimental: {
defaults: {
useAsyncData: {
deep: true,
},
},
},
})
```
If you need to, you can automate this step by running `npx codemod@latest nuxt/4/shallow-function-reactivity`
### Absolute Watch Paths in `builder:watch`
🚦 **Impact Level**: Minimal
#### What Changed
The Nuxt `builder:watch` hook now emits a path which is absolute rather than relative to your project `srcDir`.
#### Reasons for Change
This allows us to support watching paths which are outside your `srcDir`, and offers better support for layers and other more complex patterns.
#### Migration Steps
We have already proactively migrated the public Nuxt modules which we are aware use this hook. See [issue #25339](https://github.com/nuxt/nuxt/issues/25339).
However, if you are a module author using the `builder:watch` hook and wishing to remain backwards/forwards compatible, you can use the following code to ensure that your code works the same in both Nuxt v3 and Nuxt v4:
```diff
+ import { relative, resolve } from 'node:fs'
// ...
nuxt.hook('builder:watch', async (event, path) => {
+ path = relative(nuxt.options.srcDir, resolve(nuxt.options.srcDir, path))
// ...
})
```
You can automate this step by running `npx codemod@latest nuxt/4/absolute-watch-path`
### Removal of `window.__NUXT__` object
#### What Changed
We are removing the global `window.__NUXT__` object after the app finishes hydration.
#### Reasons for Change
This opens the way to multi-app patterns ([#21635](https://github.com/nuxt/nuxt/issues/21635)) and enables us to focus on a single way to access Nuxt app data - `useNuxtApp()`.
#### Migration Steps
The data is still available, but can be accessed with `useNuxtApp().payload`:
```diff
- console.log(window.__NUXT__)
+ console.log(useNuxtApp().payload)
```
### Directory index scanning
🚦 **Impact Level**: Medium
#### What Changed
Child folders in your `app/middleware/` folder are also scanned for `index` files and these are now also registered as middleware in your project.
#### Reasons for Change
Nuxt scans a number of folders automatically, including `app/middleware/` and `app/plugins/`.
Child folders in your `app/plugins/` folder are scanned for `index` files and we wanted to make this behavior consistent between scanned directories.
#### Migration Steps
Probably no migration is necessary but if you wish to revert to previous behavior you can add a hook to filter out these middleware:
```ts
export default defineNuxtConfig({
hooks: {
'app:resolve' (app) {
app.middleware = app.middleware.filter(mw => !/\/index\.[^/]+$/.test(mw.path))
},
},
})
```
### Template Compilation Changes
🚦 **Impact Level**: Minimal
#### What Changed
Previously, Nuxt used `lodash/template` to compile templates located on the file system using the `.ejs` file format/syntax.
In addition, we provided some template utilities (`serialize`, `importName`, `importSources`) which could be used for code-generation within these templates, which are now being removed.
#### Reasons for Change
In Nuxt v3 we moved to a 'virtual' syntax with a `getContents()` function which is much more flexible and performant.
In addition, `lodash/template` has had a succession of security issues. These do not really apply to Nuxt projects because it is being used at build-time, not runtime, and by trusted code. However, they still appear in security audits. Moreover, `lodash` is a hefty dependency and is unused by most projects.
Finally, providing code serialization functions directly within Nuxt is not ideal. Instead, we maintain projects like [unjs/knitwork](https://github.com/unjs/knitwork) which can be dependencies of your project, and where security issues can be reported/resolved directly without requiring an upgrade of Nuxt itself.
#### Migration Steps
We have raised PRs to update modules using EJS syntax, but if you need to do this yourself, you have three backwards/forwards-compatible alternatives:
- Moving your string interpolation logic directly into `getContents()`.
- Using a custom function to handle the replacement, such as in [https://github.com/nuxt-modules/color-mode/pull/240](https://github.com/nuxt-modules/color-mode/pull/240).
- Use `es-toolkit/compat` (a drop-in replacement for lodash template), as a dependency of *your* project rather than Nuxt:
```diff
+ import { readFileSync } from 'node:fs'
+ import { template } from 'es-toolkit/compat'
// ...
addTemplate({
fileName: 'appinsights-vue.js'
options: { /* some options */ },
- src: resolver.resolve('./runtime/plugin.ejs'),
+ getContents({ options }) {
+ const contents = readFileSync(resolver.resolve('./runtime/plugin.ejs'), 'utf-8')
+ return template(contents)({ options })
+ },
})
```
Finally, if you are using the template utilities (`serialize`, `importName`, `importSources`), you can replace them as follows with utilities from `knitwork`:
```ts
import { genDynamicImport, genImport, genSafeVariableName } from 'knitwork'
const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"\{(.+)\}"(?=,?$)/gm, r => JSON.parse(r).replace(/^\{(.*)\}$/, '$1'))
const importSources = (sources: string | string[], { lazy = false } = {}) => {
return toArray(sources).map((src) => {
if (lazy) {
return `const ${genSafeVariableName(src)} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}`
}
return genImport(src, genSafeVariableName(src))
}).join('\n')
}
const importName = genSafeVariableName
```
You can automate this step by running `npx codemod@latest nuxt/4/template-compilation-changes`
### Default TypeScript Configuration Changes
🚦 **Impact Level**: Minimal
#### What Changed
`compilerOptions.noUncheckedIndexedAccess` is now `true` instead of `false`.
#### Reasons for Change
This change is a follow up to a prior [3.12 config update](https://github.com/nuxt/nuxt/pull/27485) where we improved our defaults, mostly adhering to [TotalTypeScript's recommendations](https://www.totaltypescript.com/tsconfig-cheat-sheet).
#### Migration Steps
There are two approaches:
1. Run a typecheck on your app and fix any new errors (recommended).
2. Override the new default in your `nuxt.config.ts`:```ts
export default defineNuxtConfig({
typescript: {
tsConfig: {
compilerOptions: {
noUncheckedIndexedAccess: false,
},
},
},
})
```
### TypeScript Configuration Splitting
🚦 **Impact Level**: Minimal
#### What Changed
Nuxt now generates separate TypeScript configurations for different contexts to provide better type-checking experiences:
1. **New TypeScript configuration files**: Nuxt now generates additional TypeScript configurations:
- `.nuxt/tsconfig.app.json` - For your app code (Vue components, composables, etc.)
- `.nuxt/tsconfig.server.json` - For your server-side code (Nitro/server directory)
- `.nuxt/tsconfig.node.json` - For your build-time code (modules, `nuxt.config.ts`, etc.)
- `.nuxt/tsconfig.shared.json` - For code shared between app and server contexts (like types and non-environment specific utilities)
- `.nuxt/tsconfig.json` - Legacy configuration for backward compatibility
2. **Backward compatibility**: Existing projects that extend `.nuxt/tsconfig.json` will continue to work as before.
3. **Opt-in project references**: New projects or those wanting better type checking can adopt TypeScript's project references feature.
4. **Context-specific type checking**: Each context now has appropriate compiler options and includes/excludes for its specific environment.
5. **New typescript.nodeTsConfig option**: You can now customize the TypeScript configuration for Node.js build-time code.
#### Reasons for Change
This change provides several benefits:
1. **Better type safety**: Each context (app, server, build-time) gets appropriate type checking with context-specific globals and APIs.
2. **Improved IDE experience**: Better IntelliSense and error reporting for different parts of your codebase.
3. **Cleaner separation**: Server code won't incorrectly suggest client-side APIs and vice versa.
4. **Performance**: TypeScript can more efficiently check code with properly scoped configurations.
For example, auto-imports are not available in your `nuxt.config.ts` (but previously this was not flagged by TypeScript). And while IDEs recognized the separate context hinted by `tsconfig.json` in your `server/` directory, this was not reflected in type-checking (requiring a separate step).
#### Migration Steps
**No migration is required** - existing projects will continue to work as before.
However, to take advantage of improved type checking, you can opt in to the new project references approach:
1. **Update your root tsconfig.json** to use project references:
If your `tsconfig.json` currently has an `"extends": "./.nuxt/tsconfig.json"` line, **remove it** before adding the references. Project references and extends are mutually exclusive.
```json
{
// Remove "extends": "./.nuxt/tsconfig.json" if present
"files": [],
"references": [
{ "path": "./.nuxt/tsconfig.app.json" },
{ "path": "./.nuxt/tsconfig.server.json" },
{ "path": "./.nuxt/tsconfig.shared.json" },
{ "path": "./.nuxt/tsconfig.node.json" }
]
}
```
2. **Remove any manual server tsconfig.json** files (like `server/tsconfig.json`) that extended `.nuxt/tsconfig.server.json`.
3. **Update your type checking scripts** to use the build flag for project references:```diff
- "typecheck": "nuxt prepare && vue-tsc --noEmit"
+ "typecheck": "nuxt prepare && vue-tsc -b --noEmit"
```
4. **Move all type augmentations into their appropriate context**:
- If you are augmenting types for the app context, move the files to the `app/` directory.
- If you are augmenting types for the server context, move the files to the `server/` directory.
- If you are augmenting types that are **shared between the app and server**, move the files to the `shared/` directory.
Augmenting types from outside the `app/`, `server/`, or `shared/` directories will not work with the new project references setup.
5. **Configure TypeScript options** if needed:```ts
export default defineNuxtConfig({
typescript: {
// customize tsconfig.app.json
tsConfig: {
// ...
},
// customize tsconfig.shared.json
sharedTsConfig: {
// ...
},
// customize tsconfig.node.json
nodeTsConfig: {
// ...
},
},
nitro: {
typescript: {
// customize tsconfig.server.json
tsConfig: {
// ...
},
},
},
})
```
6. **Update any CI/build scripts** that run TypeScript checking to ensure they use the new project references approach.
The new configuration provides better type safety and IntelliSense for projects that opt in, while maintaining full backward compatibility for existing setups.
### Removal of Experimental Features
🚦 **Impact Level**: Minimal
#### What Changed
Four experimental features are no longer configurable in Nuxt 4:
- `experimental.treeshakeClientOnly` will be `true` (default since v3.0)
- `experimental.configSchema` will be `true` (default since v3.3)
- `experimental.polyfillVueUseHead` will be `false` (default since v3.4)
- `experimental.respectNoSSRHeader` will be `false` (default since v3.4)
- `vite.devBundler` is no longer configurable - it will use `vite-node` by default
#### Reasons for Change
These options have been set to their current values for some time and we do not have a reason to believe that they need to remain configurable.
#### Migration Steps
- `polyfillVueUseHead` is implementable in user-land with [this plugin](https://github.com/nuxt/nuxt/blob/f209158352b09d1986aa320e29ff36353b91c358/packages/nuxt/src/head/runtime/plugins/vueuse-head-polyfill.ts#L10-L11)
- `respectNoSSRHeader`is implementable in user-land with [server middleware](https://github.com/nuxt/nuxt/blob/c660b39447f0d5b8790c0826092638d321cd6821/packages/nuxt/src/core/runtime/nitro/no-ssr.ts#L8-L9)
### Removal of Top-Level `generate` Configuration
🚦 **Impact Level**: Minimal
#### What Changed
The top-level `generate` configuration option is no longer available in Nuxt 4. This includes all of its properties:
- `generate.exclude` - for excluding routes from prerendering
- `generate.routes` - for specifying routes to prerender
#### Reasons for Change
The top level `generate` configuration was a holdover from Nuxt 2. We've supported `nitro.prerender` for a while now, and it is the preferred way to configure prerendering in Nuxt 3+.
#### Migration Steps
Replace `generate` configuration with the corresponding `nitro.prerender` options:
```diff
export default defineNuxtConfig({
- generate: {
- exclude: ['/admin', '/private'],
- routes: ['/sitemap.xml', '/robots.txt']
- }
+ nitro: {
+ prerender: {
+ ignore: ['/admin', '/private'],
+ routes: ['/sitemap.xml', '/robots.txt']
+ }
+ }
})
```
Read more about Nitro's prerender configuration options.
## Nuxt 2 vs. Nuxt 3+
In the table below, there is a quick comparison between 3 versions of Nuxt:
Feature / Version
Nuxt 2
Nuxt Bridge
Nuxt 3+
Vue
2
2
3
Stability
😊 Stable
😊 Stable
😊 Stable
Performance
🏎 Fast
✈️ Faster
🚀 Fastest
Nitro Engine
❌
✅
✅
ESM support
🌙 Partial
👍 Better
✅
TypeScript
☑️ Opt-in
🚧 Partial
✅
Composition API
❌
🚧 Partial
✅
Options API
✅
✅
✅
Components Auto Import
✅
✅
✅
```
If you're using a custom `useAsyncData` wrapper, do not await it in the composable as that can cause unexpected behavior. See recipe for custom async data fetcher.
`data`, `status`, `pending` and `error` are Vue refs and they should be accessed with `.value` when used within the `
```
### Reactive Keys
You can use a computed ref, plain ref or a getter function as the key, allowing for dynamic data fetching that automatically updates when the key changes:
```vue [app/pages/[id].vue]
```
### Make your `handler` abortable
You can make your `handler` function abortable by using the `signal` provided in the second argument. This is useful for cancelling requests when they are no longer needed, such as when a user navigates away from a page. `$fetch` natively supports abort signals.
```ts
const { data, error } = 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
```
You can also pass an `AbortSignal` to the `refresh`/`execute` function to cancel individual requests manually.
```ts
const { refresh } = await useAsyncData(
'users',
(_nuxtApp, { signal }) => $fetch('/api/users', { signal }),
)
let abortController: AbortController | undefined
function handleUserAction () {
abortController = new AbortController()
refresh({ signal: abortController.signal })
}
function handleCancel () {
abortController?.abort() // aborts the ongoing refresh request
}
```
If your `handler` function does not support abort signals, you can implement your own abort logic using the `signal` provided.
```ts
const { data, error } = await useAsyncData(
'users',
(_nuxtApp, { signal }) => {
return new Promise((resolve, reject) => {
signal?.addEventListener('abort', () => {
reject(new Error('Request aborted'))
})
return Promise.resolve(callback.call(this, yourHandler)).then(resolve, reject)
})
},
)
```
The handler signal will be aborted when:
- A new request is made with `dedupe: 'cancel'`
- The `clear` function is called
- The `options.timeout` duration is exceeded
[`useAsyncData`](/docs/4.x/api/composables/use-async-data) is a reserved function name transformed by the compiler, so you should not name your own function [`useAsyncData`](/docs/4.x/api/composables/use-async-data).
## Params
- `key`: a unique key to ensure that data fetching can be properly de-duplicated across requests. If you do not provide a key, then a key that is unique to the file name and line number of the instance of `useAsyncData` will be generated for you.
- `handler`: an asynchronous function that must return a truthy value (for example, it should not be `undefined` or `null`) or the request may be duplicated on the client side.
The `handler` function should be **side-effect free** to ensure predictable behavior during SSR and CSR hydration. If you need to trigger side effects, use the [`callOnce`](/docs/4.x/api/utils/call-once) utility to do so.
- `options`:
- `server`: whether to fetch the data on the server (defaults to `true`)
- `lazy`: whether to resolve the async function after loading the route, instead of blocking client-side navigation (defaults to `false`)
- `immediate`: when set to `false`, will prevent the request from firing immediately. (defaults to `true`)
- `default`: a factory function to set the default value of the `data`, before the async function resolves - useful with the `lazy: true` or `immediate: false` option
- `transform`: a function that can be used to alter `handler` function result after resolving
- `getCachedData`: Provide a function which returns cached data. An `undefined` return value will trigger a fetch. By default, this is:
```ts
const getDefaultCachedData = (key, nuxtApp, ctx) => nuxtApp.isHydrating
? nuxtApp.payload.data[key]
: nuxtApp.static.data[key]
```
Which only caches data when `experimental.payloadExtraction` of `nuxt.config` is enabled.
- `pick`: only pick specified keys in this array from the `handler` function result
- `watch`: watch reactive sources to auto-refresh
- `deep`: return data in a deep ref object. It is `false` by default to return data in a shallow ref object, which can improve performance if your data does not need to be deeply reactive.
- `dedupe`: avoid fetching same key more than once at a time (defaults to `cancel`). Possible options:
- `cancel` - cancels existing requests when a new one is made
- `defer` - does not make new requests at all if there is a pending request
- `timeout` - a number in milliseconds to wait before timing out the request (defaults to `undefined`, which means no timeout)
Under the hood, `lazy: false` uses `` to block the loading of the route before the data has been fetched. Consider using `lazy: true` and implementing a loading state instead for a snappier user experience.
You can use `useLazyAsyncData` to have the same behavior as `lazy: true` with `useAsyncData`.
### Shared State and Option Consistency
When using the same key for multiple `useAsyncData` calls, they will share the same `data`, `error`, `status` and `pending` refs. This ensures consistency across components but requires option consistency.
The following options **must be consistent** across all calls with the same key:
- `handler` function
- `deep` option
- `transform` function
- `pick` array
- `getCachedData` function
- `default` value
The following options **can differ** without triggering warnings:
- `server`
- `lazy`
- `immediate`
- `dedupe`
- `watch`
```ts
// ❌ This will trigger a development warning
const { data: users1 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { deep: false })
const { data: users2 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { deep: true })
// ✅ This is allowed
const { data: users1 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { immediate: true })
const { data: users2 } = useAsyncData('users', (_nuxtApp, { signal }) => $fetch('/api/users', { signal }), { immediate: false })
```
Keyed state created using `useAsyncData` can be retrieved across your Nuxt application using [`useNuxtData`](/docs/4.x/api/composables/use-nuxt-data).
## Return Values
- `data`: the result of the asynchronous function that is passed in.
- `refresh`/`execute`: a function that can be used to refresh the data returned by the `handler` function.
- `error`: an error object if the data fetching failed.
- `status`: a string indicating the status of the data request:
- `idle`: when the request has not started, such as:
- when `execute` has not yet been called and `{ immediate: false }` is set
- when rendering HTML on the server and `{ server: false }` is set
- `pending`: the request is in progress
- `success`: the request has completed successfully
- `error`: the request has failed
- `pending`: a `Ref` that is `true` while the request is in progress (that is, while `status.value === 'pending'`).
- `clear`: a function that can be used to set `data` to `undefined` (or the value of `options.default()` if provided), set `error` to `undefined`, set `status` to `idle`, and mark any currently pending requests as cancelled.
By default, Nuxt waits until a `refresh` is finished before it can be executed again.
If you have not fetched data on the server (for example, with `server: false`), then the data *will not* be fetched until hydration completes. This means even if you await [`useAsyncData`](/docs/4.x/api/composables/use-async-data) on the client side, `data` will remain `undefined` within `
Counter: {{ counter || '-' }}
```
### Readonly Cookies
```vue
User score: {{ user?.score }}
```
### Writable Cookies
```vue
List
{{ list }}
```
### Cookies in API Routes
You can use `getCookie` and `setCookie` from [`h3`](https://github.com/h3js/h3) package to set cookies in server API routes.
```ts [server/api/counter.ts]
export default defineEventHandler((event) => {
// Read counter cookie
let counter = getCookie(event, 'counter') || 0
// Increase counter cookie by 1
setCookie(event, 'counter', ++counter)
// Send JSON response
return { counter }
})
```
---
# Source: https://nuxt.com/raw/docs/3.x/examples/advanced/use-custom-fetch-composable.md
# Source: https://nuxt.com/raw/docs/4.x/examples/advanced/use-custom-fetch-composable.md
# Use Custom Fetch Composable
> This example shows a convenient wrapper for the useFetch composable from nuxt. It allows you to customize the fetch request with default values and user authentication token.
---
# Source: https://nuxt.com/raw/docs/3.x/api/composables/use-error.md
# Source: https://nuxt.com/raw/docs/4.x/api/composables/use-error.md
# useError
> useError composable returns the global Nuxt error that is being handled.
## Usage
The `useError` composable returns the global Nuxt error that is being handled and is available on both client and server. It provides a reactive, SSR-friendly error state across your app.
```ts
const error = useError()
```
You can use this composable in your components, pages, or plugins to access or react to the current Nuxt error.
## Type
```ts
interface NuxtError {
status: number
statusText: string
message: string
data?: DataT
error?: true
}
export const useError: () => Ref
```
## Parameters
This composable does not take any parameters.
## Return Values
Returns a `Ref` containing the current Nuxt error (or `undefined` if there is no error). The error object is reactive and will update automatically when the error state changes.
## Example
```vue
```
---
# Source: https://nuxt.com/raw/docs/3.x/api/composables/use-fetch.md
# Source: https://nuxt.com/raw/docs/4.x/api/composables/use-fetch.md
# useFetch
> Fetch data from an API endpoint with an SSR-friendly composable.
This composable provides a convenient wrapper around [`useAsyncData`](/docs/4.x/api/composables/use-async-data) and [`$fetch`](/docs/4.x/api/utils/dollarfetch).
It automatically generates a key based on URL and fetch options, provides type hints for request url based on server routes, and infers API response type.
`useFetch` is a composable meant to be called directly in a setup function, plugin, or route middleware. It returns reactive composables and handles adding responses to the Nuxt payload so they can be passed from server to client without re-fetching the data on client side when the page hydrates.
## Usage
```vue [app/pages/modules.vue]
```
If you're using a custom `useFetch` wrapper, do not await it in the composable as that can cause unexpected behavior. See recipe for custom async data fetcher.
`data`, `status`, and `error` are Vue refs, and they should be accessed with `.value` when used within the `
```
When using `useFetch` with the same URL and options in multiple components, they will share the same `data`, `error` and `status` refs. This ensures consistency across components.
Keyed state created using `useFetch` can be retrieved across your Nuxt application using [`useNuxtData`](/docs/4.x/api/composables/use-nuxt-data).
`useFetch` is a reserved function name transformed by the compiler, so you should not name your own function `useFetch`.
If you encounter the `data` variable destructured from a `useFetch` returns a string and not a JSON parsed object then make sure your component doesn't include an import statement like `import { useFetch } from '@vueuse/core`.
### Reactive Fetch Options
Fetch options can be provided as reactive, supporting `computed`, `ref` and [computed getters](https://vuejs.org/guide/essentials/computed). When a reactive fetch option is updated it will trigger a refetch using the updated resolved reactive value.
```ts
const searchQuery = ref('initial')
const { data } = await useFetch('/api/search', {
query: { q: searchQuery },
})
// triggers a refetch: /api/search?q=new%20search
searchQuery.value = 'new search'
```
If needed, you can opt out of this behavior using `watch: false`:
```ts
const searchQuery = ref('initial')
const { data } = await useFetch('/api/search', {
query: { q: searchQuery },
watch: false,
})
// does not trigger a refetch
searchQuery.value = 'new search'
```
## Type
```ts [Signature]
export function useFetch (
url: string | Request | Ref | (() => string | Request),
options?: UseFetchOptions,
): Promise>
type UseFetchOptions = {
key?: MaybeRefOrGetter
method?: MaybeRefOrGetter
query?: MaybeRefOrGetter
params?: MaybeRefOrGetter
body?: MaybeRefOrGetter>
headers?: MaybeRefOrGetter | [key: string, value: string][] | Headers>
baseURL?: MaybeRefOrGetter
server?: boolean
lazy?: boolean
immediate?: boolean
getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
deep?: boolean
dedupe?: 'cancel' | 'defer'
timeout?: number
default?: () => DataT
transform?: (input: DataT) => DataT | Promise
pick?: string[]
$fetch?: typeof globalThis.$fetch
watch?: MultiWatchSources | false
timeout?: MaybeRefOrGetter
}
type AsyncDataRequestContext = {
/** The reason for this data request */
cause: 'initial' | 'refresh:manual' | 'refresh:hook' | 'watch'
}
type AsyncData = {
data: Ref
refresh: (opts?: AsyncDataExecuteOptions) => Promise
execute: (opts?: AsyncDataExecuteOptions) => Promise
clear: () => void
error: Ref
status: Ref
}
interface AsyncDataExecuteOptions {
dedupe?: 'cancel' | 'defer'
timeout?: number
signal?: AbortSignal
}
type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'
```
## Parameters
- `URL` (`string | Request | Ref | () => string | Request`): The URL or request to fetch. Can be a string, a Request object, a Vue ref, or a function returning a string/Request. Supports reactivity for dynamic endpoints.
- `options` (object): Configuration for the fetch request. Extends [unjs/ofetch](https://github.com/unjs/ofetch) options and [`AsyncDataOptions`](/docs/4.x/api/composables/use-async-data#params). All options can be a static value, a `ref`, or a computed value.
Option
Type
Default
Description
key
MaybeRefOrGetter
auto-gen
Unique key for de-duplication. If not provided, generated from URL and options.
method
MaybeRefOrGetter
'GET'
HTTP request method.
query
MaybeRefOrGetter
-
Query/search params to append to the URL. Alias:
params
.
params
MaybeRefOrGetter
-
Alias for
query
.
body
MaybeRefOrGetter>
-
Request body. Objects are automatically stringified.
headers
MaybeRefOrGetter | [key, value][] | Headers>
-
Request headers.
baseURL
MaybeRefOrGetter
-
Base URL for the request.
timeout
MaybeRefOrGetter
-
Timeout in milliseconds to abort the request.
cache
boolean | string
-
Cache control. Boolean disables cache, or use Fetch API values:
default
,
no-store
, etc.
server
boolean
true
Whether to fetch on the server.
lazy
boolean
false
If true, resolves after route loads (does not block navigation).
immediate
boolean
true
If false, prevents request from firing immediately.
default
() => DataT
-
Factory for default value of
data
before async resolves.
timeout
number
-
A number in milliseconds to wait before timing out the request (defaults to
undefined
, which means no timeout)
transform
(input: DataT) => DataT | Promise
-
Function to transform the result after resolving.
getCachedData
(key, nuxtApp, ctx) => DataT | undefined
-
Function to return cached data. See below for default.
pick
string[]
-
Only pick specified keys from the result.
watch
MultiWatchSources | false
-
Array of reactive sources to watch and auto-refresh.
false
disables watching.
All fetch options can be given a `computed` or `ref` value. These will be watched and new requests made automatically with any new values if they are updated.
**getCachedData default:**
```ts
const getDefaultCachedData = (key, nuxtApp, ctx) => nuxtApp.isHydrating
? nuxtApp.payload.data[key]
: nuxtApp.static.data[key]
```
This only caches data when `experimental.payloadExtraction` in `nuxt.config` is enabled.
## Return Values
Name
Type
Description
data
Ref
The result of the asynchronous fetch.
refresh
(opts?: AsyncDataExecuteOptions) => Promise
Function to manually refresh the data. By default, Nuxt waits until a
refresh
is finished before it can be executed again.
execute
(opts?: AsyncDataExecuteOptions) => Promise
Alias for
refresh
.
error
Ref
Error object if the data fetching failed.
status
Ref<'idle' | 'pending' | 'success' | 'error'>
Status of the data request. See below for possible values.
clear
() => void
Resets
data
to
undefined
(or the value of
options.default()
if provided),
error
to
undefined
, set
status
to
idle
, and cancels any pending requests.
### Status values
- `idle`: Request has not started (e.g. `{ immediate: false }` or `{ server: false }` on server render)
- `pending`: Request is in progress
- `success`: Request completed successfully
- `error`: Request failed
If you have not fetched data on the server (for example, with `server: false`), then the data *will not* be fetched until hydration completes. This means even if you await `useFetch` on client-side, `data` will remain null within `
```
Read more on the `Unhead` documentation.
---
# Source: https://nuxt.com/raw/docs/3.x/api/composables/use-head.md
# Source: https://nuxt.com/raw/docs/4.x/api/composables/use-head.md
# useHead
> useHead customizes the head properties of individual pages of your Nuxt app.
## Usage
The `useHead` composable allows you to manage your head tags in a programmatic and reactive way, powered by [Unhead](https://unhead.unjs.io). It lets you customize the meta tags, links, scripts, and other elements in the `` section of your HTML document.
```vue [app/app.vue]
```
If the data comes from a user or other untrusted source, we recommend you check out [`useHeadSafe`](/docs/4.x/api/composables/use-head-safe).
The properties of `useHead` can be dynamic, accepting `ref`, `computed` and `reactive` properties. The `meta` parameter can also accept a function returning an object to make the entire object reactive.
## Type
```ts [Signature]
export function useHead (meta: MaybeComputedRef): ActiveHeadEntry
interface MetaObject {
title?: string
titleTemplate?: string | ((title?: string) => string)
base?: Base
link?: Link[]
meta?: Meta[]
style?: Style[]
script?: Script[]
noscript?: Noscript[]
htmlAttrs?: HtmlAttributes
bodyAttrs?: BodyAttributes
}
interface ActiveHeadEntry {
/**
* Updates the entry with new input.
*
* Will first clear any side effects for previous input.
*/
patch: (input: Input) => void
/**
* Dispose the entry, removing it from the active head.
*
* Will queue side effects for removal.
*/
dispose: () => void
}
```
See [@unhead/schema](https://github.com/unjs/unhead/blob/main/packages/vue/src/types/schema.ts) for more detailed types.
## Parameters
`meta`: An object accepting head metadata properties to customize the page's `` section. All properties support reactive values (`ref`, `computed`, `reactive`) or can be a function returning the metadata object.
Property
Type
Description
title
string
Sets the page title.
titleTemplate
string | ((title?: string) => string)
Configures a dynamic template to customize the page title. Can be a string with
%s
placeholder or a function.
base
Base
Sets the
tag for the document.
link
Link[]
Array of link objects. Each element is mapped to a
tag, where object properties correspond to HTML attributes.
meta
Meta[]
Array of meta objects. Each element is mapped to a
tag, where object properties correspond to HTML attributes.
style
Style[]
Array of style objects. Each element is mapped to a