Перейти к содержимому

4. Страницы и маршрутизация

Astro использует файловую систему роутинга — структура файлов в директории src/pages/ автоматически определяет URL-маршруты вашего сайта. Это простой и интуитивный подход: создал файл — получил маршрут.

Каждый файл в src/pages/ становится отдельной страницей:

src/pages/
├── index.astro → /
├── about.astro → /about
├── contact.astro → /contact
├── blog/
│ ├── index.astro → /blog
│ ├── post-1.astro → /blog/post-1
│ └── [slug].astro → /blog/:slug (динамический)
└── [...path].astro → /* (catch-all)

Поддерживаемые форматы страниц:

  • .astro — Astro компоненты
  • .md / .mdx — Markdown страницы
  • .html — обычный HTML
  • .js / .ts — API эндпоинты

Самый простой случай — файл с фиксированным именем:

src/pages/about.astro
---
// Этот файл будет доступен по адресу /about
import Layout from '../layouts/Layout.astro';
const team = [
{ name: 'Алексей', role: 'Frontend' },
{ name: 'Мария', role: 'Design' },
];
---
<Layout title="О нас">
<h1>О нашей команде</h1>
<ul>
{team.map(member => (
<li>{member.name} — {member.role}</li>
))}
</ul>
</Layout>

Квадратные скобки в имени файла создают динамический параметр:

src/pages/blog/[slug].astro
---
// Доступен по: /blog/hello-world, /blog/my-post, /blog/любой-текст
import type { GetStaticPaths } from 'astro';
export const getStaticPaths = (async () => {
// Возвращаем все возможные значения параметра
return [
{ params: { slug: 'hello-world' } },
{ params: { slug: 'astro-review' } },
{ params: { slug: 'web-performance' } },
];
}) satisfies GetStaticPaths;
// Получаем текущий параметр
const { slug } = Astro.params;
---
<h1>Статья: {slug}</h1>

Обычно getStaticPaths используется вместе с загрузкой данных:

---
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post }, // Передаём данные через props
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<h1>{post.data.title}</h1>
<Content />

Три точки создают catch-all параметр, который совпадает с любым путём:

src/pages/docs/[...path].astro
---
// Совпадает с: /docs/intro, /docs/api/auth, /docs/a/b/c/d
const { path } = Astro.params;
// path = 'intro' | 'api/auth' | 'a/b/c/d'
const segments = path?.split('/') ?? [];
---
<nav>
{segments.map((seg, i) => <span>{seg}{i < segments.length-1 ? ' / ' : ''}</span>)}
</nav>
src/pages/404.astro
---
// Автоматически показывается при 404 ошибке
---
<html lang="ru">
<head><title>Страница не найдена</title></head>
<body>
<h1>404 — Страница не найдена</h1>
<a href="/">На главную</a>
</body>
</html>
src/pages/
├── index.astro → / (главная сайта)
└── blog/
└── index.astro → /blog (главная блога)
---
// Доступ к ?page=2&sort=date
const url = new URL(Astro.request.url);
const page = url.searchParams.get('page') ?? '1';
const sort = url.searchParams.get('sort') ?? 'date';
---
<p>Страница: {page}, Сортировка: {sort}</p>
src/pages/[category]/[slug].astro → /tech/astro-guide, /news/latest
src/pages/[lang]/[...rest].astro → /ru/blog/post, /en/docs/api
src/pages/[category]/[slug].astro
---
const { category, slug } = Astro.params;
export async function getStaticPaths() {
return [
{ params: { category: 'tech', slug: 'astro-guide' } },
{ params: { category: 'news', slug: 'latest' } },
];
}
---
<h1>{category} / {slug}</h1>

Кликайте на файлы в дереве, чтобы увидеть соответствующие URL-маршруты: