extendPages function signature
extendPages is a function with signature: function extendPages(callback: (pages: NuxtPage[]) => void): void. It takes a callback function that receives the pages configuration array and allows you to modify it directly by adding, deleting, or modifying elements.
NuxtPage properties for extendPages
The NuxtPage object passed to extendPages callback has the following properties: name (string, not required) - the name of the route useful for programmatic navigation and identifying routes; path (string, not required) - the route URL path, if not set Nuxt will infer it from file location; file (string, not required) - path to the Vue file used as the component for the route; meta (NuxtPageMeta, not required) - custom metadata for the route usable in layouts, middlewares, or navigation guards; alias (string[] | string, not required) - one or more alias paths for the route useful for supporting multiple URLs; redirect (RouteLocationRaw, not required) - redirect rule for the route supporting named routes, objects, or string paths; children (NuxtPage[], not required) - nested child routes under this route for layout or view nesting.
extendPages example with custom page metadata
To augment NuxtPageMeta with custom metadata, declare a module in an index.d.ts file: declare module '@nuxt/schema' { interface NuxtPageMeta { requiresAuth?: boolean } } export {}. Then in modules, use extendPages to access the custom metadata fields which will be type-safe.
extendPages working example
import { createResolver, defineNuxtModule, extendPages } from '@nuxt/kit'
export default defineNuxtModule({
setup (options) {
const { resolve } = createResolver(import.meta.url)
extendPages((pages) => {
pages.unshift({
name: 'prismic-preview',
path: '/preview',
file: resolve('runtime/preview.vue'),
})
})
},
})
This example shows adding a new page to the pages configuration array.
extendRouteRules function signature
extendRouteRules is a function with signature: function extendRouteRules(route: string, rule: NitroRouteConfig, options?: ExtendRouteRulesOptions): void. It takes a route pattern string, a Nitro route configuration, and optional ExtendRouteRulesOptions to apply route rules.
extendRouteRules parameters
extendRouteRules accepts: route (string, required) - a route pattern to match against; rule (NitroRouteConfig, required) - a route rule configuration to apply to the matched route; options (ExtendRouteRulesOptions, not required) - an object with override property (boolean, default false) that when set to true will override the existing route configuration.
extendRouteRules working example
import { createResolver, defineNuxtModule, extendPages, extendRouteRules } from '@nuxt/kit'
export default defineNuxtModule({
setup (options) {
const { resolve } = createResolver(import.meta.url)
extendPages((pages) => {
pages.unshift({
name: 'preview-new',
path: '/preview-new',
file: resolve('runtime/preview.vue'),
})
})
extendRouteRules('/preview', {
redirect: {
to: '/preview-new',
status: 302,
},
})
extendRouteRules('/preview-new', {
cache: {
maxAge: 60 * 60 * 24 * 7,
},
})
},
})
This example shows adding pages and configuring route rules for redirects and caching.
addRouteMiddleware function signature
addRouteMiddleware is a function with signature: function addRouteMiddleware(input: NuxtMiddleware | NuxtMiddleware[], options?: AddRouteMiddlewareOptions): void. It registers route middlewares to be available for all routes or for specific routes.
addRouteMiddleware NuxtMiddleware properties
The NuxtMiddleware object has the following properties: name (string, required) - the name of the middleware; path (string, required) - the file path to the middleware; global (boolean, not required) - if set to true, applies middleware to all routes.
addRouteMiddleware options
addRouteMiddleware accepts an options parameter with properties: override (boolean, default false) - if true, replaces middleware with the same name; prepend (boolean, default false) - if true, prepends middleware before existing middlewares.
addRouteMiddleware working example
import { addRouteMiddleware, createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
const { resolve } = createResolver(import.meta.url)
addRouteMiddleware({
name: 'auth',
path: resolve('runtime/auth'),
global: true,
}, { prepend: true })
},
})
In runtime/auth.ts:
export default defineNuxtRouteMiddleware((to, from) => {
if (to.path !== '/login' && isAuthenticated() === false) {
return navigateTo('/login')
}
})
This example shows registering a global authentication middleware that runs before other middlewares.
composables directory auto-import setup
The app/composables/ directory automatically imports Vue composables into the application. Composables can be created using either named exports or default exports. Named exports use the exact function name as the import name. Default exports are imported using the camelCase version of the filename without extension (e.g., use-foo.ts becomes useFoo()).
composables named export example
export const useFoo = () => {
return useState('foo', () => 'bar')
}
composables default export example
export default function () {
return useState('foo', () => 'bar')
}
composables usage in components
Auto-imported composables can be used directly in .js, .ts, and .vue files without explicit imports. In a Vue component with script setup, simply call the composable function by name (e.g., const foo = useFoo()).
composables reactivity not directory-specific
The app/composables/ directory does not provide additional reactivity capabilities beyond Vue's Composition API. Reactivity in composables is achieved using Vue mechanisms like ref and reactive, which are not limited to the composables directory. Reactive code can be used anywhere in the application.
composables type generation with nuxt prepare
Nuxt auto-generates the file .nuxt/imports.d.ts to declare types for composables. The nuxt prepare, nuxt dev, or nuxt build commands must be run to generate these types. If a composable is created without the dev server running, TypeScript will throw an error like 'Cannot find name useBar'.
composables nested directory scanning
Nuxt only scans files at the top level of the app/composables/ directory. Nested files (e.g., app/composables/nested/utils.ts) are not automatically scanned. To enable auto-imports for nested modules, either re-export them from app/composables/index.ts or configure the scanner using the imports.dirs option in nuxt.config.ts.
composables file scanning paths
Only app/composables/index.ts and top-level files like app/composables/useFoo.ts are scanned for auto-imports. Files in nested directories like app/composables/nested/utils.ts are not scanned.
composables re-export pattern for nested files
To enable auto-import for composables in nested directories, re-export them from app/composables/index.ts. Example: export { utils } from './nested/utils.ts' enables auto import for the utils export.
composables scanner configuration
The imports.dirs option in nuxt.config.ts can be configured to scan nested composables directories. Examples include '~/composables' for top-level, '~/composables/*/index.{ts,js,mjs,mts}' for one level deep, and '~/composables/**' for all directories within composables.
nested composables usage
A composable can use another composable within it through auto-imports. For example, a useFoo composable can call useNuxtApp() and useBar() without explicit imports.
createUseFetch for custom fetchers
createUseFetch is used to create a custom fetcher composable for your API. It accepts configuration options including baseURL, onRequest, and onResponseError. The onRequest hook receives an object with options property containing headers that can be modified. The onResponseError hook receives an object with response property for handling error responses.
Custom useFetch example with auth and error handling
export const useAPI = createUseFetch({
baseURL: 'https://api.nuxt.com',
onRequest ({ options }) {
const { session } = useUserSession()
if (session.value?.token) {
options.headers.set('Authorization', `Bearer ${session.value.token}`)
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await navigateTo('/login')
}
},
})
This example shows creating a custom useFetch composable that adds JWT authentication headers and redirects to /login on 401 responses.
useAsyncData and useFetch composables example
Example of using useAsyncData and useFetch in Nuxt 3:
```vue
<script setup lang="ts">
const { data: post, refresh } = await useAsyncData('post', () => $fetch(`https://api.nuxtjs.dev/posts/${params.id}`))
// Or using useFetch
const { data: post, refresh } = await useFetch(`https://api.nuxtjs.dev/posts/${params.id}`)
</script>
```
Both return data and refresh, where data contains the fetched result and refresh updates the data.
watchQuery replacement with watcher example
Example of replacing watchQuery with a watcher in Nuxt 3:
```vue
<script setup lang="ts">
const route = useRoute()
const { data, refresh } = await useFetch('/api/user')
watch(() => route.query, () => refresh())
</script>
```