Nuxt core packages architecture
Nuxt is composed of core packages: nuxt (core engine), @nuxt/vite-builder, @nuxt/rspack-builder, @nuxt/webpack-builder (bundlers), @nuxt/cli (command line interface), nitro (server engine), and @nuxt/kit (development kit).
render:html hook example
Example of extending the HTML template using the render:html hook:
```ts
[server/plugins/extend-html.ts]
import { definePlugin } from 'nitro'
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
// This will be an object representation of the html template.
console.log(html)
html.head.push(`<meta name="description" content="My custom description" />`)
})
// You can also intercept the response here.
nitroApp.hooks.hook('render:response', (response, { event }) => { console.log(response) })
})
```
Extend HTML template with Nitro plugin
You can have full control over the HTML template by adding a Nitro plugin that registers a hook. The render:html hook allows you to mutate the HTML before it is sent to the client.
Single layout recommendation
If you only have a single layout in your application, use app.vue with <NuxtPage /> instead of the layouts system.
Layout example with header and footer
A typical layout structure with header and footer:
```vue
[app/layouts/default.vue]
<template>
<div>
<AppHeader />
<slot />
<AppFooter />
</div>
</template>
```
NuxtLayout component usage
Use the <NuxtLayout> component in app.vue to wrap <NuxtPage /> and apply layouts to pages:
```vue
[app/app.vue]
<template>
<div>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>
```
Modifying head section with hooks
The render:html hook provides an object representation of the HTML template where you can push elements to html.head to add meta tags and other head elements.
Layouts wrap pages with common UI
Layouts are wrapper components around pages that contain common UI elements like headers and footers. They use <slot /> to display page content.
Nuxt creates Vue app automatically
Nuxt handles the creation of the Vue app behind the scenes, so you do not need a main.js file to initialize your application.
app.vue example
A basic app.vue file structure:
```vue
<template>
<div>
<h1>Welcome to the homepage</h1>
</div>
</template>
```
app.vue is the entry point
By default, Nuxt treats the app.vue file as the entry point of the application and renders its content for every route.
Default layout file
The app/layouts/default.vue file is used as the default layout for all pages. Custom layouts can be set as part of page metadata.
Full layer priority example with extends
When using extends with local layers in ~/layers, the complete priority order is: your project files (highest), ~~/layers/custom, ../base, @my-themes/awesome, github:my-themes/awesome#v1 (lowest). Project files always have highest priority, then auto-scanned layers, then extends entries in order.
Layers feature overview
Nuxt layers allow you to extend the default Nuxt application to reuse components, utils, and configuration. The layers structure is almost identical to a standard Nuxt application, making them easy to author and maintain.
Layer use cases
Layers can be used to: share reusable configuration presets using nuxt.config and app.config; create a component library using app/components/; create utility and composable libraries using app/composables/ and app/utils/; create Nuxt module presets; share standard setup across projects; create Nuxt themes; and enhance code organization through modular architecture and Domain-Driven Design patterns.
Auto-registration of layers in layers directory
By default, any layers within your project in the ~~/layers directory will be automatically registered as layers. This feature was introduced in Nuxt v3.12.0.
Named layer aliases creation
Named layer aliases to the srcDir of each layer are automatically created. For example, the ~~/layers/test layer can be accessed via #layers/test. This feature was introduced in Nuxt v3.16.0.
Layer extending tools
Nuxt uses unjs/c12 and unjs/giget for extending remote layers. These libraries provide the underlying functionality for configuration merging and git repository cloning.
Layer priority order from highest to lowest
Layer priority order is: (1) Your project files have the highest priority, (2) Auto-scanned layers from ~~/layers directory sorted alphabetically with Z having higher priority than A, (3) Layers in extends config with first entry having higher priority than second.
Controlling layer priority with numeric prefixes
You can prefix layer directories with numbers to control the override order. For example, 1.base/ has lowest priority, 2.features/ has medium priority, and 3.admin/ has highest priority among layers. Higher numbers mean higher priority.
When to use layers directory vs extends
Use the ~~/layers directory for local layers that are part of your project. Use extends for external dependencies like npm packages, remote repositories, or layers outside your project directory.
Virtual File System for modules
Nuxt provides a Virtual File System (VFS) that allows modules to add templates to the .nuxt directory without writing them to disk.
Nuxt is powered by Nitro server engine
Nuxt uses Nitro, a modern server engine, to power its server-side functionality.
Browser executes full Vue lifecycle after mounting
Unlike on the server, the browser executes the full Vue lifecycle after the Vue application is mounted.
Provide helpers to all composables using nuxtApp.provide()
You can provide helpers to be usable across all composables and the application using nuxtApp.provide(key, value). This typically happens within a Nuxt plugin. Provided helpers are accessible via nuxtApp.$key.
Plugins receive nuxtApp as first argument
Plugins automatically receive nuxtApp as the first argument for convenience, without needing to call useNuxtApp().
Run code within Nuxt context using nuxtApp.runWithContext
To explicitly call functions within the Nuxt context outside the normally accessible locations, use nuxtApp.runWithContext().
Nuxt context accessibility locations
The Nuxt context is only accessible in plugins, Nuxt hooks, Nuxt middleware (if wrapped in defineNuxtRouteMiddleware), and setup functions (in pages and components).
Use tryUseNuxtApp() to safely check for NuxtApp
If a composable does not always need nuxtApp or you want to check if it is present without throwing an exception, use tryUseNuxtApp() instead of useNuxtApp(), which throws an exception if the context is not available.
Access NuxtApp with useNuxtApp() composable
Within composables, plugins and components you can access the NuxtApp instance using the useNuxtApp() composable. This gives you access to the runtime Nuxt app instance.
Fresh NuxtApp instance created per request
A fresh instance of the Nuxt context is created on every request, so the context does not persist across requests.
Alternative way to provide helpers in plugins
Plugins can provide helpers by returning an object with a 'provide' key, which is an alternative to using nuxtApp.provide() directly.