Структура страниц

В этом разделе описывается структура страниц в Boilerplate, основанная на App Router в Next.js 15. Вы узнаете, как создавать и организовывать страницы вашего приложения.

Обзор структуры страниц

В Boilerplate используется App Router от Next.js, который основан на файловой системе. Каждая папка представляет собой сегмент пути URL, а файлы внутри этих папок определяют, что будет отображаться на соответствующих маршрутах.

Основные страницы

В проекте доступны следующие основные страницы:

  • /app/(landing)/page.tsx → Главная страница (Landing)
  • /app/dashboard/page.tsx → Панель управления
  • /app/blog/page.tsx → Блог
  • /app/docs/page.tsx → Документация

Создание новой страницы

Чтобы создать новую страницу, вам нужно:

  1. Создать новую папку в директории app с именем маршрута.

  2. Создать файл page.tsx внутри этой папки.

  3. Опционально: создать файл layout.tsx для определения уникального макета.

Пример создания новой страницы:

tsx
// app/about/page.tsx
export default function AboutPage() {
  return (
    <div className="container py-8">
      <h1 className="text-3xl font-bold mb-4">О нас</h1>
      <p>
        Информация о компании и проекте.
      </p>
    </div>
  );
}

Группировка маршрутов

В Next.js App Router вы можете группировать маршруты с помощью круглых скобок, не влияя на фактический URL. Например, в Boilerplate страница landing использует группировку:

text
app/
├── (landing)/
│   └── page.tsx      // Доступ по URL: /
├── dashboard/
│   └── page.tsx      // Доступ по URL: /dashboard
└── blog/
    └── page.tsx      // Доступ по URL: /blog

Группировка также позволяет разделять маршруты с разными макетами, что активно используется в Boilerplate.

Серверные и клиентские компоненты

По умолчанию все компоненты в App Router являются серверными. Для клиентских компонентов используйте директиву 'use client':

tsx
// app/example/page.tsx
import { ServerComponent } from "./ServerComponent";
import { ClientComponent } from "./ClientComponent";

export default function Page() {
  return (
    <div>
      <ServerComponent />
      <ClientComponent />
    </div>
  );
}
tsx
// app/example/ClientComponent.tsx
"use client";

import { useState } from "react";

export function ClientComponent() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Счётчик: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Увеличить
      </button>
    </div>
  );
}

Загрузка данных

В серверных компонентах вы можете асинхронно загружать данные:

tsx
// app/users/page.tsx
import { getUsers } from "@/lib/api";

export default async function UsersPage() {
  // Данные загружаются на сервере
  const users = await getUsers();
  
  return (
    <div>
      <h1>Пользователи</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

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

Для создания динамических маршрутов используются квадратные скобки:

text
app/
├── blog/
│   ├── page.tsx           // Доступ по URL: /blog
│   └── [slug]/
│       └── page.tsx       // Доступ по URL: /blog/:slug

Пример компонента для динамического маршрута:

tsx
// app/blog/[slug]/page.tsx
interface BlogPostPageProps {
  params: {
    slug: string;
  };
}

export default function BlogPostPage({ params }: BlogPostPageProps) {
  return (
    <div>
      <h1>Статья: {params.slug}</h1>
      {/* Загрузка и отображение контента статьи */}
    </div>
  );
}

Организация компонентов для страниц

В Boilerplate компоненты, относящиеся к конкретной странице, размещаются в папке _components внутри директории страницы:

text
app/
├── dashboard/
│   ├── _components/
│   │   ├── DashboardHeader.tsx
│   │   └── DashboardSidebar.tsx
│   └── page.tsx

Это помогает лучше организовать код и отделить компоненты для конкретной страницы от общих компонентов приложения.

Метаданные страниц

Для добавления метаданных (заголовок, описание и т.д.) используйте объект metadata:

tsx
// app/about/page.tsx
import { Metadata } from "next";

export const metadata: Metadata = {
  title: "О нас | Мой проект",
  description: "Информация о нашем проекте и компании",
  openGraph: {
    title: "О нас | Мой проект",
    description: "Информация о нашем проекте и компании",
    images: ["/images/about-og.jpg"],
  },
};

export default function AboutPage() {
  // ...содержимое страницы
}