Перейти до основного вмісту

Основи Next.js

Що таке Next.js?

Next.js — це прогресивний фреймворк для розробки веб-застосунків на основі React. Він розширює можливості React, додаючи готову інфраструктуру для Server-Side Rendering (SSR), генерації статичних сторінок, маршрутизації через файлову систему, а також можливість створювати backend-ендпоінти прямо в проєкті.

Чому він став популярним?

Next.js швидко здобув популярність завдяки тому, що пропонує:

  • SEO-дружні сторінки завдяки SSR / SSG;
  • швидкий перший рендер (First Page Load);
  • просту маршрутизацію без налаштування;
  • розгортання в один клік через Vercel;
  • вбудовану оптимізацію зображень та продуктивності.

Чим відрізняється від класичного React

У класичному React ми отримуємо лише клієнтську бібліотеку для побудови UI-компонентів. Усе інше (SSR, маршрути, API) треба налаштовувати вручну або через сторонні бібліотеки (наприклад, React Router, Redux, Express, etc.).

Next.js — це уже повноцінний фреймворк. Він одразу має:

  • серверний рендеринг (SSR);
  • static generation (SSG);
  • маршрутизацію через папку pages або app;
  • можливість створювати backend-функції в папці pages/api.

Наприклад, класичний React без SSR:


// App.jsx
function App() {
  return (
    <div>
      <h1>Hello React</h1>
    </div>
  );
}
export default App;

А в Next.js досить створити файл pages/index.js:


// pages/index.js
export default function Home() {
  return (
    <div>
      <h1>Hello Next.js</h1>
    </div>
  );
}

Головні можливості Next.js

Next.js пропонує набір функцій «з коробки», які значно спрощують розробку сучасних веб-застосунків:

  • Server-Side Rendering (SSR) — рендеринг сторінок на сервері перед відправкою користувачу.
  • Static Site Generation (SSG) — попередня генерація HTML під час зборки (build).
  • File-based Routing — автоматична маршрутизація на основі структури папки pages/ або app/.
  • API Routes — можливість створювати backend endpoint-и прямо всередині Next.js-проєкту.
  • Підтримка TypeScript — повна інтеграція без додаткових налаштувань.
  • Оптимізація зображень — компонент <Image /> забезпечує lazy-loading і responsive images.

Наприклад: створимо сторінку з SSR за допомогою getServerSideProps:


// pages/ssr-example.js
export async function getServerSideProps() {
  return {
    props: {
      time: new Date().toLocaleTimeString()
    }
  };
}

export default function SSRExample({ time }) {
  return (
    <div>
      <h2>Server-side rendered page</h2>
      <p>Time: {time}</p>
    </div>
  );
}

Для SSG (Static Generation) використовується getStaticProps():


// pages/static-example.js
export async function getStaticProps() {
  return {
    props: {
      message: "Це сторінка, згенерована на етапі build"
    }
  };
}

export default function StaticExample({ message }) {
  return (
    <div>
      <h2>Static Page</h2>
      <p>{message}</p>
    </div>
  );
}

Встановлення та перший проєкт

Для старту з Next.js потрібно мати встановлений Node.js (рекомендується версія 16+). Створити новий проєкт можна за допомогою інструменту Create Next App.

Команда для створення нового Next-проєкту:

npx create-next-app@latest my-next-app

Після створення проєкту структура папок виглядає приблизно так:


my-next-app/
├─ pages/
│   ├─ index.js
│   ├─ _app.js
│   └─ api/
│       └─ hello.js
├─ public/
│   └─ favicon.ico
├─ styles/
│   └─ globals.css
├─ package.json

Щоб запустити проєкт у режимі розробки:

cd my-next-app
npm run dev

Після запуску, застосунок буде доступний за адресою http://localhost:3000

Маршрути та сторінки

У Next.js маршрутизація побудована за принципом «файл = сторінка». Усе, що розміщується в папці pages, автоматично стає маршрутом.

Наприклад, файл pages/about.js автоматично стане сторінкою за адресою /about:


// pages/about.js
export default function About() {
  return (
    <div>
      <h1>Про нас</h1>
      <p>Це сторінка "About".</p>
    </div>
  );
}

Динамічні маршрути

Для динамічних сторінок використовуються квадратні дужки у назві файлу, наприклад [id].js.


// pages/products/[id].js
import { useRouter } from 'next/router';

export default function ProductPage() {
  const router = useRouter();
  const { id } = router.query;

  return (
    <div>
      <h2>Product ID: {id}</h2>
    </div>
  );
}

Вкладені маршрути

Створюються через вкладені папки:


pages/
├─ blog/
│   └─ first-post.js

Ця сторінка буде за шляхом /blog/first-post.

Головна сторінка

Файл pages/index.js — це корінь сайту (/):


// pages/index.js
export default function Home() {
  return (
    <div>
      <h1>Головна сторінка</h1>
    </div>
  );
}

Рендеринг: SSR vs SSG vs CSR

У Next.js можна використовувати різні стратегії рендерингу сторінок залежно від потреб.

  • CSR (Client-Side Rendering) — класичний React, коли все відбувається на стороні клієнта.
  • SSR (Server-Side Rendering) — сторінка генерується на сервері при кожному запиті за допомогою getServerSideProps().
  • SSG (Static Site Generation) — сторінка генерується під час збірки (build), використовуючи getStaticProps() і, при потребі, getStaticPaths().

SSR (Server-Side Rendering)


// pages/ssr-example.js
export async function getServerSideProps() {
  const data = { time: new Date().toISOString() };
  return { props: { data } };
}

export default function SSRExample({ data }) {
  return (
    <div>
      <h2>SSR Example</h2>
      <p>Time: {data.time}</p>
    </div>
  );
}

SSG (Static Generation)


// pages/ssg-example.js
export async function getStaticProps() {
  return {
    props: {
      message: "Ця сторінка створена під час build"
    }
  };
}

export default function SSGExample({ message }) {
  return (
    <div>
      <h2>SSG Example</h2>
      <p>{message}</p>
    </div>
  );
}

CSR (Client-Side Rendering)


// pages/csr-example.js
import { useEffect, useState } from "react";

export default function CSRExample() {
  const [time, setTime] = useState("");

  useEffect(() => {
    setTime(new Date().toISOString());
  }, []);

  return (
    <div>
      <h2>CSR Example</h2>
      <p>Time: {time}</p>
    </div>
  );
}

Використовуй SSR, якщо дані змінюються на кожному запиті (наприклад, профіль користувача або статистика в реальному часі). Використовуй SSG для статичних сторінок, наприклад, блог, маркетинг, документація. А CSR — якщо все може відрендеритися з API прямо в браузері.

Робота з API Routes

Next.js дозволяє створювати серверні функції (API endpoints) без потреби у зовнішньому сервері типу Express. Це зручно для обробки форм, авторизації, обміну даними з базою тощо.

Усі API-роути створюються в папці pages/api. Кожен файл у цій папці автоматично стає HTTP endpoint’ом.

Приклад простого API-роута:


// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ message: "Привіт з API!" });
}

Після запуску проєкту цей endpoint буде доступний за адресою: http://localhost:3000/api/hello

Обробка методів POST, GET, тощо


// pages/api/echo.js
export default function handler(req, res) {
  if (req.method === 'POST') {
    const { name } = req.body;
    res.status(200).json({ received: name });
  } else {
    res.status(405).json({ error: 'Метод не дозволено' });
  }
}

Як викликати API на клієнті:


// Виклик з React-компонента (CSR)
const response = await fetch('/api/hello');
const data = await response.json();
console.log(data.message);

API Routes зручно використовувати для невеликих проєктів або коли немає окремого бекенду. У складніших випадках зазвичай використовують зовнішній сервер (наприклад, NestJS) або хмарні функції.

Коментарі

Популярні публікації

Шпаргалка по базових командах PostgreSQL

1. Підключення до PostgreSQL через командний рядок: psql -h <host> -p <port> -U <username> -d <database> 2. Підключення до бази без параметрів (якщо користувач і база мають однакове ім’я): psql 3. Показати список усіх баз даних: \l 4. Підключитися до іншої бази даних: \c <database_name> 5. Показати список таблиць у поточній базі: \dt 6. Показати всі об'єкти (таблиці, індекси, секвенції): \d 7. Показати таблиці з усіх схем: \dt *.* 8. Переглянути структуру конкретної таблиці: \d <table_name> 9. Виконати SQL-запит (приклад): SELECT * FROM users; 10. Вийти з psql: \q 11. Створити нову базу даних: CREATE DATABASE mydb; 12. Створити нову таблицю: CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE ); 13. Додати новий запис: INSERT INTO users (name, email) VALUES ('Іван', 'ivan@example.com'); 14. Оновити дані в таблиці: UPDATE users SET name = 'Петро' WH...

Основи GLSL

Що таке GLSL? GLSL (OpenGL Shading Language) – мова програмування шейдерів для OpenGL. Використовується для написання vertex, fragment, geometry та інших шейдерів, що працюють на GPU. Оголошення версії #version 330 core Вказує версію GLSL. Наприклад, 330 core відповідає OpenGL 3.3. Вхідні та вихідні змінні layout(location=0) in vec3 aPos; layout(location=1) in vec3 aNormal; out vec3 FragPos; in – вхідні атрибути (vertex shader). out – вихідні змінні (vertex shader) або фінальний колір (fragment shader). Основні типи даних float, int, bool vec2, vec3, vec4 mat2, mat3, mat4 sampler2D (текстури) Тип Опис Приклади використання vec2 Двокомпонентний вектор з типом float. - Текстурні координати (UV) - 2D позиції - Швидкість у 2D vec3 Трикомпонентний вектор з типом float. - Координати позицій у 3D - Нормалі - Колір у форматі RGB vec4 Чотирикомпо...

Атоми в мові програмування Elixir

Атоми в Elixir Атоми є фундаментальною концепцією в Elixir , що відіграє ключову роль у створенні надійних та масштабованих систем. В Elixir це специфічний тип даних, який є константою , незмінною , ідентифікованою за своїм ім'ям . Отже, атом в Elixir — це іменована константа, що представляє себе. Уявіть, що ви даєте унікальне ім'я певній речі, і це ім'я завжди посилається саме на цю річ, і ніколи на щось інше. Наприклад, атом :ok завжди буде означати саме успішне завершення операції, а не якесь інше значення. Технічно, атоми є похідними від чисел . Кожен унікальний атом зберігається у таблиці атомів, і йому присвоюється унікальний цілочисельний ідентифікатор. Це робить їх надзвичайно ефективними для порівняння: замість порівняння рядків (що є повільною операцією), Elixir порівнює цілочисельні ідентифікатори. Переваги та особливості використання атомів Переваги атомів: Ефективність. Завдяки своєму числовому представленню, порівняння атомів є дуже швидким. Це осо...

Встановлення PostgreSQL на Ubuntu-сервер

Встановлення Оновлюємо пакети та встановлюємо PostgreSQL: sudo apt update sudo apt install -y postgresql postgresql-contrib Перевіряємо статус сервісу: sudo systemctl status postgresql Якщо PostgreSQL не запущений, запустимо його: sudo systemctl start postgresql sudo systemctl enable postgresql Налаштування безпеки Зміна пароля: sudo -u postgres psql У консолі PostgreSQL: ALTER USER postgres PASSWORD 'міцний_пароль'; \q \q - вихід з консолі. Список основних команд для роботи з PostgreSQL можна переглянути за посиланням. За замовчуванням PostgreSQL слухає localhost (127.0.0.1). Щоб дозволити доступ із зовнішніх машин, редагуємо конфігурацію: sudo nano /etc/postgresql/17/main/postgresql.conf (замість 17 вкажи версію PostgreSQL, яку встановлено) Шукаємо рядок: #listen_addresses = 'localhost' та замінюємо на listen_addresses = '*' Зберігаємо (Ctrl + X, Y, Enter). Тепер редагуємо pg_hba.conf: sudo nano /etc/postgresql/17/main/pg_hba.conf...

Прості типи даних в Elixir

Мова Elixir має низку простих (примітивних) типів даних, які часто використовуються в повсякденному програмуванні. Числа Elixir підтримує цілі (integer) та дійсні числа (float). # Цілі числа a = 42 b = -7 # Дійсні числа c = 3.14 d = -0.001 Булеві значення Elixir має два булевих значення: true та false . x = true y = false z = x and y # false Атоми Атоми — це константи з іменем, що починається з двокрапки. Вони широко використовуються, наприклад, для імен параметрів або станів. :ok :error :running :elixir_is_fun Рядки Рядки в Elixir — це двійкові дані з кодуванням UTF-8, оголошуються в подвійних лапках. name = "Pavlo" greeting = "Привіт, #{name}!" Nil Nil — це спеціальне значення, що позначає "відсутність значення". value = nil is_nil(value) # true Бінарні дані та байти Бінарні дані оголошуються в подвійних лапках або як бінарні літерали. string = "Привіт" # це рядок, але також бінарні дані binary = ...