За один рабочий день реально собрать 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-командах часто встречаются оба.

