Вступ до Next.js
Вступ до Next.js — міст між клієнтом і сервером
Ми пройшли великий шлях: від HTML і CSS до JavaScript, TypeScript і React. Тепер час зробити фінальний крок -- познайомитися з Next.js, фреймворком, який робить React-додатки готовими до продакшену.
Навіщо Next.js?
React сам по собі -- це бібліотека для побудови UI. Але для повноцінного вебзастосунку потрібно ще багато речей:
| Потреба | React | Next.js |
|---|---|---|
| Routing (маршрутизація) | Потрібен React Router | Вбудований (file-based) |
| SEO | Погано (CSR, пустий HTML) | Чудово (SSR/SSG) |
| Серверний рендеринг | Потрібна ручна настройка | Вбудований |
| API endpoints | Потрібен окремий бекенд | Вбудовані API routes |
| Оптимізація зображень | Вручну | Вбудований Image component |
| Code splitting | Потрібна настройка | Автоматичне |
Next.js -- це фреймворк поверх React, створений компанією Vercel. Він додає все, що потрібно для production-ready додатку.
Next.js не замінює React -- він його розширює. Все, що ти знаєш про React (компоненти, хуки, стейт), працює в Next.js без змін.
Створення проекту
Створити новий Next.js проект дуже просто:
Створення Next.js проєкту з інтерактивними налаштуваннями
npx create-next-app@latest my-app
Тебе запитають кілька питань:
Would you like to use TypeScript? › Yes
Would you like to use ESLint? › Yes
Would you like to use Tailwind CSS? › Yes
Would you like to use `src/` directory? › Yes
Would you like to use App Router? › Yes
Would you like to use Turbopack? › Yes
Завжди обирай App Router -- це сучасний підхід у Next.js. Pages Router -- це застарілий варіант, хоча він все ще підтримується.
Після створення:
cd my-app
npm run dev
Відкрий http://localhost:3000 -- ти побачиш стартову сторінку Next.js!
Структура проекту
my-app/
src/
app/ # App Router -- тут живуть сторінки
layout.tsx # Кореневий layout
page.tsx # Головна сторінка (/)
globals.css # Глобальні стилі
lib/ # Утиліти, хелпери
components/ # React-компоненти
public/ # Статичні файли (зображення, іконки)
next.config.ts # Конфігурація Next.js
tailwind.config.ts # Конфігурація Tailwind
tsconfig.json # Конфігурація TypeScript
package.json
File-based Routing
У Next.js маршрутизація базується на файловій системі. Кожен файл page.tsx в директорії app/ автоматично стає маршрутом:
src/app/
page.tsx → /
about/
page.tsx → /about
blog/
page.tsx → /blog
contact/
page.tsx → /contact
Щоб створити нову сторінку, просто створи папку з файлом page.tsx:
// src/app/about/page.tsx
export default function AboutPage() {
return (
<main>
<h1>Про нас</h1>
<p>Ласкаво просимо на нашу сторінку!</p>
</main>
);
}
Тепер сторінка /about працює автоматично -- жодного конфігу, жодного роутера!
Вкладені маршрути
src/app/
blog/
page.tsx → /blog
first-post/
page.tsx → /blog/first-post
tutorials/
page.tsx → /blog/tutorials
Компонент Link
Для навігації між сторінками використовуй компонент Link замість тегу <a>:
import Link from "next/link";
export default function Navigation() {
return (
<nav>
<Link href="/">Головна</Link>
<Link href="/about">Про нас</Link>
<Link href="/blog">Блог</Link>
<Link href="/contact">Контакти</Link>
</nav>
);
}
Чому Link, а не <a>?
Linkробить клієнтську навігацію (без повного перезавантаження сторінки)- Автоматичний prefetching -- Next.js заздалегідь завантажує сторінку, на яку вказує лінк
- Працює як SPA (Single Page Application), але з серверним рендерингом
Link -- для внутрішніх посилань (на сторінки твого сайту). Для зовнішніх посилань (на інші сайти) використовуй звичайний тег <a> або Link з target="_blank".
Dynamic Routes (динамічні маршрути)
Часто потрібні маршрути з параметрами: /blog/my-first-post, /users/123. У Next.js це робиться через квадратні дужки:
src/app/
blog/
[slug]/
page.tsx → /blog/anything, /blog/my-post, тощо
// src/app/blog/[slug]/page.tsx
interface PageProps {
params: Promise<{
slug: string;
}>;
}
export default async function BlogPost({ params }: PageProps) {
const { slug } = await params;
return (
<article>
<h1>Стаття: {slug}</h1>
<p>Тут буде контент статті з slug: {slug}</p>
</article>
);
}
Тепер:
/blog/hello-world→slug = "hello-world"/blog/nextjs-intro→slug = "nextjs-intro"
Кілька динамічних сегментів
src/app/
shop/
[category]/
[productId]/
page.tsx → /shop/shoes/42
// src/app/shop/[category]/[productId]/page.tsx
interface PageProps {
params: Promise<{
category: string;
productId: string;
}>;
}
export default async function ProductPage({ params }: PageProps) {
const { category, productId } = await params;
return (
<div>
<p>Категорія: {category}</p>
<p>ID товару: {productId}</p>
</div>
);
}
Спеціальні файли App Router
Next.js App Router має кілька спеціальних файлів, які автоматично обробляють типові ситуації:
layout.tsx -- обгортка для сторінок
// src/app/layout.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Мій сайт",
description: "Створений на Next.js",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="uk">
<body>
<header>
<nav>Навігація</nav>
</header>
<main>{children}</main>
<footer>Футер</footer>
</body>
</html>
);
}
Layout зберігає стан між переходами -- навігація, хедер, футер не перерендерюються.
loading.tsx -- стан завантаження
// src/app/blog/loading.tsx
export default function Loading() {
return <div>Завантаження...</div>;
}
Автоматично показується, поки сторінка завантажує дані.
error.tsx -- обробка помилок
// src/app/blog/error.tsx
"use client";
export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
return (
<div>
<h2>Щось пішло не так!</h2>
<p>{error.message}</p>
<button onClick={reset}>Спробувати ще</button>
</div>
);
}
error.tsx повинен бути Client Component ("use client"), бо він використовує інтерактивні елементи (кнопка reset).
not-found.tsx -- сторінка 404
// src/app/not-found.tsx
import Link from "next/link";
export default function NotFound() {
return (
<div>
<h2>Сторінку не знайдено</h2>
<p>Не вдалося знайти запитаний ресурс.</p>
<Link href="/">Повернутися на головну</Link>
</div>
);
}
Практичний приклад: простий сайт
Створимо сайт з навігацією та кількома сторінками:
// src/components/Header.tsx
import Link from "next/link";
export default function Header() {
return (
<header style={{ padding: "1rem", borderBottom: "1px solid #eee" }}>
<nav style={{ display: "flex", gap: "1rem" }}>
<Link href="/">Головна</Link>
<Link href="/about">Про нас</Link>
<Link href="/blog">Блог</Link>
</nav>
</header>
);
}
// src/app/layout.tsx
import Header from "@/components/Header";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="uk">
<body>
<Header />
<main style={{ padding: "2rem" }}>{children}</main>
</body>
</html>
);
}
// src/app/page.tsx
export default function HomePage() {
return (
<div>
<h1>Вітаємо на нашому сайті!</h1>
<p>Це головна сторінка, створена на Next.js.</p>
</div>
);
}
// src/app/about/page.tsx
export default function AboutPage() {
return (
<div>
<h1>Про нас</h1>
<p>Ми навчаємося створювати вебзастосунки.</p>
</div>
);
}
Підсумок
- Next.js -- фреймворк поверх React, який додає routing, SSR/SSG, API routes, оптимізацію
- File-based routing -- файли в
app/автоматично стають сторінками - Link -- компонент для клієнтської навігації (замість
<a>) - Dynamic routes --
[slug]для параметризованих маршрутів - Спеціальні файли:
layout.tsx,loading.tsx,error.tsx,not-found.tsx
Що далі?
У наступному уроці розберемося з pre-rendering та data fetching -- дізнаємося, чим відрізняються SSG, SSR і CSR, і коли що використовувати.
Корисні посилання:
- Next.js Documentation -- офіційна документація
- Next.js: Routing -- детально про маршрутизацію
- Next.js: Learn -- інтерактивний курс від Vercel
Відео:
- Next.js in 100 Seconds — Fireship — вступ до Next.js: SSR, SSG, file-based routing
Більше корисних YouTube-каналів та інструментів — на сторінці ресурсів.