За один рабочий день реально собрать production-подобный проект. Не hello world — а многостраничный сайт с динамическими маршрутами, оптимизированными изображениями и SEO-мета. Готовый для портфолио. Пригодный для деплоя.

Но есть условие. Нужно понимать, что Next.js берёт на себя, а что разработчик всё равно решает сам. Большинство туториалов про это молчат — и человек в итоге копирует код из устаревшей статьи, получает ошибку TypeScript, и не может понять почему.


Оглавление


Что нужно до старта

Next.js — не отдельный язык и не замена React. Это фреймворк, который берёт React и оборачивает его в инфраструктуру: маршрутизация, серверный рендеринг, кеширование, оптимизация изображений, обработка мета-данных. Фундамент остаётся прежним.

Официальная документация Next.js прямо перечисляет prerequirements:

  • HTML и CSS;

  • JavaScript;

  • React;

  • TypeScript — рекомендуется для новых проектов.

Попытка учить Next.js вместо React — распространённая ловушка. Человек запускает create-next-app, не понимает, зачем нужны хуки, и тонет в error boundaries с непонятным стеком ошибок. Порядок имеет значение: сначала React, потом Next.js поверх.


Создаём проект

Актуальный способ — одна команда:

pnpm create next-app

Интерактивный CLI предложит выбрать TypeScript, ESLint, Tailwind CSS, App Router и Turbopack. Это рекомендуемый набор для нового проекта в 2026 году, и все дальнейшие примеры ориентированы именно на него.

Структура после инициализации:

my-site/

├── app/

│   ├── layout.tsx

│   ├── page.tsx

│   └── globals.css

├── public/

├── package.json

├── tsconfig.json

├── eslint.config.mjs

└── next.config.ts

Здесь важна одна деталь. Файловая структура — не просто организация кода. Папки внутри app/ являются частью архитектуры приложения. Это станет понятно через две минуты.


Как Next.js устроен под капотом

Next.js 16 — не «React, который сам делает SSR». Это архитектурный runtime вокруг React: routing, Server Components, streaming, caching и rendering strategy существуют как единая система.

Самое важное, что нужно понять в начале: в App Router page.tsx и layout.tsx по умолчанию являются Server Components. Не клиентскими. Серверными. Это означает, что данные можно запрашивать прямо в компоненте, без useEffect и отдельного API-слоя.

// app/page.tsx — Server Component по умолчанию

export default async function HomePage() {

  const res = await fetch('https://api.example.com/posts')

  const posts = await res.json()

  return <PostList posts={posts} />

}

Браузер получает готовый HTML и RSC-payload. JavaScript-бандл клиента не раздувается кодом, который браузеру вообще не нужен.

Client Components нужны только там, где появляются состояние, event handlers или browser API:

'use client'

import { useState } from 'react'

export function MobileMenu() {

  const [open, setOpen] = useState(false)

  return (

    <button onClick={() => setOpen(!open)}>

      {open ? 'Закрыть' : 'Меню'}

    </button>

  )

}

'use client' — не «магическая настройка React». Это архитектурная граница. Всё выше неё в дереве компонентов выполняется на сервере, всё ниже — идёт в клиентский бандл.

Правило: начинайте с Server Component. Добавляйте 'use client' только там, где это реально нужно.


Routing, layout и страницы

Файловый роутер App Router работает предсказуемо. Каждая папка — сегмент URL. Файл page.tsx внутри — страница.

app/

├── page.tsx              → /

├── about/

│   └── page.tsx          → /about

├── blog/

│   ├── page.tsx          → /blog

│   └── [slug]/

│       └── page.tsx      → /blog/:slug

└── api/

    └── contact/

        └── route.ts      → API endpoint

layout.tsx оборачивает дочерние страницы. В корневом layout — <html>, <body>, шапка и подвал. Во вложенных layout — более специфичная обёртка, например, сайдбар для раздела /blog.

Для сайта-приглашения, который делается за день, хватит такой структуры:

app/

├── page.tsx              → главная

├── gallery/

│   └── page.tsx          → галерея

├── location/

│   └── page.tsx          → место проведения

├── rsvp/

│   └── page.tsx          → форма ответа

└── invite/

    └── [guestId]/

        └── page.tsx      → персональное приглашение

Пять маршрутов. Понятная структура. Никаких дополнительных конфигов.


params в Next.js 16: почему старый код ломается

Динамический маршрут — один из первых камней, о которые спотыкаются. Особенно если источник — туториал 2022-2023 года.

Паттерн, который сейчас ломается:

// Старый код — синхронные params

export default function Page({ params }: { params: { slug: string } }) {

  return <h1>{params.slug}</h1>

}

В актуальной документации Next.js 16 params — это Promise. Правильный код:

// app/invite/[guestId]/page.tsx

type Props = {

  params: Promise<{ guestId: string }>

}

export default async function InvitePage({ params }: Props) {

  const { guestId } = await params

  const guest = await getGuest(guestId)

  if (!guest) {

    return <h1>Приглашение не найдено</h1>

  }

  return (

    <main>

      <h1>{guest.name}, будем рады вас видеть</h1>

      <p>20 июня 2027 года</p>

    </main>

  )

}

API менялся несколько раз между Next.js 13 и 16. Копировать код из старых блогов без сверки с текущей документацией — прямой путь к ситуации, где ничего не работает и непонятно почему.


SEO без магии: Metadata API

«Next.js делает SEO» — популярное, но неточное утверждение. Корректнее: Next.js даёт удобную инфраструктуру для SSR/prerendering и метаданных. Качество SEO зависит от содержимого, структуры, скорости загрузки, ссылок и accessibility — и это по-прежнему работа разработчика.

Тем не менее Metadata API полезен. Для статических страниц:

// app/about/page.tsx

export const metadata = {

  title: 'О нас',

  description: 'Мы рады вас приветствовать на нашем празднике',

  openGraph: {

    title: 'Свадьба Ивана и Марии',

    images: ['/og-image.jpg'],

  },

}

Для динамических:

export async function generateMetadata({ params }: Props) {

  const { guestId } = await params

  const guest = await getGuest(guestId)

  return {

    title: guest

      ? Приглашение для ${guest.name}

      : 'Приглашение',

  }

}

Next.js сгенерирует нужные <head>-элементы: <title>, <meta name="description">, Open Graph-теги. Favicon и иконки тоже настраиваются через Metadata API или файлами в директории app/.


Изображения и LCP

Самый быстрый способ ухудшить Core Web Vitals на первом проекте — вставить изображение обычным тегом <img>.

Сравнение:

// Вариант A: обычный img

<img src="/hero.jpg" />

// Вариант B: next/image

import Image from 'next/image'

<Image

  src="/hero.jpg"

  alt="Иван и Мария"

  width={1600}

  height={900}

  priority

/>

next/image автоматически конвертирует изображение в современные форматы (WebP, AVIF), подбирает размер под устройство, откладывает загрузку для off-screen изображений и резервирует место под картинку, исключая layout shift.

Атрибут priority указывает, что изображение является LCP-элементом и должно грузиться в первую очередь. Без него hero-изображение загружается как обычное — и LCP падает.

Измерить результат можно через Chrome DevTools, Lighthouse или PageSpeed Insights. Не стоит заранее обещать «LCP улучшится на X%» — замерьте конкретный проект.


Production: что происходит после pnpm build

pnpm build

pnpm start

pnpm build — точка, в которой Next.js анализирует весь проект и принимает решения о рендеринге. В выводе видна маркировка каждого маршрута:

○  /              (статически подготовлено)

○  /about         (статически подготовлено)

λ  /invite/[id]   (серверный рендеринг по запросу)

○ — маршрут предварительно подготовлен. λ — рендерится при каждом запросе.

Кеширование в Next.js 16: новая модель

В Next.js 16 появилась директива 'use cache'. Результат компонента или функции становится кешируемым, ключ кеша зависит от входных аргументов и замыканий:

async function GuestList() {

  'use cache'

  const guests = await db.guest.findMany()

  return <GuestListView guests={guests} />

}

Это заменяет ряд старых конструкций: export const revalidate = 60 и export const dynamic = 'force-dynamic' в ряде сценариев уступают место новой модели use cache / cacheLife.

Понимание этой цепочки отделяет tutorial project от инженерного навыка:

source → compiler → server/client boundary → render → cache → HTML/RSC → browser

Именно способность ответить на вопросы «кто выполняет этот компонент, где, когда и нужно ли это делать снова» превращает первый сайт в базу для следующего.


Четыре ошибки, которые делает каждый

Делать всё Client Component. Новичок видит привычный React и ставит 'use client' везде. Получается обычный client-side React — значительная часть преимуществ серверной модели теряется. Правило простое: начинайте с Server Component, добавляйте клиентскую границу только там, где она реально нужна.

Учить Next.js без понимания React. Фреймворк не избавляет от необходимости понимать component composition, props, state, hooks, async JavaScript и HTTP. Это не заменители, это уровни.

Копировать старые туториалы. getServerSideProps, getStaticProps, getStaticPaths — это Pages Router, не App Router. params.slug без await — это API до Next.js 15. Код из статей 2022-2023 годов без сверки с текущей документацией работать не будет.

Считать SSR синонимом «быстро». Производительность — это система: серверный рендеринг, кеш, размер JS-бандла, изображения, шрифты, latency базы данных и сеть. Можно написать SSR-приложение, которое работает медленнее простого статического HTML.


Что требует рынок в 2026 году

По данным Stack Overflow Developer Survey 2025, React используют 83,6% respondентов в соответствующем разделе, Next.js — 58,6%. Это статистика опросов, не доля вакансий, поэтому интерпретировать их как «процент рабочих мест» нельзя.

Реальные вакансии с профильных ресурсов дают более конкретную картину. В актуальных описаниях обычно обретаются React.js + Next js,  нужно понимать SSG, SSR, ISR, CSR, App Router, Pages Router, dynamic routes, data fetching, Jest/Cypress и GitLab CI. Не стоит также забывать про Node.js, REST API, Redux, Jest/React Testing Library и Git. Senior-позиции добавляют Redux Toolkit, RTK Query, Docker, Jenkins и AI-инструменты.

Из этого складывается не абстрактный тезис «всем нужен Next.js», а конкретный стек:

Навык

Контекст

JavaScript / TypeScript

фундамент; TypeScript — практический стандарт в React-стеке

React

базовая платформа

Next.js

всё чаще требуется в продуктовых командах

SSR / SSG / ISR / CSR

уже не просто аббревиатуры в описании вакансии

REST / HTTP

основа интеграции

Git

обязательный рабочий инструмент

Testing: Jest / RTL

Middle и выше

CI/CD, Docker

особенно для production-позиций

State management

Redux Toolkit / RTK Query

AI coding tools

новая часть рабочего процесса в 2026 году

Два распространённых заблуждения стоит развенчать сразу.

Webpack не умер. State of JS 2025 показывает 86,4% использования webpack против 84,4% у Vite — разница минимальная. В новых проектах Vite и Turbopack действительно заметнее, но существующие enterprise-системы могут годами оставаться на webpack.

Pages Router не мёртв. Next.js официально продолжает его поддерживать. App Router — выбор для нового проекта, Pages Router — важный legacy/maintenance skill. В вакансиях оба роутера упоминаются рядом.

И ещё один нюанс: в 2026 году AI-инструменты снижают стоимость написания первого компонента. Зато повышается ценность понимания архитектуры. Способность объяснить, почему компонент серверный, почему данные кешируются именно здесь и почему этот код нельзя отправлять клиенту, становится дифференцирующим навыком.


Что изучать дальше

Первый сайт готов. Следующий вопрос обычно оказывается не про Next.js — а про то, что вокруг него. Ниже: конкретные пробелы и инструменты для их закрытия.

Если проблема — TypeScript и архитектура компонентов

В программе «Фронтенд-разработчик» Хекслета объединены React, TypeScript, Redux Toolkit/RTK Query, автоматическое и продвинутое тестирование, а в проектной части — Next.js с SSR и API routes. Это не узкий курс «Next.js за X недель»: большая часть посвящена фундаментальному frontend engineering. Хорошо закрывает проблему «умею делать страницу, но не понимаю, как превратить её в поддерживаемое приложение». Ограничение: для тех, кто уже уверенно знает React и TypeScript, значительная часть материала может оказаться повторением. Стоимость в каталоге Хабра — 85 000 ₽, около 10 месяцев. 

Подробнее о программе — в каталоге Хабр Курсов

Если проблема — production: тесты, API, Docker, CI/CD

«Мидл фронтенд-разработчик» от Яндекс Практикума покрывает именно ту инфраструктуру, которая появляется вокруг Next.js, когда проект перестаёт быть учебным: Node.js, REST API, Docker, CI/CD, Nginx, WebSockets, Jest, PostgreSQL. Next.js не является центром программы — ценность в системном расширении кругозора Middle-разработчика. Покупать её исключительно ради Next.js нерационально. Около 116 500 ₽, 5 месяцев, онлайн с проектами и code review. 

Подробнее о программе — в каталоге Хабр Курсов

Если проблема — React-фундамент перед переходом к Next.js

«Фронтенд-разработчик» от Бруноям покрывает функциональные компоненты, Hooks, React Router, CSS Modules, TypeScript и Redux Toolkit. Отдельного Next.js-модуля в программе нет, поэтому использовать её стоит именно как источник React/TypeScript базы, а не как обучение Next.js. 63 900 ₽, около 8 месяцев. 

Подробнее о программе — в каталоге Хабр Курсов

Если проблема — качество кода при работе с AI-инструментами

«Нейрофронтендер» от HTML Academy включает React patterns, TypeScript, тестирование, оптимизацию производительности и блок, ориентированный на AI workflow. Полезен для ситуации «генерирую код нейросетью, но не всегда понимаю, насколько он архитектурно нормальный». Важное ограничение: программа существенно шире задачи «сделать сайт на Next.js за день», а React-модуль ориентирован прежде всего на клиентские приложения. Около 42 900 ₽, 15 месяцев для полной программы. 

Подробнее — в каталоге Хабр Курсов


Шпаргалка Next.js App Router

Создать проект и запустить:

pnpm create next-app   # инициализация

pnpm dev               # dev-сервер

pnpm build             # production build

pnpm start             # production-сервер

Ключевые файлы:

Файл

Назначение

app/layout.tsx

корневой layout, обёртка для всех страниц

app/page.tsx

страница маршрута /

app/[slug]/page.tsx

динамический маршрут

app/api/route.ts

API endpoint

loading.tsx

UI загрузки для маршрута

error.tsx

обработка ошибок

not-found.tsx

страница 404

Server Component vs Client Component:

// Server Component (по умолчанию)

export default async function Page() {

  const data = await fetch('...')  // можно прямо здесь

  return <div>{data}</div>

}

// Client Component

'use client'

import { useState } from 'react'

export function Counter() {

  const [n, setN] = useState(0)

  return <button onClick={() => setN(n + 1)}>{n}</button>

}

Dynamic route + params (Next.js 16):

type Props = { params: Promise<{ slug: string }> }

export default async function Page({ params }: Props) {

  const { slug } = await params

  return <h1>{slug}</h1>

}

Metadata:

// Статическая

export const metadata = { title: '...', description: '...' }

// Динамическая

export async function generateMetadata({ params }: Props) {

  const { slug } = await params

  return { title: Страница: ${slug} }

}

Кеширование (Next.js 16):

async function CachedComponent() {

  'use cache'

  const data = await db.find()

  return <View data={data} />

}

«Сделать сайт на Next.js за день» — достижимая цель. Не волшебная, но реальная. Главное, что отделяет tutorial project от инженерного навыка: можете ли вы объяснить, кто выполняет каждый компонент, где он выполняется и нужно ли это делать снова при следующем запросе. Понимание Server/Client границы, rendering pipeline и caching — именно это превращает первый сайт в базу для следующего проекта.

Начать можно прямо сейчас: pnpm create next-app и документация — достаточный старт. Остальное появится по мере реальных задач.


FAQ

Нужен ли бэкенд для сайта на Next.js?

Для статического сайта-визитки или портфолио — нет. API routes в app/api/ позволяют обрабатывать формы прямо в приложении. Для серьёзного production-продукта с базой данных бэкенд обычно появляется отдельно: Next.js скрывает часть инфраструктурных деталей, но не заменяет бэкенд полностью.

Можно ли деплоить не на Vercel?

Да. Next.js поддерживает деплой на любой Node.js-хостинг. Vercel как платформа от создателей фреймворка даёт дополнительные интеграции, но это не обязательное условие. Альтернативы: Railway, Fly.io, собственный сервер с Docker.

Когда использовать Pages Router вместо App Router?

Для нового проекта — App Router. Для поддержки существующего кода — Pages Router остаётся полностью поддерживаемым. Знание обоих подходов ценится в вакансиях: в production-командах часто встречаются оба.