Пререндеринг
Nuxt может отрендерить часть страниц при сборке. По запросу будут отдаваться уже готовые страницы, а не генерироваться на лету.
Пререндеринг по обходу ссылок
Команда nuxt generate собирает приложение и пререндерит его с помощью краулера Nitro. По смыслу это то же, что nuxt build с nitro.static: true или nuxt build --prerender.
Собирается сайт, поднимается экземпляр Nuxt, по умолчанию пререндериваются корневая страница / и все страницы, на которые с неё есть ссылки, затем страницы, на которые ссылаются они, и т.д.
npx nuxt generate
yarn nuxt generate
pnpm nuxt generate
bun x nuxt generate
deno x nuxt generate
Директорию .output/public можно развернуть на любом статическом хостинге или посмотреть локально: npx serve .output/public.
Статические и пререндеренные сборки также создают SPA fallback-файлы 200.html и 404.html. Подробнее: Что такое 200.html и 404.html?.
Как работает краулер Nitro:
- Загружается HTML корневого маршрута (
/), всех нединамических страниц из~/pagesи маршрутов изnitro.prerender.routes. - HTML и
_payload.jsonсохраняются в~/.output/public/для статической раздачи. - В HTML ищутся все ссылки (
<a href="...">) для перехода на другие маршруты. - Шаги 1–3 повторяются для каждой найденной ссылки, пока нечего обходить.
Страницы, на которые нет ссылок с обходимых страниц, автоматически пререндерены не будут.
Выборочный пререндеринг
Маршруты для пререндеринга и исключения можно задать в nuxt.config:
// @errors: 2353
export default defineNuxtConfig({
nitro: {
prerender: {
routes: ['/user/1', '/user/2'],
ignore: ['/dynamic'],
},
},
})
В сочетании с crawlLinks: true можно добавить маршруты, которые краулер сам не найдёт (например /sitemap.xml, /robots.txt):
// @errors: 2353
export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true,
routes: ['/sitemap.xml', '/robots.txt'],
},
},
})
Установка nitro.prerender в true эквивалентна nitro.prerender.crawlLinks: true.
То же можно задать через routeRules:
export default defineNuxtConfig({
routeRules: {
'/rss.xml': { prerender: true },
'/this-DOES-NOT-get-prerendered': { prerender: false },
'/blog/**': { prerender: true },
},
})
Краткая форма в файле страницы — defineRouteRules.
<script setup>
defineRouteRules({
prerender: true,
})
</script>
<template>
<div>
<h1>Homepage</h1>
<p>Pre-rendered at build time</p>
</div>
</template>
Это преобразуется в:
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
},
})
Извлечение payload
Когда Nuxt рендерит страницу на сервере, он сериализует результаты загрузки данных (useAsyncData и useFetch) и состояние приложения (useState) в payload, чтобы клиент мог выполнить гидрацию без повторных запросов. При включённом извлечении payload Nuxt также записывает его в файл _payload.json рядом с HTML маршрута:
- Пререндеренные маршруты создают файл payload при сборке.
- Маршруты с кэшированием ISR или SWR создают файл payload при первом рендере, даже на гибридном (не полностью статическом) сайте.
При клиентской навигации Nuxt загружает _payload.json для целевого маршрута и переиспользует извлечённые данные вместо повторного выполнения загрузки в браузере.
Поведение настраивается опцией experimental.payloadExtraction:
'client'— payload встраивается в HTML при первом рендере и извлекается в файлы_payload.jsonдля клиентской навигации. Дополнительного сетевого запроса при первой загрузке нет.true— payload выносится в отдельный_payload.jsonи при первом рендере, и при клиентской навигации. HTML меньше, файл payload можно кэшировать на CDN, но при первой загрузке добавляется один запрос.false— извлечение payload отключено. Payload всегда встраивается в HTML, файлы_payload.jsonне создаются.
По умолчанию: true, или 'client' при compatibilityVersion: 5. Принудительно false при ssr: false.
export default defineNuxtConfig({
experimental: {
payloadExtraction: 'client',
},
})
Практические последствия:
- На полностью статическом сайте клиентская навигация переиспользует данные, захваченные при сборке, поэтому они могут устареть до следующей пересборки.
- Для маршрутов ISR/SWR CDN может кэшировать файлы payload вместе с HTML, улучшая производительность клиентской навигации для закэшированных маршрутов. Динамические маршруты вроде
pages/[...slug].vueможно подключить glob-паттернами, например'/**': { isr: true }. - Payload сериализуется через devalue, поэтому пользовательские типы (например, экземпляры классов) требуют payload-плагинов с reducers и revivers, чтобы пережить цикл сериализация–десериализация.
Конфигурация пререндеринга в рантайме
prerenderRoutes
В контексте Nuxt можно добавлять маршруты для пререндеринга:
<script setup>
prerenderRoutes(['/some/other/url'])
prerenderRoutes('/api/content/article/my-article')
</script>
<template>
<div>
<h1>This will register other routes for prerendering when prerendered</h1>
</div>
</template>
Хук Nuxt prerender:routes
Вызывается перед пререндерингом для регистрации дополнительных маршрутов:
export default defineNuxtConfig({
hooks: {
async 'prerender:routes' (ctx) {
const { pages } = await fetch('https://api.some-cms.com/pages').then(
res => res.json(),
)
for (const page of pages) {
ctx.routes.add(`/${page.name}`)
}
},
},
})
Хук Nitro prerender:generate
Вызывается для каждого маршрута при пререндеринге — можно точечно решать, пропускать ли маршрут:
export default defineNuxtConfig({
nitro: {
hooks: {
'prerender:generate' (route) {
if (route.route?.includes('private')) {
route.skip = true
}
},
},
},
})