Как мы анонсировали на Next.js Conf, Next.js 13 (стабильная версия) закладывает основы для динамичности без ограничений:
- Директория
app
(бета): Проще, быстрее, меньше клиентского JS. - Turbopack (альфа): До 700x быстрее, замена Webpack на основе Rust.
- Новый
next/image
: Быстрее с нативной ленивой загрузкой в браузере. - Новый
@next/font
(бета): Автоматическое самохостинг шрифтов без сдвигов макета. - Улучшенный
next/link
: Упрощенный API с автоматическим<a>
.
Next.js 13 и директория pages
стабильны и готовы к продакшену. Обновитесь сегодня, выполнив:
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
Новая директория app
(Бета)
Сегодня мы улучшаем опыт работы с маршрутизацией и макетами в Next.js, согласуясь с будущим React, представляя директорию app
. Это продолжение RFC по макетам, ранее опубликованного для обратной связи сообщества.
Директория app
сейчас находится в бета-версии, и мы не рекомендуем использовать её в продакшене. Вы можете использовать Next.js 13 с директорией pages
и стабильными функциями, такими как улучшенные компоненты next/image
и next/link
, и переходить на директорию app
в своем темпе. Директория pages
будет поддерживаться в обозримом будущем.
Директория app
включает поддержку:
- Макетов: Легко делитесь UI между маршрутами, сохраняя состояние и избегая дорогостоящих перерисовок.
- Серверных компонентов: Сделано сервер-ориентированным по умолчанию для самых динамичных приложений.
- Потоковой передачи: Отображайте мгновенные состояния загрузки и получайте UI по мере его рендеринга.
- Поддержки загрузки данных:
async
серверные компоненты и расширенный APIfetch
позволяют загружать данные на уровне компонентов.
Директорию app можно внедрять постепенно из существующей директории pages/.
Макеты
Директория app/
упрощает создание сложных интерфейсов, которые сохраняют состояние между переходами, избегают дорогостоящих перерисовок и поддерживают продвинутые паттерны маршрутизации. Более того, вы можете вкладывать макеты и располагать код приложения рядом с маршрутами, например, компоненты, тесты и стили.
Директорию app/ можно внедрять постепенно из существующей директории pages/.
Создание маршрутов внутри app/
требует одного файла page.js
:
// Этот файл соответствует корневому маршруту (/)
export default function Page() {
return <h1>Привет, Next.js!</h1>;
}
Затем вы можете определять макеты через файловую систему. Макеты позволяют делиться UI между несколькими страницами. При навигации макеты сохраняют состояние, остаются интерактивными и не перерисовываются.
export default function BlogLayout({ children }) {
return <section>{children}</section>;
}
Узнайте больше о макетах и страницах или разверните пример, чтобы попробовать.
Серверные компоненты
Директория app/
вводит поддержку новой архитектуры серверных компонентов React. Серверные и клиентские компоненты используют сервер и клиент для того, что у них получается лучше всего — позволяя вам создавать быстрые, высокоинтерактивные приложения с единой моделью программирования, обеспечивающей отличный опыт разработки.
С серверными компонентами мы закладываем основы для создания сложных интерфейсов, уменьшая количество JavaScript, отправляемого клиенту, что ускоряет первоначальную загрузку страниц.
При загрузке маршрута загружаются рантайм Next.js и React, который кешируется и имеет предсказуемый размер. Этот рантайм не увеличивается в размере по мере роста вашего приложения. Более того, рантайм загружается асинхронно, позволяя постепенно улучшать HTML с сервера на клиенте.
Узнайте больше о серверных компонентах или разверните пример, чтобы попробовать.
Потоковая передача
Директория app/
вводит возможность прогрессивного рендеринга и инкрементальной потоковой передачи отрендеренных частей UI клиенту.
С серверными компонентами и вложенными макетами в Next.js вы можете мгновенно отображать части страницы, которые не требуют данных, и показывать состояние загрузки для частей, которые загружают данные. При таком подходе пользователю не нужно ждать полной загрузки страницы, чтобы начать взаимодействовать с ней.
Вы можете располагать код приложения, такой как компоненты, тесты и стили, рядом с маршрутами.
При развертывании на Vercel приложения Next.js 13, использующие директорию app/
, будут по умолчанию использовать потоковую передачу ответов как в Node.js, так и в Edge рантаймах для улучшения производительности.
Узнайте больше о потоковой передаче или разверните пример, чтобы попробовать.
Загрузка данных
Недавний RFC React Поддержка промисов представляет мощный новый способ загрузки данных и обработки промисов внутри компонентов:
async function getData() {
const res = await fetch('https://api.example.com/...');
// Возвращаемое значение *не* сериализуется
// Можно возвращать Date, Map, Set и т.д.
return res.json();
}
// Это асинхронный серверный компонент
export default async function Page() {
const data = await getData();
return <main>{/* ... */}</main>;
}
Нативный Web API fetch
также был расширен в React и Next.js. Он автоматически устраняет дублирование запросов fetch и предоставляет единый гибкий способ загрузки, кеширования и ревалидации данных на уровне компонента. Это означает, что все преимущества Static Site Generation (SSG), Server-Side Rendering (SSR) и Incremental Static Regeneration (ISR) теперь доступны через один API:
// Этот запрос должен кешироваться до ручной инвалидации.
// Аналогично `getStaticProps`.
// `force-cache` используется по умолчанию и может быть опущен.
fetch(URL, { cache: 'force-cache' });
// Этот запрос должен повторяться при каждом запросе.
// Аналогично `getServerSideProps`.
fetch(URL, { cache: 'no-store' });
// Этот запрос должен кешироваться с временем жизни 10 секунд.
// Аналогично `getStaticProps` с опцией `revalidate`.
fetch(URL, { next: { revalidate: 10 } });
В директории app
вы можете загружать данные внутри макетов, страниц и компонентов — включая поддержку потоковой передачи ответов с сервера.
Мы предоставляем эргономичные способы обработки состояний загрузки и ошибок, а также потоковой передачи UI по мере его рендеринга. В будущих релизах мы также улучшим и упростим мутации данных.
С директорией app/ вы можете использовать новый специальный файл loading.js для автоматического создания мгновенных состояний загрузки с границами Suspense.
Мы рады работать с open-source сообществом, разработчиками пакетов и другими компаниями, вносящими вклад в экосистему React, чтобы строить эту новую эру React и Next.js. Возможность располагать загрузку данных внутри компонентов и отправлять меньше JavaScript клиенту были двумя важными пожеланиями сообщества, которые мы рады включить в директорию app/
.
Узнайте больше о загрузке данных или разверните пример, чтобы попробовать.
Знакомство с Turbopack (Альфа)
Next.js 13 включает Turbopack, новый преемник Webpack на основе Rust.
Webpack был скачан более 3 миллиардов раз. Хотя он был неотъемлемой частью веб-разработки, мы достигли пределов максимальной производительности, возможной с инструментами на JavaScript.
В Next.js 12 мы начали переход к инструментам на основе Rust. Мы начали с миграции от Babel, что привело к ускорению транспиляции в 17 раз. Затем мы заменили Terser, что дало ускорение минификации в 6 раз. Пришло время полностью перейти на нативные решения для сборки.
Использование Turbopack alpha с Next.js 13 дает:
- Обновления в 700x быстрее, чем Webpack
- Обновления в 10x быстрее, чем Vite
- Холодный старт в 4x быстрее, чем Webpack
Turbopack — наш преемник Webpack на основе Rust, с HMR в 700x быстрее для больших приложений.
Turbopack собирает только минимально необходимые ассеты в разработке, поэтому время запуска крайне мало. Для приложения с 3,000 модулей Turbopack запускается за 1.8 секунды. Vite занимает 11.4 секунды, а Webpack — 16.5 секунд.
Turbopack поддерживает серверные компоненты, TypeScript, JSX, CSS и многое другое из коробки. Во время альфа-версии многие функции ещё не поддерживаются. Мы будем рады услышать ваш отзыв об использовании Turbopack для ускорения локальной разработки.
Примечание: Turbopack в Next.js пока поддерживает только
next dev
. Смотрите поддерживаемые функции. Мы также работаем над добавлением поддержкиnext build
через Turbopack.
Попробуйте Turbopack alpha сегодня в Next.js 13 с next dev --turbo
.
next/image
Next.js 13 представляет мощный новый компонент Image, позволяющий легко отображать изображения без сдвигов макета и оптимизировать файлы по требованию для повышения производительности.
Во время опроса сообщества Next.js 70% респондентов сообщили, что используют компонент Image в продакшене, и в результате увидели улучшение Core Web Vitals. С Next.js 13 мы улучшаем next/image
ещё больше.
Новый компонент Image:
- Отправляет меньше клиентского JavaScript
- Легче стилизовать и настраивать
- Более доступен, требует атрибут
alt
по умолчанию - Соответствует веб-платформе
- Быстрее, так как нативная ленивая загрузка не требует гидратации
import Image from 'next/image';
import avatar from './lee.png';
export default function Home() {
// "alt" теперь обязателен для улучшенной доступности
// опционально: файлы изображений могут располагаться внутри директории app/
return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}
Узнайте больше о компоненте Image или разверните пример, чтобы попробовать.
Обновление next/image
до Next.js 13
Старый компонент Image был переименован в next/legacy/image
. Мы предоставили кодмод, который автоматически обновит ваше использование next/image
на next/legacy/image
. Например, эта команда запустит кодмод для вашей директории ./pages
, если выполнить её из корня:
npx @next/codemod next-image-to-legacy-image ./pages
@next/font
Next.js 13 представляет совершенно новую систему шрифтов, которая:
- Автоматически оптимизирует ваши шрифты, включая пользовательские
- Удаляет внешние сетевые запросы для улучшения конфиденциальности и производительности
- Встроенный автоматический самохостинг для любых файлов шрифтов
- Нулевые сдвиги макета автоматически с использованием CSS свойства
size-adjust
Эта новая система шрифтов позволяет удобно использовать все шрифты Google с учетом производительности и конфиденциальности. CSS и файлы шрифтов загружаются во время сборки и самохостятся вместе с остальными статическими ассетами. Браузер не отправляет запросы к Google.
import { Inter } from '@next/font/google';
const inter = Inter();
<html className={inter.className}></html>;
Также поддерживаются пользовательские шрифты, включая автоматический самохостинг, кеширование и предзагрузку файлов шрифтов.
import localFont from '@next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
<html className={myFont.className}></html>;
Вы можете настраивать каждый аспект загрузки шрифтов, сохраняя отличную производительность и отсутствие сдвигов макета, включая font-display
, предзагрузку, фолбэки и многое другое.
Узнайте больше о новом компоненте Font или разверните пример, чтобы попробовать.
next/link
next/link
больше не требует ручного добавления <a>
как дочернего элемента.
Это было добавлено как экспериментальная опция в 12.2 и теперь стало поведением по умолчанию. В Next.js 13 <Link>
всегда рендерит <a>
и позволяет передавать пропсы в нижележащий тег. Например:
import Link from 'next/link'
// Next.js 12: `<a>` должен быть вложен, иначе он исключается
<Link href="/about">
<a>О нас</a>
</Link>
// Next.js 13: `<Link>` всегда рендерит `<a>`
<Link href="/about">
О нас
</Link>
Узнайте больше об улучшенном компоненте Link или разверните пример, чтобы попробовать.
Обновление next/link
до Next.js 13
Для обновления ваших ссылок до Next.js 13 мы предоставили кодмод, который автоматически обновит вашу кодовую базу. Например, эта команда запустит кодмод для директории ./pages
, если выполнить её из корня проекта:
npx @next/codemod new-link ./pages
Узнайте больше о кодмоде или ознакомьтесь с документацией.
Генерация OG-изображений
Социальные карточки (Open Graph изображения) могут значительно увеличить вовлечённость и количество кликов по вашему контенту — некоторые эксперименты показывают рост конверсии до 40%.
Статические социальные карточки требуют много времени, подвержены ошибкам и сложны в поддержке. Поэтому ими часто пренебрегают или вообще пропускают. До недавнего времени динамические социальные карточки, требующие персонализации и вычислений на лету, были сложными и дорогими в реализации.
Мы создали новую библиотеку @vercel/og
, которая бесшовно работает с Next.js для генерации динамических социальных карточек.
import { ImageResponse } from '@vercel/og';
export const config = {
runtime: 'experimental-edge',
};
export default function () {
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
}}
>
Hello, World!
</div>
),
);
}
Это решение в 5 раз быстрее существующих аналогов благодаря использованию Vercel Edge Functions, WebAssembly и совершенно новой базовой библиотеки для преобразования HTML и CSS в изображения с использованием абстракции React-компонентов.
Узнайте больше о генерации OG-изображений или разверните пример, чтобы попробовать.
Обновления API Middleware
В Next.js 12 мы представили Middleware для полной гибкости работы с роутером Next.js. Учитывая ваши отзывы о первоначальном дизайне API, мы внесли улучшения для удобства разработчиков и добавили новую функциональность.
Теперь вы можете проще устанавливать заголовки запроса:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Клонируем заголовки запроса и устанавливаем новый заголовок `x-version`
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-version', '13');
// Также можно установить заголовки запроса в NextResponse.rewrite
const response = NextResponse.next({
request: {
// Новые заголовки запроса
headers: requestHeaders,
},
});
// Устанавливаем новый заголовок ответа `x-version`
response.headers.set('x-version', '13');
return response;
}
Теперь также можно напрямую возвращать ответ из Middleware без необходимости использовать rewrite
или redirect
.
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';
// Ограничиваем middleware путями, начинающимися с `/api/`
export const config = {
matcher: '/api/:function*',
};
export function middleware(request: NextRequest) {
// Проверяем запрос с помощью функции аутентификации
if (!isAuthenticated(request)) {
// Возвращаем JSON с сообщением об ошибке
return NextResponse.json(
{
success: false,
message: 'Auth failed',
},
{
status: 401,
},
);
}
}
Отправка ответов из Middleware в настоящее время требует настройки experimental.allowMiddlewareResponseBody
в next.config.js
.
Критические изменения
- Минимальная версия React увеличена с 17.0.2 до 18.2.0.
- Минимальная версия Node.js увеличена с 12.22.0 до 14.6.0, так как версия 12.x достигла конца жизненного цикла (PR).
- Свойство конфигурации
swcMinify
изменено сfalse
наtrue
. Подробнее см. в Next.js Compiler. - Импорт
next/image
переименован вnext/legacy/image
. Импортnext/future/image
переименован вnext/image
. Доступен кодмод для безопасного и автоматического переименования импортов. - Дочерний элемент
next/link
больше не может быть<a>
. Используйте пропlegacyBehavior
для сохранения старого поведения или удалите<a>
для обновления. Доступен кодмод для автоматического обновления кода. - Маршруты больше не предзагружаются, если
User-Agent
является ботом. - Устаревшая опция
target
вnext.config.js
удалена. - Поддерживаемые браузеры изменены: удалена поддержка Internet Explorer и добавлены современные браузеры. Вы всё ещё можете использовать Browserslist для настройки целевых браузеров.
- Chrome 64+
- Edge 79+
- Firefox 67+
- Opera 51+
- Safari 12+
Подробнее см. в руководстве по обновлению.
Сообщество
Шесть лет назад мы выпустили Next.js для публичного использования. Нашей целью было создать React-фреймворк с нулевой настройкой, упрощающий процесс разработки. Оглядываясь назад, поразительно наблюдать, как выросло сообщество и что нам удалось создать вместе. Давайте продолжать в том же духе.
Next.js — это результат совместной работы более 2400 разработчиков, отраслевых партнёров, таких как Google и Meta, и нашей основной команды. С более чем 3 миллионами загрузок в неделю через npm и 94 000 звёзд на GitHub, Next.js является одним из самых популярных способов создания веб-приложений.
Особая благодарность команде Aurora из Google Chrome, которая помогла с фундаментальными исследованиями и экспериментами, приведшими к этому релизу.
Этот релиз стал возможен благодаря вкладу: @ijjk, @huozhi, @HaNdTriX, @iKethavel, @timneutkens, @shuding, @rishabhpoddar, @hanneslund, @balazsorban44, @devknoll, @anthonyshew, @TomerAberbach, @philippbosch, @styfle, @mauriciomutte, @hayitsdavid, @abdennor, @Kikobeats, @cjdunteman, @Mr-Afonso, @kdy1, @jaril, @abdallah-nour, @North15, @feedthejim, @brunocrosier, @Schniz, @sedlukha, @hashlash, @Ethan-Arrowood, @fireairforce, @migueloller, @leerob, @janicklas-ralph, @Trystanr, @atilafassina, @nramkissoon, @kasperadk, @valcosmos, @henriqueholtz, @nip10, @jesstelford, @lorensr, @AviAvinav, @SukkaW, @jaycedotbin, @saurabhburade, @notrab, @kwonoj, @sanruiz, @angeloashmore, @falsepopsky, @fmontes, @Gebov, @UltiRequiem, @p13lgst, @Simek, @mrkldshv, @thomasballinger, @kyliau, @AdarshKonchady, @endymion1818, @pedro757, @perkinsjr, @gnoff, @jridgewell, @silvioprog, @mabels, @nialexsan, @feugy, @jackromo888, @crazyurus, @EarlGeorge, @MariaSolOs, @lforst, @maximbaz, @maxam2017, @teobler, @Nutlope, @sunwoo0706, @WestonThayer, @Brooooooklyn, @Nsttt, @charlypoly, @aprendendofelipe, @sviridoff, @jackton1, @nuta, @Rpaudel379, @marcialca, @MarDi66, @ismaelrumzan, @javivelasco, @eltociear и @hiro0218.