BackНазад к блогу

Next.js 13

Next.js 13 представляет директорию app с поддержкой макетов, серверных компонентов React и потоковой передачи, а также Turbopack, улучшенный компонент изображений и совершенно новый компонент шрифтов.

Как мы анонсировали на Next.js Conf, Next.js 13 (стабильная версия) закладывает основы для динамичности без ограничений:

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 серверные компоненты и расширенный API fetch позволяют загружать данные на уровне компонентов.

Директорию app можно внедрять постепенно из существующей директории pages/.

Директорию app можно внедрять постепенно из существующей директории pages/.

Макеты

Директория app/ упрощает создание сложных интерфейсов, которые сохраняют состояние между переходами, избегают дорогостоящих перерисовок и поддерживают продвинутые паттерны маршрутизации. Более того, вы можете вкладывать макеты и располагать код приложения рядом с маршрутами, например, компоненты, тесты и стили.

Директорию app/ можно внедрять постепенно из существующей директории pages/.

Директорию app/ можно внедрять постепенно из существующей директории pages/.

Создание маршрутов внутри app/ требует одного файла page.js:

app/page.js
// Этот файл соответствует корневому маршруту (/)
export default function Page() {
  return <h1>Привет, Next.js!</h1>;
}

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

app/blog/layout.js
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 Поддержка промисов представляет мощный новый способ загрузки данных и обработки промисов внутри компонентов:

app/page.js
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.

С директорией 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 — наш преемник 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 по умолчанию
  • Соответствует веб-платформе
  • Быстрее, так как нативная ленивая загрузка не требует гидратации
app/page.js
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.

app/layout.js / pages/_app.js
import { Inter } from '@next/font/google';
 
const inter = Inter();
 
<html className={inter.className}></html>;

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

app/layout.js / pages/_app.js
import localFont from '@next/font/local';
 
const myFont = localFont({ src: './my-font.woff2' });
 
<html className={myFont.className}></html>;

Вы можете настраивать каждый аспект загрузки шрифтов, сохраняя отличную производительность и отсутствие сдвигов макета, включая font-display, предзагрузку, фолбэки и многое другое.

Узнайте больше о новом компоненте Font или разверните пример, чтобы попробовать.

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.js 13 мы предоставили кодмод, который автоматически обновит вашу кодовую базу. Например, эта команда запустит кодмод для директории ./pages, если выполнить её из корня проекта:

Terminal
npx @next/codemod new-link ./pages

Узнайте больше о кодмоде или ознакомьтесь с документацией.

Генерация OG-изображений

Социальные карточки (Open Graph изображения) могут значительно увеличить вовлечённость и количество кликов по вашему контенту — некоторые эксперименты показывают рост конверсии до 40%.

Статические социальные карточки требуют много времени, подвержены ошибкам и сложны в поддержке. Поэтому ими часто пренебрегают или вообще пропускают. До недавнего времени динамические социальные карточки, требующие персонализации и вычислений на лету, были сложными и дорогими в реализации.

Мы создали новую библиотеку @vercel/og, которая бесшовно работает с Next.js для генерации динамических социальных карточек.

pages/api/og.jsx
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, мы внесли улучшения для удобства разработчиков и добавили новую функциональность.

Теперь вы можете проще устанавливать заголовки запроса:

middleware.ts
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.

middleware.ts
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.