Разработка22 марта 2026 16 мин

Next.js за 1 день: от нуля до деплоя

Create app, роутинг, серверные и клиентские компоненты, Tailwind CSS, деплой на Vercel — полный практический гайд.

Почему Next.js

Next.js — это React-фреймворк номер один в мире. Его используют Vercel, Netflix, TikTok, Twitch, Hulu и тысячи стартапов. В 2026 году это стандарт де-факто для веб-разработки.

Что даёт Next.js поверх React:

  • Серверный рендеринг (SSR) — страницы быстро загружаются и индексируются поисковиками
  • Файловый роутинг — создал файл = создал страницу
  • API Routes — бэкенд прямо в проекте
  • Server Components — компоненты работают на сервере (меньше JS на клиенте)
  • Image Optimization — автоматическая оптимизация картинок
  • Деплой в 1 клик на Vercel

К концу этой статьи вы создадите полноценное приложение и задеплоите его.

Подготовка

Убедитесь, что установлен Node.js:

node --version  # v20+ или v22+
npm --version   # 10+

Если нет — скачайте с nodejs.org.

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

npx create-next-app@latest my-app

На вопросы отвечайте:

  • TypeScript? → Yes
  • ESLint? → Yes
  • Tailwind CSS? → Yes
  • src/ directory? → Yes
  • App Router? → Yes
  • Import alias? → @/* (по умолчанию)
cd my-app
npm run dev

Откройте http://localhost:3000 — вы увидите стартовую страницу Next.js.

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

my-app/
├── src/
│   └── app/
│       ├── layout.tsx      # Корневой лейаут (шаблон)
│       ├── page.tsx         # Главная страница (/)
│       ├── globals.css      # Глобальные стили
│       ├── about/
│       │   └── page.tsx     # Страница /about
│       └── api/
│           └── hello/
│               └── route.ts # API эндпоинт /api/hello
├── public/                  # Статические файлы
├── tailwind.config.ts       # Конфиг Tailwind
├── tsconfig.json
└── package.json

Главное правило: Каждая папка в app/ = маршрут. Файл page.tsx = страница.

Роутинг

Статические страницы

Создайте файл — получите страницу:

src/app/about/page.tsx     → /about
src/app/blog/page.tsx      → /blog
src/app/contact/page.tsx   → /contact
// src/app/about/page.tsx
export default function AboutPage() {
  return (
    <div className="max-w-2xl mx-auto p-8">
      <h1 className="text-3xl font-bold mb-4">О нас</h1>
      <p className="text-gray-600">
        Мы создаём продукты с помощью ИИ.
      </p>
    </div>
  )
}

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

Для страниц вроде /blog/my-article используйте квадратные скобки:

// src/app/blog/[slug]/page.tsx
interface Props {
  params: Promise<{ slug: string }>
}

export default async function BlogPost({ params }: Props) {
  const { slug } = await params
  return (
    <div className="max-w-2xl mx-auto p-8">
      <h1 className="text-3xl font-bold">Статья: {slug}</h1>
    </div>
  )
}

Теперь /blog/hello, /blog/world, /blog/любой-текст — всё работает.

Вложенные лейауты

Лейаут — это обёртка, общая для всех страниц в папке:

// src/app/blog/layout.tsx
export default function BlogLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div className="flex">
      <aside className="w-64 p-4 border-r">
        <nav>
          <a href="/blog" className="block mb-2">Все статьи</a>
          <a href="/blog/categories" className="block mb-2">Категории</a>
        </nav>
      </aside>
      <main className="flex-1 p-8">{children}</main>
    </div>
  )
}

Все страницы внутри /blog/ будут иметь сайдбар.

Server Components vs Client Components

Это ключевая концепция Next.js 15.

Server Components (по умолчанию)

Каждый компонент по умолчанию — серверный. Он рендерится на сервере и отправляет готовый HTML клиенту. Никакого JavaScript на клиенте.

// Server Component (по умолчанию)
// Можно делать fetch, обращаться к БД, читать файлы
async function UserList() {
  const users = await fetch('https://api.example.com/users')
  const data = await users.json()

  return (
    <ul>
      {data.map((user: any) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  )
}

Client Components

Когда нужна интерактивность (клики, формы, useState), добавьте "use client":

'use client'

import { useState } from 'react'

export function Counter() {
  const [count, setCount] = useState(0)

  return (
    <button
      onClick={() => setCount(count + 1)}
      className="px-4 py-2 bg-blue-600 text-white rounded"
    >
      Нажатий: {count}
    </button>
  )
}

Правило: Используйте Server Components везде, где возможно. Client Components — только для интерактивности.

Tailwind CSS

Tailwind уже настроен в проекте. Стилизуйте прямо в className:

export default function Card() {
  return (
    <div className="bg-white rounded-2xl shadow-lg p-6
                    hover:shadow-xl transition-shadow duration-300
                    border border-gray-100">
      <h2 className="text-xl font-bold text-gray-900 mb-2">
        Заголовок карточки
      </h2>
      <p className="text-gray-600 leading-relaxed">
        Описание карточки с полезным контентом.
      </p>
      <button className="mt-4 px-6 py-2 bg-gradient-to-r
                         from-purple-600 to-blue-600 text-white
                         rounded-lg font-medium
                         hover:from-purple-700 hover:to-blue-700
                         transition-all duration-200">
        Подробнее
      </button>
    </div>
  )
}

Полезные классы Tailwind:

| Класс | Описание | |-------|----------| | max-w-7xl mx-auto | Контейнер с центровкой | | flex items-center gap-4 | Flexbox с центровкой | | grid grid-cols-3 gap-6 | CSS Grid 3 колонки | | text-lg font-semibold | Размер и жирность текста | | bg-gradient-to-r from-X to-Y | Градиент | | hover:scale-105 transition | Анимация при наведении | | dark:bg-gray-900 | Тёмная тема |

API Routes

Бэкенд прямо в Next.js проекте:

// src/app/api/generate/route.ts
import { NextRequest, NextResponse } from 'next/server'
import Anthropic from '@anthropic-ai/sdk'

const anthropic = new Anthropic()

export async function POST(request: NextRequest) {
  const { prompt } = await request.json()

  const message = await anthropic.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    messages: [{ role: 'user', content: prompt }],
  })

  return NextResponse.json({
    text: message.content[0].type === 'text'
      ? message.content[0].text
      : '',
  })
}

Вызов из клиентского компонента:

'use client'
import { useState } from 'react'

export function AIForm() {
  const [result, setResult] = useState('')
  const [loading, setLoading] = useState(false)

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault()
    setLoading(true)
    const formData = new FormData(e.currentTarget)
    const prompt = formData.get('prompt') as string

    const res = await fetch('/api/generate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ prompt }),
    })
    const data = await res.json()
    setResult(data.text)
    setLoading(false)
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <textarea
        name="prompt"
        className="w-full p-3 border rounded-lg"
        placeholder="Введите промпт..."
        rows={3}
      />
      <button
        type="submit"
        disabled={loading}
        className="px-6 py-2 bg-blue-600 text-white rounded-lg
                   disabled:opacity-50"
      >
        {loading ? 'Генерация...' : 'Сгенерировать'}
      </button>
      {result && (
        <div className="p-4 bg-gray-50 rounded-lg whitespace-pre-wrap">
          {result}
        </div>
      )}
    </form>
  )
}

Собираем мини-проект: AI Landing Generator

Давайте создадим реальное приложение — генератор лендингов на базе ИИ.

Структура:

src/app/
├── layout.tsx          # Навигация
├── page.tsx            # Главная (форма)
├── result/
│   └── page.tsx        # Результат генерации
└── api/
    └── generate/
        └── route.ts    # API для генерации

Главная страница:

// src/app/page.tsx
import { AIForm } from '@/components/AIForm'

export default function Home() {
  return (
    <main className="min-h-screen bg-gradient-to-b
                     from-gray-900 to-gray-800">
      <div className="max-w-3xl mx-auto px-4 py-20">
        <h1 className="text-5xl font-bold text-white text-center mb-4">
          AI Landing Generator
        </h1>
        <p className="text-xl text-gray-400 text-center mb-12">
          Опишите ваш продукт — получите готовый лендинг за 30 секунд
        </p>
        <AIForm />
      </div>
    </main>
  )
}

Навигация в layout:

// src/app/layout.tsx
import type { Metadata } from 'next'
import './globals.css'

export const metadata: Metadata = {
  title: 'AI Landing Generator',
  description: 'Генерируй лендинги с помощью ИИ',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="ru">
      <body>
        <nav className="bg-gray-900 border-b border-gray-800 px-6 py-4">
          <div className="max-w-7xl mx-auto flex justify-between items-center">
            <a href="/" className="text-xl font-bold text-white">
              LandingAI
            </a>
            <div className="flex gap-6">
              <a href="/" className="text-gray-300 hover:text-white">
                Генератор
              </a>
              <a href="/about" className="text-gray-300 hover:text-white">
                О проекте
              </a>
            </div>
          </div>
        </nav>
        {children}
      </body>
    </html>
  )
}

Деплой на Vercel

Через GitHub (рекомендуется):

  1. Создайте репозиторий на GitHub
  2. Запушьте код:
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/my-app.git
git push -u origin main
  1. Зайдите на vercel.com → New Project → Import from GitHub
  2. Выберите репозиторий → Deploy
  3. Через 1 минуту — ваше приложение на my-app.vercel.app

Через CLI:

npm install -g vercel
vercel

Ответьте на вопросы → деплой за 30 секунд.

Environment Variables:

Если у вас есть API-ключи (Claude API, Stripe и т.д.):

  1. Vercel Dashboard → Project → Settings → Environment Variables
  2. Добавьте переменные (ANTHROPIC_API_KEY, DATABASE_URL и т.д.)
  3. Redeploy

Чек-лист после деплоя

  • [ ] Все страницы открываются
  • [ ] Формы работают
  • [ ] API-routes отвечают
  • [ ] Изображения загружаются
  • [ ] Мета-теги корректные (title, description)
  • [ ] Адаптивность на мобильных
  • [ ] Performance в Lighthouse > 90

Что дальше

Вы освоили основы Next.js за 1 день. Вот что изучить дальше:

  1. Server Actions — формы без API routes
  2. Middleware — перехват запросов (авторизация, редиректы)
  3. Metadata API — динамические SEO-теги
  4. Parallel Routes — несколько страниц в одном лейауте
  5. Streaming — поэтапная загрузка контента

Ресурсы:

  • nextjs.org/docs — официальная документация
  • nextjs.org/learn — интерактивный курс
  • Vercel YouTube — видеоуроки

Хочешь изучить это глубже? Смотри наш курс — за неделю ты будешь создавать полноценные SaaS-приложения на Next.js с ИИ.

Понравилась статья?

Переходи от чтения к практике. 7-дневный челлендж — бесплатно.

Блог NEURO BRATVA — статьи про AI, вайбкодинг и заработок на ИИ