Хотите заказать веб-сайт? Связаться с нами

SSR в Next.js: React на полной мощности

Цель урока: понять, что такое Server Side Rendering (SSR), зачем он нужен и как Next.js упрощает создание React-приложений с рендерингом на сервере. Научиться создавать многостраничные приложения с улучшенным SEO, быстрой загрузкой и богатым функционалом «из коробки».

SSR в Next.js: React на полной мощности

Введение: проблема SPA и рождение SSR

React-приложения по умолчанию — это Single Page Applications (SPA). Весь JavaScript загружается в браузер один раз, а затем React управляет страницей.

Проблемы SPA

  1. SEO (поисковая оптимизация) — поисковые боты не всегда выполняют JavaScript, поэтому они видят пустую страницу с <div id="root"></div>
  2. Первая загрузка — пользователь видит пустой экран, пока загружается весь JavaScript
  3. Производительность — на слабых устройствах загрузка может быть медленной

Главная мысль: SSR (Server Side Rendering) решает эти проблемы, рендеря React-компоненты на сервере и отправляя готовый HTML в браузер. Пользователь видит страницу сразу, а React «оживает» её после загрузки JavaScript.

Два подхода

Подход Что происходит Когда использовать
SPA (Create React App, Vite) Рендеринг в браузере Админки, внутренние приложения
SSR (Next.js) Рендеринг на сервере Публичные сайты, интернет-магазины

Что такое Next.js и почему он популярен

(откроется в новой вкладке)Next.js — это фреймворк на основе React, созданный компанией Vercel.

Что даёт Next.js «из коробки»:

  1. SSR и SSG — рендеринг на сервере и генерация статики
  2. Автоматическая маршрутизация — страницы создаются из папки pages/
  3. API Routes — создание API-эндпоинтов внутри приложения
  4. Оптимизация изображений — автоматическое сжатие и lazy loading
  5. Hot Module Replacement — мгновенное обновление при разработке
  6. Zero Config — почти нет настроек

Главная мысль: Next.js — это «React на максималках». Ты получаешь все возможности React плюс SSR, SEO, производительность и множество удобных инструментов.

Сравнение с другими

Create React App Vite Next.js
SSR ❌ Нет ❌ Нет ✅ Есть
SEO ❌ Плохое ❌ Плохое ✅ Отличное
Настройка Простая Простая Простая
Маршрутизация Вручную (React Router) Вручную Автоматическая
Размер бандла Большой Маленький Оптимизированный

Создание проекта Next.js

Установка:

npx create-next-app@latest my-next-app
cd my-next-app
npm run dev

Структура проекта:

my-next-app/
├── pages/              # Страницы (маршрутизация)
│   ├── _app.jsx        # Глобальная обёртка
│   ├── index.jsx       # Главная страница ( / )
│   └── about.jsx       # Страница /about
├── public/             # Статические файлы
├── styles/             # Стили (CSS Modules)
├── package.json
└── next.config.js      # Конфигурация

Первый компонент (pages/index.jsx):

export default function Home() {
  return (
    <div>
      <h1>Привет, Next.js!</h1>
      <p>Это SSR-приложение на React</p>
    </div>
  );
}

Важно: ты просто создаёшь файл в pages/ — и он автоматически становится страницей по пути, соответствующему имени файла!

Маршрутизация в Next.js (pages router)

Файловая маршрутизация — просто и удобно:

Файл URL Что рендерится
pages/index.jsx / Главная страница
pages/about.jsx /about Страница «О нас»
pages/blog.jsx /blog Блог
pages/blog/post.jsx /blog/post Конкретный пост
pages/users/[id].jsx /users/123 Динамический параметр

Динамические маршруты:

// pages/users/[id].jsx
import { useRouter } from 'next/router';

export default function UserProfile() {
  const router = useRouter();
  const { id } = router.query;
  
  return <h1>Профиль пользователя {id}</h1>;
}
// /users/123 → id = "123"
Из ноутбука появляются летающие светящиеся экраны

Оживи свой сайт. Освой JavaScript!

Статичная верстка — это только скелет. Наш онлайн-курс "JavaScript с нуля до профи" даст твоим страницам мышцы и нервы. Научись создавать слайдеры, формы, интерактивные карты и получать данные с сервера.

От теории — к реальным скриптам в твоём портфолио.

Подробнее о курсе

Навигация между страницами (Link)

import Link from 'next/link';

export default function Navigation() {
  return (
    <nav>
      <Link href="/">Главная</Link>
      <Link href="/about">О нас</Link>
      <Link href="/blog">Блог</Link>
      <Link href="/users/123">Пользователь 123</Link>
    </nav>
  );
}

Важно: next/link работает как React Router, но с предзагрузкой страниц для мгновенного перехода.

SSR vs SSG vs ISR (три способа рендеринга)

Способ Что происходит Когда использовать
SSR (Server Side Rendering) Рендерится на сервере при каждом запросе Динамические данные, персонализация
SSG (Static Site Generation) Рендерится один раз при сборке Блоги, статические сайты
ISR (Incremental Static Regeneration) Обновляется периодически после сборки Каталоги товаров, новостные сайты

SSG (генерируется при сборке):

// pages/blog.jsx
export async function getStaticProps() {
  // Загружаем данные при сборке
  const response = await fetch('https://api.example.com/posts');
  const posts = await response.json();

  return {
    props: { posts }, // Передаём в компонент
  };
}

export default function Blog({ posts }) {
  return (
    <div>
      <h1>Блог</h1>
      {posts.map(post => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  );
}

SSR (рендерится при каждом запросе):

// pages/dashboard.jsx
export async function getServerSideProps() {
  // Загружаем данные при каждом запросе
  const response = await fetch('https://api.example.com/dashboard');
  const data = await response.json();

  return {
    props: { data },
  };
}

export default function Dashboard({ data }) {
  return <div>Панель управления: {data}</div>;
}

ISR (обновляется периодически):

export async function getStaticProps() {
  const response = await fetch('https://api.example.com/products');
  const products = await response.json();

  return {
    props: { products },
    revalidate: 60, // Пересоздавать страницу каждые 60 секунд
  };
}

Получение данных в Next.js

На клиенте (useEffect, как в обычном React):

import { useState, useEffect } from 'react';

export default function ClientSideData() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(res => res.json())
      .then(setData);
  }, []);

  return <div>{data}</div>;
}

На сервере (getStaticProps / getServerSideProps):

// Страница с данными, полученными на сервере
export async function getStaticProps() {
  const response = await fetch('https://api.example.com/posts');
  const posts = await response.json();

  return {
    props: { posts },
  };
}

export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

API Routes (создание API внутри Next.js)

Next.js позволяет создавать API-эндпоинты прямо в приложении:

// pages/api/users.js
export default function handler(req, res) {
  if (req.method === 'GET') {
    res.status(200).json([
      { id: 1, name: 'Алексей' },
      { id: 2, name: 'Мария' }
    ]);
  } else {
    res.status(405).json({ error: 'Метод не разрешён' });
  }
}
// Теперь доступно по адресу: /api/users

Оптимизация изображений (next/image)

import Image from 'next/image';

export default function Home() {
  return (
    <Image
      src="/images/photo.jpg"
      alt="Описание"
      width={800}
      height={600}
      quality={80}
      priority // Для ключевых изображений (LCP)
    />
  );
}

Что даёт:

  1. Автоматическое сжатие и оптимизация
  2. Lazy loading (по умолчанию)
  3. WebP-формат для поддерживаемых браузеров
  4. Resize на лету

Продвинутые возможности Next.js

Глобальные стили (_app.jsx):

// pages/_app.jsx
import '../styles/globals.css';

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

SEO через next/head:

import Head from 'next/head';

export default function Home() {
  return (
    <>
      <Head>
        <title>Мой сайт | Главная</title>
        <meta name="description" content="Описание страницы" />
        <meta property="og:title" content="Мой сайт" />
      </Head>
      <div>Контент</div>
    </>
  );
}

Middleware (для логирования, авторизации):

// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  const token = request.cookies.get('token');
  
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  
  return NextResponse.next();
}

React Router vs Next.js (сравнение)

Характеристика React Router Next.js
SSR/SSG ❌ Нет ✅ Есть
SEO ❌ Плохое ✅ Отличное
Маршрутизация Ручная (через код) Автоматическая (по папкам)
Настройка Требуется дополнительная Zero Config
Размер бандла Оптимизируется вручную Автоматическая оптимизация
API Routes Нет Есть
Когда использовать SPA, админки, внутренние приложения Публичные сайты, магазины

Частые ошибки новичков

Ошибка Почему Исправление
Используют клиентские API на сервере window, localStorage не существуют на сервере Используй useEffect или проверку typeof window !== 'undefined'
Не используют Link для навигации Полная перезагрузка страницы Используй next/link
Забывают про _app.jsx Глобальные стили не применяются Добавь импорт стилей в _app.jsx
Не оптимизируют изображения Медленная загрузка Используй next/image
Используют getServerSideProps для статики Лишняя нагрузка на сервер Используй getStaticProps

Итог (что мы узнали)

Что узнали Как это работает
SSR Рендеринг на сервере для SEO и скорости
Next.js Фреймворк для React с SSR «из коробки»
Файловая маршрутизация Страницы автоматически по папкам
getStaticProps Генерация статики при сборке
getServerSideProps Рендеринг при каждом запросе
Link Навигация без перезагрузки
API Routes Создание API внутри приложения
ISR Обновление статики периодически

Задание для закрепления (на 2–3 часа)

Создай Next.js-приложение с тремя страницами:

  1. Главная страница (/) — используй getStaticProps для загрузки списка постов с публичного API (например, JSONPlaceholder)
  2. Страница поста (/posts/[id]) — используй getStaticPaths и getStaticProps для генерации страниц всех постов
  3. Страница «О нас» (/about) — статическая страница с SEO-оптимизацией (Head с title и description)

Дополнительно:

  1. Добавь навигацию между страницами через next/link
  2. Используй next/image для аватаров пользователей
  3. Добавь API-роут /api/users, который возвращает список пользователей

Проверка: убедись, что все страницы работают, навигация происходит мгновенно, а при отключённом JavaScript контент всё равно виден (проверь через инспектор «Disable JavaScript»).

Скачать код выполненного задания на GitHub: (откроется в новой вкладке)SSR в Nextjs

Что дальше?

В следующем уроке разберём React Query — мощную библиотеку для работы с серверными данными. Ты узнаешь, как управлять кешированием, перезапросом, пагинацией и оптимистичными обновлениями. Это сделает работу с API простой и эффективной.

Теги: