Вивчай

Deployment

Next.js Deployment — ракета на стартовому майданчику готова до запуску в ранковому світліNext.js Deployment — ракета на стартовому майданчику готова до запуску в ранковому світлі

Це фінальний урок не тільки блоку Next.js, але й всього курсу. Ми пройшли шлях від командного рядка до повноцінного фреймворку. Тепер навчимося робити останній, але найважливіший крок -- вивести проект у світ. Адже код, який ніхто не бачить -- це просто хобі. Код, який працює на сервері -- це продукт.


npm run build -- збірка проекту

Перш ніж деплоїти, потрібно зібрати проект:

npm run build — збірка Next.js з таблицею маршрутівnpm run build — збірка Next.js з таблицею маршрутів

npm run build

Next.js покаже детальний звіт:

Route (app)                    Size     First Load JS
┌ ○ /                          5.2 kB   87.3 kB
├ ○ /about                     1.8 kB   83.9 kB
├ ● /blog                      3.1 kB   85.2 kB
├ ● /blog/[slug]               2.4 kB   84.5 kB
├ ○ /contact                   4.1 kB   86.2 kB
└ λ /api/users                 0 B      0 B

○  (Static)   prerendered as static content
●  (SSG)      prerendered as static HTML (uses generateStaticParams)
λ  (Dynamic)  server-rendered on demand

Символи:

  • Static -- повністю статична сторінка
  • SSG -- статична з даними (generateStaticParams)
  • λ Dynamic -- серверний рендеринг при кожному запиті
Порада

Звертай увагу на First Load JS -- це розмір JavaScript, який завантажує браузер. Тримай його якомога менше. Якщо сторінка важить більше 200 КБ -- час оптимізувати.

Перевірка локально

npm run build && npm start

Це запустить production-сервер на http://localhost:3000. Перевір, що все працює перед деплоєм!


Environment Variables

Секретні ключі та налаштування зберігаються в змінних оточення:

Файли .env

# .env.local -- тільки локально (в .gitignore!)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
API_SECRET_KEY=super-secret-key

# Змінні з NEXT_PUBLIC_ доступні в браузері
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_SITE_NAME=Мій сайт

Серверні vs клієнтські змінні

ПрефіксДоступністьПриклад
Без префіксаТільки серверDATABASE_URL, API_SECRET
NEXT_PUBLIC_Сервер + браузерNEXT_PUBLIC_API_URL
// Server Component або API route -- доступні ВСІ змінні
const dbUrl = process.env.DATABASE_URL; // ✅

// Client Component -- тільки NEXT_PUBLIC_
const apiUrl = process.env.NEXT_PUBLIC_API_URL; // ✅
const dbUrl = process.env.DATABASE_URL; // ❌ undefined
Увага

НІКОЛИ не додавай .env.local в Git! Секретні ключі повинні бути тільки на сервері. У .gitignore вже має бути рядок .env*.local.

Пріоритет файлів

.env                 -- базові значення (в Git)
.env.local           -- локальні override (НЕ в Git)
.env.development     -- тільки для npm run dev
.env.production      -- тільки для npm run build/start

SEO та Metadata

generateMetadata для динамічних сторінок

// src/app/blog/[slug]/page.tsx
import type { Metadata } from "next";

interface Post {
  title: string;
  description: string;
  image: string;
}

async function getPost(slug: string): Promise<Post> {
  // Отримання даних
  return { title: "Мій пост", description: "Опис", image: "/og.jpg" };
}

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>;
}): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);

  return {
    title: post.title,
    description: post.description,
    openGraph: {
      title: post.title,
      description: post.description,
      images: [{ url: post.image, width: 1200, height: 630 }],
    },
    twitter: {
      card: "summary_large_image",
      title: post.title,
      description: post.description,
    },
  };
}

robots.txt

// src/app/robots.ts
import type { MetadataRoute } from "next";

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: "*",
      allow: "/",
      disallow: ["/api/", "/admin/"],
    },
    sitemap: "https://mysite.com/sitemap.xml",
  };
}

sitemap.xml

// src/app/sitemap.ts
import type { MetadataRoute } from "next";

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getAllPosts();

  const postUrls = posts.map((post) => ({
    url: `https://mysite.com/blog/${post.slug}`,
    lastModified: post.updatedAt,
    changeFrequency: "weekly" as const,
    priority: 0.8,
  }));

  return [
    {
      url: "https://mysite.com",
      lastModified: new Date(),
      changeFrequency: "yearly",
      priority: 1,
    },
    {
      url: "https://mysite.com/about",
      lastModified: new Date(),
      changeFrequency: "monthly",
      priority: 0.5,
    },
    ...postUrls,
  ];
}

async function getAllPosts() {
  return [
    { slug: "hello", updatedAt: new Date() },
    { slug: "nextjs", updatedAt: new Date() },
  ];
}

Деплой на Vercel

Vercel -- це платформа від творців Next.js. Деплой максимально простий:

1. Підключи GitHub репозиторій

  1. Зайди на vercel.com та створи акаунт (через GitHub)
  2. Натисни "New Project"
  3. Обери свій GitHub репозиторій
  4. Vercel автоматично визначить Next.js проект

2. Налаштуй environment variables

В налаштуваннях проекту на Vercel додай всі змінні з .env.local:

DATABASE_URL = postgresql://...
API_SECRET_KEY = ...
NEXT_PUBLIC_API_URL = https://api.example.com

3. Деплой!

Натисни "Deploy" -- і через хвилину твій сайт доступний за URL виду my-app.vercel.app.

Автоматичний деплой: кожен push в main автоматично деплоїть нову версію. Pull request'и отримують preview URL для тестування.


Деплой на Netlify

Netlify -- популярна альтернатива Vercel:

1. Створи netlify.toml

# netlify.toml
[build]
  command = "npm run build"
  publish = ".next"

[[plugins]]
  package = "@netlify/plugin-nextjs"

2. Встанови плагін

npm install -D @netlify/plugin-nextjs

3. Підключи репозиторій

  1. Зайди на netlify.com
  2. "New site from Git" → обери репозиторій
  3. Додай environment variables в налаштуваннях
  4. Deploy!
Інфо

Vercel має нативну підтримку Next.js (бо це їхній продукт), тому деякі фічі (Edge Functions, ISR) працюють "з коробки". На Netlify потрібен плагін @netlify/plugin-nextjs.


Checklist перед деплоєм

Перед тим як випускати проект у світ, перевір:

Функціональність

  • npm run build проходить без помилок
  • Всі сторінки працюють коректно
  • Форми відправляються правильно
  • API routes повертають очікувані дані
  • Навігація працює між всіма сторінками

Оптимізація

  • Зображення використовують next/image
  • Шрифти підключені через next/font
  • First Load JS менше 200 КБ на сторінку
  • Немає зайвого "use client" (тільки де потрібна інтерактивність)

SEO

  • Кожна сторінка має title та description
  • Open Graph метадані для соцмереж
  • robots.ts налаштований
  • sitemap.ts генерується

Безпека

  • .env.local НЕ в Git
  • Секретні ключі тільки без NEXT_PUBLIC_ префікса
  • API routes валідують вхідні дані
  • Environment variables налаштовані на хостингу

Якість

  • Немає помилок у консолі
  • Responsive дизайн (перевірити на мобільних)
  • Favicon додано
  • 404 сторінка оформлена

Підсумок блоку Next.js

За 8 уроків ми пройшли повний цикл Next.js розробки:

  1. Routing -- file-based маршрутизація, Link, dynamic routes
  2. Data Fetching -- SSG, SSR, ISR, getStaticProps/getServerSideProps
  3. Dynamic Routes -- getStaticPaths, generateStaticParams, fallback
  4. API Routes -- серверні endpoints, CRUD, валідація
  5. App Router -- Server/Client Components, layouts, streaming
  6. Data Fetching в App Router -- async components, кешування, Server Actions
  7. Стилізація -- CSS Modules, Tailwind, next/font, next/image
  8. Deployment -- збірка, env variables, SEO, деплой

Підсумок всього курсу

Ти пройшов шлях від cd та ls до повноцінного Next.js додатку. Давай згадаємо:

  • Block 1: Термінал, Git, GitHub -- інструменти розробника
  • Block 2: HTML -- структура вебсторінок
  • Block 3: CSS -- стилізація та responsive дизайн
  • Block 4: JavaScript Basics -- змінні, функції, масиви, об'єкти
  • Block 5: JavaScript & DOM -- інтерактивність у браузері
  • Block 6: JavaScript Advanced -- async, fetch, модулі, класи
  • Block 7: TypeScript -- типізація для надійного коду
  • Block 8: React -- компоненти, стейт, хуки, SPA
  • Block 9: Next.js -- SSR, SSG, API, деплой

Це фундамент, на якому будується кар'єра веб-розробника. Далі -- практика, власні проекти, і постійне навчання.

Порада

Найкращий спосіб закріпити знання -- створити власний проект. Портфоліо, блог, інтернет-магазин -- неважливо що, головне -- використай все, що вивчив.

Інфо

Що вивчати далі: