Next.js 13.3 добавляет популярные функции, запрошенные сообществом, включая:
- File-Based Metadata API: Динамическое создание карт сайта, robots.txt, фавиконов и других метаданных.
- Динамические Open Graph изображения: Генерация OG-изображений с использованием JSX, HTML и CSS.
- Статический экспорт для App Router: Поддержка статических сайтов и SPA (Single-Page Applications) для Server Components.
- Параллельные маршруты и перехват: Расширенные возможности маршрутизации для App Router.
Обновитесь сегодня, выполнив:
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
Мы приближаемся к тому, чтобы объявить App Router стабильным в следующем минорном релизе, и сосредотачиваемся на оптимизации производительности, улучшении поведения и исправлении ошибок.
Хотя мы всё ещё работаем над некоторыми функциями, такими как Mutations, мы не ожидаем, что они повлияют на API других функций App Router. Мы с нетерпением ждём, что вы построите с помощью App Router, и рады вашим отзывам.
File-Based Metadata API
В Next.js 13.2 мы представили новый Metadata API, позволяющий определять метаданные (например, теги title
, meta
и link
внутри HTML-элемента head
) путём экспорта объекта Metadata из layout или страницы.
// Статические метаданные
export const metadata = {
title: 'Home',
};
// Результат:
// <head>
// <title>Home</title>
// </head>
// Или динамические метаданные
export async function generateMetadata({ params, searchParams }) {
const product = await getProduct(params.id);
return { title: product.title };
}
// Результат:
// <head>
// <title>My Unique Product</title>
// </head>
export default function Page() {}
В дополнение к конфигурационным метаданным, Metadata API теперь поддерживает новые файловые соглашения, позволяя удобно настраивать страницы для улучшения SEO и публикации в интернете:
opengraph-image.(jpg|png|svg)
twitter-image.(jpg|png|svg)
favicon.ico
icon.(ico|jpg|png|svg)
sitemap.(xml|js|jsx|ts|tsx)
robots.(txt|js|jsx|ts|tsx)
manifest.(json|js|jsx|ts|tsx)
Например, вы можете использовать файловые метаданные для добавления фавикона вашего приложения и Open Graph изображения для страницы /about
:
app
├── favicon.ico
├── layout.js
├── page.js
└── about
├── opengraph-image.jpg
└── page.js
Next.js автоматически обслуживает эти файлы с хешами (для имени файла) в продакшене для кэширования и обновляет соответствующие элементы head
с правильной информацией о метаданных, такой как URL ресурса, тип файла и размер изображения.
// При посещении "/"
<link rel="icon" href="<computedUrl>"/>
// При посещении "/about"
<link rel="icon" href="<computedUrl>"/>
<meta property="og:image" content="<computedUrl>" type="<computedType>" ... />
Добавление статических файлов в ваше приложение часто является самым простым подходом, но бывают случаи, когда вам может понадобиться создавать файлы динамически. Для каждого статического файлового соглашения существует соответствующий динамический вариант (.js|.jsx|.ts|.tsx)
, позволяющий писать код для генерации файла.
Например, хотя вы можете добавить статический файл sitemap.xml
, большинство сайтов имеют страницы, которые динамически генерируются с использованием внешнего источника данных. Чтобы создать динамическую карту сайта, вы можете добавить файл sitemap.js
, возвращающий массив ваших динамических маршрутов.
export default async function sitemap() {
const res = await fetch('https://.../posts');
const allPosts = await res.json();
const posts = allPosts.map((post) => ({
url: `https://acme.com/blog/${post.slug}`,
lastModified: post.publishedAt,
}));
const routes = ['', '/about', '/blog'].map((route) => ({
url: `https://acme.com${route}`,
lastModified: new Date().toISOString(),
}));
return [...routes, ...posts];
}
С конфигурационными и новыми файловыми опциями у вас теперь есть комплексный Metadata API, охватывающий как статические, так и динамические метаданные.
Metadata API доступен в 13.3 для App Router (app
). Он не доступен в директории pages
. Узнайте больше о файловых метаданных и просмотрите API reference.
Динамическая генерация Open Graph изображений
Шесть месяцев назад мы выпустили @vercel/og и Satori, библиотеки, позволяющие динамически генерировать изображения с использованием JSX, HTML и CSS.
@vercel/og
прошёл проверку на Next.js Conf, сгенерировав более 100,000 динамических изображений билетов для каждого участника. Благодаря широкому внедрению среди клиентов Vercel и более 900,000 загрузок с момента релиза, мы рады представить динамически генерируемые изображения для всех приложений Next.js без необходимости во внешнем пакете.
Теперь вы можете импортировать ImageResponse
из next/server
для генерации изображений:
import { ImageResponse } from 'next/server';
export const size = { width: 1200, height: 600 };
export const alt = 'About Acme';
export const contentType = 'image/png';
export const runtime = 'edge';
export default function og() {
return new ImageResponse();
// ...
}
ImageResponse
естественно интегрируется с другими API Next.js, включая Route Handlers и файловые метаданные. Например, вы можете использовать ImageResponse
в файле opengraph-image.tsx
для генерации Open Graph и Twitter изображений во время сборки или динамически во время запроса.
Узнайте больше о Image Response API.
Статический экспорт для App Router
App Router Next.js теперь поддерживает полностью статический экспорт.
Вы можете начать со статического сайта или SPA (Single-Page Application), а затем при необходимости перейти к использованию функций Next.js, требующих сервера.
При запуске next build
Next.js генерирует HTML-файл для каждого маршрута. Разбивая строгое SPA на отдельные HTML-файлы, Next.js может избежать загрузки ненужного JavaScript-кода на стороне клиента, уменьшая размер бандла и обеспечивая более быструю загрузку страниц.
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
output: 'export',
};
module.exports = nextConfig;
Статический экспорт работает с новыми функциями app
router, включая статические Route Handlers, Open Graph изображения и React Server Components.
Например, Server Components будут выполняться во время сборки, аналогично традиционной генерации статических сайтов, рендеря компоненты в статический HTML для начальной загрузки страницы и статический payload для клиентской навигации между маршрутами.
Ранее для использования статического экспорта в директории pages
требовалось выполнить next export
. Однако с опцией next.config.js
next build
будет выводить директорию out
, когда установлено output: 'export'
. Вы можете использовать ту же конфигурацию для app
router и директории pages
. Это означает, что next export
больше не требуется.
С расширенной поддержкой статического экспорта вы будете получать ошибки раньше в процессе разработки (next dev
), например, при попытке использовать динамическую функцию, требующую сервера, такую как cookies()
или headers()
.
Узнайте больше о Статическом экспорте.
Параллельные маршруты и перехват
Next.js 13.3 представляет новые динамические соглашения, позволяющие реализовать сложные случаи маршрутизации: Параллельные маршруты и Перехватывающие маршруты. Эти функции позволяют показывать более одной страницы в одном представлении, как в сложных дашбордах или модальных окнах.
С Параллельными маршрутами вы можете одновременно отображать одну или несколько страниц в одном представлении, которые могут навигироваться независимо. Это также можно использовать для условного рендеринга страниц.
Параллельные маршруты создаются с использованием именованных "слотов". Слоты определяются с соглашением @folder
:
dashboard
├── @user
│ └── page.js
├── @team
│ └── page.js
├── layout.js
└── page.js
Layout в том же сегменте маршрута принимает слоты как пропсы:
export default async function Layout({ children, user, team }) {
const userType = getCurrentUserType();
return (
<>
{userType === 'user' ? user : team}
{children}
</>
);
}
В примере выше слоты параллельных маршрутов @user
и @team
(явные) рендерятся условно на основе вашей логики. children
является неявным слотом маршрута, который не нужно сопоставлять с @folder
. Например, dashboard/page.js
эквивалентен dashboard/@children/page.js
.
Перехватывающие маршруты позволяют загружать новый маршрут в текущем layout, "маскируя" URL браузера. Это полезно, когда важно сохранить контекст текущей страницы, например, развернуть фотографию в ленте через модальное окно, где лента остаётся на фоне модального окна.
Перехватывающие маршруты могут быть определены с соглашением (..)
, аналогично относительным путям ../
. Вы также можете использовать соглашение (...)
для создания пути относительно директории app
.
feed
├── @modal
│ └── (..)photo
│ └── [id]
│ └── page.tsx
├── page.tsx
└── layout.tsx
photo
└── [id]
└── page.tsx
В примере выше клик по фотографии из профиля пользователя откроет фотографию в модальном окне во время клиентской навигации. Однако обновление или совместное использование страницы загрузит фотографию с её стандартным layout.
Параллельные маршруты и перехват позволяют реализовать модальную маршрутизацию, как в Instagram.
Это решает проблемы, с которыми вы можете столкнуться при создании модальных окон, такие как возможность совместного использования содержимого модального окна через URL, предотвращение потери контекста при обновлении страницы и закрытие и повторное открытие модального окна с навигацией назад и вперёд.
Для дополнительных примеров и поведения см. документацию по Параллельным и Перехватывающим маршрутам.
Другие улучшения
- Обновления дизайна: Главная страница Next.js и галерея были обновлены новым дизайном.
- Turbopack: Добавлена поддержка Middleware, всех опций
next/font
и стриминга с Server Components по мере приближения к бета-версии (см. демо). Мы также исправили дополнительные ошибки, обнаруженные при тестировании на зрелых приложениях Next.js, таких как vercel.com и nextjs.org. Узнайте больше. - Fast Refresh для
next.config.js
: Изменения вnext.config.js
теперь автоматически перезапускают локальный сервер разработки. Это расширяет автоматическую перезагрузку конфигурационных файлов.env
,.env.*
,jsconfig.json
,tsconfig.json
. - Доступность: App Router теперь включает объявление маршрута из
pages
. Эта функция объявляет переходы между маршрутами на стороне клиента для скринридеров и других вспомогательных технологий. Узнайте больше. - Статически типизированные ссылки:
redirects
иrewrites
, установленные вnext.config.js
, теперь учитываются при проверке типов. Узнайте больше. - Tailwind CSS для
create-next-app
: При создании нового проекта сnpx create-next-app@latest
вы теперь можете опционально выбрать Tailwind CSS или использовать флаг--tailwind
, чтобы предварительно настроить ваше приложение с этим стилевым решением. - Route Handlers: Использование
export default
вместо поддерживаемого HTTP-глагола теперь вызывает полезную ошибку сroute.ts
. Узнайте больше о Route Handlers. - Изображения:
next/image
теперь поддерживает атрибутfetchPriority="high"
. - Метаданные: Предыдущий API для метаданных (
head.js
), устаревший в 13.2, был удалён. Вместо этого используйте встроенную поддержку SEO через Metadata API. - Исключение папок из маршрутизации: Префикс
_
для папки исключает её и все дочерние сегменты из маршрутизации. Например,app/_dashboard/page.tsx
не будет доступен для маршрутизации. - App Router: Мы добавили новый хук
useParams
для клиентских компонентов, чтобы читать динамические параметры для данного сегмента маршрута. Узнайте больше. - Улучшенная загрузка стилей: Next.js теперь реализует Suspensey CSS от React, что исправляет многие проблемы с загрузкой CSS и мерцанием нестилизованного контента, особенно во время навигации.
- Улучшенная обработка Not Found: В дополнение к перехвату ожидаемых ошибок
notFound()
, корневой файлapp/not-found.js
также будет обрабатывать любые URL, не обрабатываемые вашим приложением. Это означает, что пользователи, посещающие URL, не обрабатываемый вашим приложением, увидят UI, экспортированный файломapp/not-found.js
. Узнайте больше. - Улучшенный кэш клиентского роутера:
router.refresh()
теперь инвалидирует весь кэш, а параметры поиска теперь являются частью ключа кэша, позволяя навигацию между двумя параметрами поиска (например,/?search=leerob
и/?search=tim
) корректно восстанавливать контент, зависящий от параметра.
Сообщество
Next.js — это результат совместной работы более 2,600 индивидуальных разработчиков, отраслевых партнёров, таких как Google и Meta, и нашей основной команды в Vercel. С более чем 4.2 миллионами загрузок npm в неделю и 104,000+ звёзд на GitHub, Next.js является одним из самых популярных способов создания веб-приложений.
Присоединяйтесь к сообществу на GitHub Discussions, Reddit и Discord.
Этот релиз стал возможен благодаря:
- Команде Next.js: Andrew, Balazs, Hannes, Jan, Jiachi, Jimmy, JJ, Josh, Sebastian, Shu, Steven, Tim, и Wyatt.
- Команде Turbopack: Alex, Donny, Justin, Leah, LongYinan, Maia, OJ, Tobias, и Will.
А также вкладу: @shuding, @huozhi, @sokra, @hanneslund, @JesseKoldewijn, @kaguya3222, @yangshun, @ijjk, @konomae, @Brooooooklyn, @jridgewell, @zlrlyy, @JohnDaly, @abhiyandhakal, @benjie, @johnnyomair, @nk980113, @dirheimerb, @DerTimonius, @DuCanhGH, @padmaia, @stafyniaksacha, @Gladowar, @zek, @jankaifer, @styfle, @balazsorban44, @wbinnssmith, @chibicode, @ForsakenHarmony, @franktronics, @FSaldanha, @Schniz, @raisedadead, @AdamKatzDev, @wyattjoh, @leerob, @meesvandongen, @vladikoff, @feedthejim, @tka5, @pyjun01, @gdborton, @M3kH, @aretrace, @shivanshubisht, @alexkirsz, @agrattan0820, @vinaykulk621, @heyitsuzair, @mrkldshv, @timneutkens, @furkanmavili, @swaminator, @EndangeredMassa, @DevEsteves, @rishabhpoddar, @schehata, @molebox, @dlehmhus, @akshaynox, @sp00ls, @janicklas-ralph, @tomryanx, @kwonoj, @karlhorky, @kdy1, @dante-robinson, @lachlanjc, @ianmacartney, @hotters, @isaackatayev, @insik-han, @jayair, @ivanhofer, @javivelasco, @SukkaW, @visshaljagtap, @imranbarbhuiya, @nivak-monarch, @HarshaVardhanReddyDuvvuru, @ianldgs, @ricardofiorani, @swarnava, и @gustavostz.