Що таке Next.js і чому його варто використовувати
Next.js — це фреймворк, побудований на основі React, який обробляє все те, що React не надає «з коробки»: рендеринг на стороні сервера, маршрутизація, оптимізація та інше.
React сам по собі є бібліотекою для створення інтерфейсів. Він не диктує, як налаштувати маршрутизацію, де рендерити сторінки або як обробляти запити до API. Next.js відповідає на всі ці запитання і надає готову структуру для виробничих додатків.
Яку проблему вирішує Next.js
Якщо ви створюєте React-додаток з нуля, використовуючи create-react-app або Vite, ви отримуєте SPA (односторінковий додаток). Увесь HTML генерується на клієнті за допомогою JavaScript. Це створює кілька проблем:
- SEO. Боти пошукових систем бачать порожній HTML, поки не виконається JavaScript. Для контентних сайтів, блогів і онлайн-магазинів це критично.
- Швидкість першого завантаження. Користувач чекає, поки весь JavaScript завантажиться і виконається, перш ніж побачити будь-який контент.
- Налаштування інфраструктури. Для SSR, розподілу коду, оптимізації зображень тощо вам потрібно самостійно підключити та налаштувати безліч інструментів.
Next.js вирішує всі ці проблеми «з коробки».
Ключові особливості
Кілька стратегій рендерингу
Next.js дозволяє вибрати стратегію рендерингу для кожної сторінки індивідуально:
- SSR (рендеринг на стороні сервера) — сторінка рендериться на сервері при кожному запиті. Добре підходить для динамічного контенту, який часто змінюється.
- SSG (генерація статичних сайтів) — сторінка генерується один раз під час збірки. Ідеально підходить для блогів, документації, лендінгів.
- ISR (інкрементальна статична регенерація) — статична сторінка, яка може оновлюватися у фоновому режимі через певні інтервали. Компроміс між SSR і SSG.
- CSR (рендеринг на стороні клієнта) — звичайний рендеринг на стороні клієнта, як у класичному React-додатку.
// SSR: дані отримуються при кожному запиті
export default async function Page() {
const data = await fetch('https://api.example.com/posts', {
cache: 'no-store'
})
const posts = await data.json()
return <PostList posts={posts} />
}// SSG: дані отримуються один раз під час збірки (за замовчуванням)
export default async function Page() {
const data = await fetch('https://api.example.com/posts')
const posts = await data.json()
return <PostList posts={posts} />
}// ISR: перевіряє кожні 60 секунд
export default async function Page() {
const data = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 }
})
const posts = await data.json()
return <PostList posts={posts} />
}Маршрутизація на основі файлів
У Next.js вам не потрібно налаштовувати React Router. Структура файлів у папці app автоматично стає вашими маршрутами:
app/
page.tsx -> /
about/
page.tsx -> /about
blog/
page.tsx -> /blog
[slug]/
page.tsx -> /blog/my-post (динамічний маршрут)Квадратні дужки [slug] створюють динамічний сегмент. Next.js самостійно визначає, як відповідати URL компоненту.
Серверні компоненти
У App Router (починаючи з Next.js 13) компоненти за замовчуванням є серверними компонентами. Це означає, що вони виконуються на сервері та надсилають готовий HTML клієнту.
// Цей компонент виконується на сервері
// Ви можете безпосередньо отримати доступ до бази даних, файлової системи тощо.
export default async function UsersPage() {
const users = await db.user.findMany()
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}Якщо вам потрібна інтерактивність (useState, onClick, useEffect), додайте 'use client' на початку файлу:
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Кліки: {count}
</button>
)
}API маршрути
Next.js дозволяє створювати бекенд-ендпоінти прямо у вашому проекті. У App Router їх називають Route Handlers:
// app/api/users/route.ts
import { NextResponse } from 'next/server'
export async function GET() {
const users = await db.user.findMany()
return NextResponse.json(users)
}
export async function POST(request: Request) {
const body = await request.json()
const user = await db.user.create({ data: body })
return NextResponse.json(user, { status: 201 })
}Це зручно для простих API, обробки форм, вебхуків. Для складного бекенду краще використовувати окремий сервер.
Вбудована оптимізація
Next.js включає оптимізації, які в чистому React вам довелося б налаштовувати самостійно:
- Компонент
Imageавтоматично оптимізує зображення: змінює розмір, конвертує у WebP, додає л lazy loading. - Компонент
Linkпопередньо завантажує сторінки при наведенні, роблячи навігацію миттєвою. - Компонент
Scriptконтролює завантаження сторонніх скриптів, щоб вони не блокували рендеринг. - Автоматичний розподіл коду. Кожна сторінка завантажує лише той JavaScript, який їй потрібен.
import Image from 'next/image'
import Link from 'next/link'
export default function Header() {
return (
<header>
<Image src="/logo.png" width={120} height={40} alt="Логотип" />
<nav>
<Link href="/about">Про нас</Link>
<Link href="/blog">Блог</Link>
</nav>
</header>
)
}Чим Next.js відрізняється від React
| React | Next.js | |
|---|---|---|
| Тип | Бібліотека | Фреймворк |
| Рендеринг | Тільки CSR | SSR, SSG, ISR, CSR |
| Маршрутизація | Потрібен React Router | Вбудована (на основі файлів) |
| SEO | Проблеми без SSR | Чудово «з коробки» |
| API | Немає | Route Handlers |
| Оптимізація | Вручну | Вбудована |
React не замінюється Next.js. Next.js працює поверх React. Ви все ще пишете компоненти, використовуєте хуки та все інше з React. Next.js просто додає інфраструктуру навколо цього.
Коли використовувати Next.js
Добре підходить для:
- Контентних сайтів і блогів, де важливе SEO
- Онлайн-магазинів
- Корпоративних веб-сайтів
- Панелей управління з авторизацією на стороні сервера
- Додатків, де важлива швидкість першого завантаження
Може бути надмірним для:
- Малих SPA без вимог до SEO (адмін-панелі, внутрішні інструменти)
- Додатків, де весь контент генерується на клієнті (наприклад, графічні редактори)
- Прототипів, де швидкість розробки важливіша за оптимізацію
Резюме
Next.js не є заміною для React, а є шаром поверх, який перетворює його з бібліотеки для створення інтерфейсів у повноцінний виробничий фреймворк. Він обробляє серверний рендеринг, маршрутизацію, оптимізацію та API, дозволяючи розробнику зосередитися на продукті, а не на конфігурації.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.