Release·  

Nuxt 4.4

Nuxt 4.4 — фабрики createUseFetch/createUseAsyncData, vue-router v5, доступность (useAnnouncer), типизированные пропсы лейаутов, профилирование сборки, умная работа с payload и многое другое.
Daniel Roe

Daniel Roe

@danielroe.dev

🏭 createUseFetch и createUseAsyncData

Теперь можно создавать собственные экземпляры useFetch и useAsyncData с нужными опциями по умолчанию (#32300).

composables/api.ts
// Простые значения по умолчанию
export const useClientFetch = createUseFetch({
  server: false,
})

// Динамические значения по умолчанию с полным контролем слияния
export const useApiFetch = createUseFetch((currentOptions) => {
  const runtimeConfig = useRuntimeConfig()

  return {
    ...currentOptions,
    baseURL: currentOptions.baseURL ?? runtimeConfig.public.baseApiUrl,
  }
})

Используйте их так же, как useFetch — с полной типизацией и теми же опциями:

pages/dashboard.vue
<script setup lang="ts">
// baseURL из runtimeConfig подставляется автоматически
const { data: users } = await useApiFetch('/users')
</script>

При передаче обычного объекта опции использования переопределяют значения по умолчанию. При передаче функции вы полностью управляете слиянием опций — можно комбинировать перехватчики, заголовки и другие сложные настройки.

Внутри за это отвечает новый ad-hoc модуль Nuxt: он сканирует папку composables и регистрирует ваши экземпляры для инъекции по ключу, поэтому они работают с SSR так же, как useAsyncData и useFetch.

Для того же подхода с useAsyncData есть createUseAsyncData.

Узнать больше Docs > API > Composables > Create Use Async Data.

🗺️ Vue Router v5

Мы перешли на vue-router v5 (#34181): зависимость от unplugin-vue-router больше не нужна. Это первое мажорное обновление vue-router со времён Nuxt 3, с множеством улучшений внутри.

Для большинства приложений миграция прозрачна. Если вы подключали unplugin-vue-router отдельно, его можно убрать из зависимостей.

Дальше планируем вывести типизированные маршруты из экспериментального статуса. 👀

💪 Типизированные пропсы лейаутов в definePageMeta

Теперь пропсы лейаутам можно передавать прямо из definePageMeta (#34262). Лейауты можно параметризовать для каждой страницы без provide/inject и обходных решений. Подробности — в обновлённой документации.

pages/dashboard.vue
definePageMeta({
  layout: {
    name: 'panel',
    props: {
      sidebar: true,
      title: 'Dashboard',
    },
  },
})

Пропсы полностью типизированы (#34409): при определении пропсов в лейауте в definePageMeta доступны автодополнение и проверка типов.

layouts/panel.vue
<script setup lang="ts">
defineProps<{
  sidebar?: boolean
  title?: string
}>()
</script>
Узнать больше Docs > Guide > Directory Structure > Layouts.

🗣️ Композабл useAnnouncer

Доступность усилена новым композаблом useAnnouncer и компонентом <NuxtAnnouncer> (#34318). useRouteAnnouncer объявляет смену страницы для скринридеров, а многим приложениям нужно объявлять динамические изменения на странице — отправку форм, состояния загрузки, результаты поиска и т.д.

<template>
  <NuxtAnnouncer />
  <NuxtRouteAnnouncer />
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
Это часть нашего дорожной карты по доступности. Использовать везде не обязательно: часто достаточно переноса фокуса на новый контент или нативной валидации форм. useAnnouncer особенно полезен, когда контент меняется динамически без смены фокуса.
Узнать больше Docs > API > Composables > Use Announcer.

🚀 Переход на unrouting

Генерация file-system маршрутов Nuxt перенесена на unrouting (#34316) с использованием trie для построения маршрутов. Холодный старт примерно тот же (~8 мс против ~6 мс для больших приложений), зато изменения в dev-сервере до 28× быстрее, когда страницы не добавляются и не удаляются, и примерно на 15% быстрее в остальных случаях.

Генерация маршрутов стала более детерминированной и больше не зависит от порядка файлов страниц.

🍫 Умная работа с payload для кэшированных маршрутов

При рендере кэшированного маршрута (ISR/SWR) с извлечением payload браузер сразу запрашивает _payload.json вторым запросом — и это запускает полный повторный SSR той же страницы. В serverless это может поднять вторую lambda до завершения стриминга первого ответа.

В этом релизе это учтено двумя изменениями (#34410):

  1. Режим payloadExtraction: 'client': полный payload встраивается в начальный HTML, при этом _payload.json по-прежнему генерируется для клиентской навигации.
  2. In-memory LRU кэш payload в рантайме, чтобы запросы _payload.json обслуживались без полного повторного рендера.
nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    payloadExtraction: 'client',
  },
})
payloadExtraction: 'client' станет значением по умолчанию при compatibilityVersion: 5. Кэш в рантайме действует для всех пользователей.
Узнать больше Docs > Guide > Going Further > Experimental Features#payloadextraction.

🍪 Опция refresh для useCookie

При использовании cookies для сессий часто нужно продлевать срок жизни без смены значения. Новая опция refresh решает это (#33814):

const session = useCookie('session-id', {
  maxAge: 60 * 60,
  refresh: true,
})

// Продлевает срок при каждом обращении, даже при том же значении
session.value = session.value
Узнать больше Docs > API > Composables > Use Cookie.

♻️ Сброс useState к начальному значению

useState и clearNuxtState теперь поддерживают сброс к начальному значению вместо очистки в undefined (#33527). Поведение согласовано с useAsyncData и удобнее для управления состоянием.

const count = useState('counter', () => 0)
count.value = 42

// Сброс в 0 (начальное значение), а не в undefined
clearNuxtState('counter')
Узнать больше Docs > API > Utils > Clear Nuxt State.

🕵️‍♂️ Улучшенная защита от импортов

По мотивам TanStack Start, защита от импортов теперь показывает подсказки и полный trace происхождения проблемного импорта (#34454). Так проще понять, почему server-only импорт оказался в клиентском бандле.

Например, при случайном импорте из server route в компоненте:

Trace показывает цепочку импортов (компонент импортирован со страницы), точную строку и конкретные рекомендации по исправлению.

Планируем и дальше улучшать сообщения об ошибках. 🪵

🔮 Типы view transitions

В экспериментальной поддержке view transitions Nuxt теперь можно задавать типы переходов (#31982). Так можно использовать разные переходы для разных сценариев навигации (вперёд/назад, вкладки и страницы и т.д.).

Узнать больше Docs > Getting Started > Transitions#view Transitions API Experimental.

💡 Улучшенные подсказки по optimizeDeps

Когда Vite находит новые зависимости в рантайме и перезагружает страницы, Nuxt теперь показывает готовый фрагмент для nuxt.config.ts, чтобы предсобрать их (#34320). При старте также выводятся предупреждения о неразрешаемых записях.

🏷️ Нормализованные имена компонентов страниц (экспериментально)

Новая экспериментальная опция приводит имена компонентов страниц в соответствие с именами маршрутов (#33513) — удобнее в devtools и при отладке.

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    normalizeComponentNames: true,
  },
})
Узнать больше Docs > Guide > Going Further > Experimental Features#normalizecomponentnames.

⚡ Профилирование сборки

Хотите понять, куда уходит время сборки? Теперь можно получить детальную разбивку по этапам сборки Nuxt (#34468, nuxt/cli#1243):

nuxt build --profile

В отчёте — длительность, изменение RSS и heap для каждой фазы сборки, модуля и плагина бандлера:

Профилируются и отдельные модули с плагинами бандлера, чтобы проще находить узкие места. Записываются три формата:

  • Chrome Trace (.nuxt/perf-trace.json) — открыть в chrome://tracing или Perfetto для временной шкалы
  • JSON-отчёт (.nuxt/perf-report.json) — машинно-читаемые данные для анализа во времени
  • CPU-профиль (nuxt-build.cpuprofile) — открыть в Chrome DevTools или VS Code для flame graph

Для ещё более детального вывода используйте --profile=verbose, чтобы печатать разбивку по времени в консоль.

Узнать больше Docs > API > Commands > Build.

Мы будем использовать эту возможность, чтобы делать Nuxt ещё быстрее — и если производительность вам важна, это хороший повод поучаствовать в разработке!

🔥 Улучшения производительности

  • Парсинг ID модулей до ~14 000× быстрее — цепочка new URL() + regex заменена на один indexOf + slice (#34451)
  • Отключён prefetch по видимости NuxtLink в dev — Vite больше не обнаруживает и не перезагружает зависимости без необходимости (#34325)

⬆︎ Обновление

Рекомендуем выполнить:

npx nuxt upgrade --dedupe

Команда дедуплицирует lockfile и поможет подтянуть обновления зависимостей Nuxt, в том числе из экосистемы unjs.

Смотрите руководство по обновлению, если обновляетесь со старой версии.

👉 Full Release Notes

Читать полный список изменений Nuxt v4.4.0.

Спасибо всем, кто участвовал в этом релизе! 💚

← Вернуться в блог
Nuxt on LinkedInNuxt on BlueskyNuxt on X