🧩 Что это
Этот skill — набор проверенных паттернов и оптимизаций для Nuxt 4 (и Nuxt 3 с оглядкой на 4). Он помогает разработчикам избегать типичных ошибок при SSR, управлять гидратацией, эффективно загружать данные, настраивать рендеринг на уровне маршрутов и оптимизировать производительность. Skill пригодится, когда вы сталкиваетесь с несоответствием HTML на сервере и клиенте, хотите внедрить ISR/SWR, ленивую загрузку или отложенную гидратацию компонентов.
⚙️ Как работает
🔒 Гидратационная безопасность (Hydration Safety)
Главное правило: сервер и клиент должны сгенерировать одинаковый HTML при первом рендере. Если этого не происходит — получаем ошибки гидратации.
- Не используйте в шаблонах, рендерящихся на сервере,
Date.now(), Math.random(), браузерные API (localStorage, window) или чтение из хранилищ. Они дадут разный результат на сервере и клиенте.
- Выносите клиентский код в
onMounted(), import.meta.client, оборачивайте в ClientOnly или используйте суффикс .client.vue.
- Используйте
useRoute() от Nuxt, а не от vue-router.
- Не полагайтесь на
route.fullPath в SSR-разметке — фрагмент URL (#hash) доступен только на клиенте.
ssr: false — крайняя мера для страниц, которые вообще не должны рендериться на сервере, а не способ «починить» гидратацию.
📡 Получение данных (Data Fetching)
useFetch() — основной инструмент для SSR-безопасного получения данных на страницах и в компонентах. Он автоматически передаёт результат с сервера в Nuxt payload, избегая повторного запроса на клиенте.
useAsyncData() — когда нужна кастомная логика (не просто $fetch), свой ключ кеша или объединение нескольких источников. Всегда передавайте стабильный ключ (первый аргумент).
$fetch() — для пользовательских действий (POST, PUT) или клиентских операций, не для данных, которые должны прийти с SSR.
- Ленивая загрузка:
lazy: true, useLazyFetch(), useLazyAsyncData() — для некритичных данных. Обрабатывайте status === 'pending' в UI.
server: false — только если данные не нужны для SEO и первого отображения.
pick — сокращайте размер payload, выбирая только нужные поля.
Пример типичного паттерна:
const route = useRoute()
const { data: article, status, error, refresh } = await useAsyncData(
() => `article:${route.params.slug}`,
() => $fetch(`/api/articles/${route.params.slug}`)
)
const { data: comments } = await useFetch(
`/api/articles/${route.params.slug}/comments`,
{ lazy: true, server: false }
)
🗺️ Правила маршрутов (Route Rules)
В nuxt.config.ts задаются стратегии рендеринга для групп маршрутов:
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/products/**': { swr: 3600 },
'/blog/**': { isr: true },
'/admin/**': { ssr: false },
'/api/**': { cache: { maxAge: 60 * 60 } }
}
})
prerender — статический HTML на этапе сборки.
swr — отдавать кеш, фоном обновлять.
isr — инкрементальная статическая регенерация (на поддерживаемых платформах).
ssr: false — чисто клиентский рендеринг.
cache / redirect — низкоуровневые опции Nitro.
🐌 Ленивая загрузка и производительность
- Nuxt уже делает code-splitting по маршрутам. Не дробите компоненты без нужды.
- Используйте Lazy-префикс для динамического импорта неключевых компонентов:
<LazyHeavyWidget />.
- Комбинируйте с
v-if, чтобы код загружался только когда компонент действительно нужен.
- Отложенная гидратация (deferred hydration):
<LazyProductGallery hydrate-on-visible /> — компонент гидратируется только когда появляется в области видимости.
- Для кастомных стратегий —
defineLazyHydrationComponent() с триггерами visible или idle.
- Используйте
NuxtLink для внутренних переходов — Nuxt предзагрузит компоненты и payload.
✅ Когда использовать
- Гидратационные ошибки — несоответствие серверного и клиентского HTML.
- Разные стратегии рендеринга — часть страниц статическая, часть динамическая, часть только на клиенте.
- Оптимизация производительности — большие компоненты ниже сгиба экрана, тяжёлые виджеты, комментарии, графики.
- Работа с данными — нужно получать данные на сервере и избегать двойных запросов.
- Настройка кеширования — для API или страниц с разной свежестью.
⚠️ Важно знать
- Ключи
useAsyncData должны быть стабильными (строки или функции, возвращающие строку). Иначе кеш не работает, и данные будут перезапрашиваться.
- Побочные эффекты в обработчиках
useAsyncData недопустимы — они могут выполняться и на сервере, и на клиенте.
hydrate-on-visible и другие директивы отложенной гидратации работают только в Nuxt 4 (или с экспериментальным флагом в Nuxt 3).
- Route Rules применяются по принципу «первое совпадение» — порядок в конфиге важен.
- Проверочный список перед деплоем: одинаковый HTML, данные через
useFetch/useAsyncData, ленивые данные с UI загрузки, корректные routeRules, тяжёлые компоненты ленивые или отложенные.
Комментарии
Комментариев пока нет. Будьте первым.