Маршрутизация
Astro использует маршрутизацию на основе файлов для генерации URL-адресов ваших сборок на основе схемы расположения файлов в каталоге src/pages/
вашего проекта.
Навигация между страницами
Заголовок раздела Навигация между страницамиAstro использует стандартные HTML-элементы <a>
для навигации между маршрутами. Нет специфического для фреймворка компонента <Link>
.
<p>Читайте далее <a href="/about/">об</a> Astro!</p>
<!-- С настроенной опцией `base: "/docs"` --><p>Узнайте больше в нашем <a href="/docs/reference/">справочнике</a>!</p>
Статические маршруты
Заголовок раздела Статические маршрутыКомпоненты страниц .astro
, а также Markdown и MDX файлы (.md
, .mdx
) в директории src/pages/
автоматически становятся страницами вашего сайта. Маршрут каждой страницы соответствует ее пути и имени файла в каталоге src/pages/
.
# Пример: Статические маршрутыsrc/pages/index.astro -> mysite.com/src/pages/about.astro -> mysite.com/aboutsrc/pages/about/index.astro -> mysite.com/aboutsrc/pages/about/me.astro -> mysite.com/about/mesrc/pages/posts/1.md -> mysite.com/posts/1
В проекте Astro нет отдельного “конфигурационного файла маршрутизации”! Когда вы добавляете файл в директорию src/pages/
, для вас автоматически создается новый маршрут. В статических сборках вы можете настроить формат вывода файлов с помощью опции build.format
(EN).
Динамические маршруты
Заголовок раздела Динамические маршрутыВ имени файла страницы Astro могут быть указаны параметры динамического маршрута для создания нескольких подходящих страниц. Например, src/pages/authors/[author].astro
генерирует биографическую страницу для каждого автора в вашем блоге. author
становится параметром, к которому вы можете обращаться внутри страницы.
В стандартном режиме статического вывода Astro эти страницы генерируются во время сборки, поэтому вы должны заранее определить список авторов
, которые получат соответствующий файл. В режиме SSR страница будет генерироваться по запросу для любого маршрута, который соответствует.
Статический (SSG) режим
Заголовок раздела Статический (SSG) режимПоскольку все маршруты должны быть определены во время сборки, динамический маршрут должен экспортировать функцию getStaticPaths()
, которая возвращает массив объектов со свойством params
. Каждый из этих объектов будет генерировать соответствующий маршрут.
[dog].astro
определяет динамический параметр dog
в своем имени, поэтому объекты, возвращаемые getStaticPaths()
, должны включать dog
в свои params
. Затем страница может получить доступ к этому параметру с помощью Astro.params
.
---export function getStaticPaths() { return [ { params: { dog: "clifford" }}, { params: { dog: "rover" }}, { params: { dog: "spot" }}, ];}
const { dog } = Astro.params;---<div>Good dog, {dog}!</div>
В результате будут сгенерированы три страницы: /dogs/clifford
, /dogs/rover
и /dogs/spot
, каждая из которых отображает соответствующее имя собаки.
Имя файла может включать несколько параметров, которые должны быть включены в объекты params
в getStaticPaths()
:
---export function getStaticPaths () { return [ { params: { lang: "en", version: "v1" }}, { params: { lang: "fr", version: "v2" }}, ];}
const { lang, version } = Astro.params;---
В результате будут сгенерированы /en-v1/info
и /fr-v2/info
.
Параметры могут быть включены в отдельные части пути. Например, файл src/pages/[lang]/[version]/info.astro
с тем же getStaticPaths()
, что и выше, сгенерирует маршруты /en/v1/info
и /fr/v2/info
.
Декодирование params
Заголовок раздела Декодирование paramsПараметры, переданные функции getStaticPaths()
, не декодируются. Используйте функцию decodeURI
, когда вам нужно декодировать значения параметров.
---export function getStaticPaths() { return [ { params: { slug: decodeURI("%5Bpage%5D") }}, // декодирует в "[page]" ]}---
getStaticPaths()
(EN).

Rest параметры
Заголовок раздела Rest параметрыЕсли вам нужна большая гибкость в маршрутизации URL, вы можете использовать rest параметры ([...path]
) в имени файла .astro
для сопоставления путей файлов любой глубины:
---export function getStaticPaths() { return [ { params: { path: "one/two/three" }}, { params: { path: "four" }}, { params: { path: undefined }} ]}
const { path } = Astro.params;---...
Это сгенерирует /sequences/one/two/three
, /sequences/four
и /sequences
. (Установка параметра rest в значение undefined
позволяет ему соответствовать странице верхнего уровня).
Параметры rest можно использовать с другими именованными параметрами. Например, просмотрщик файлов GitHub может быть представлен следующим динамическим маршрутом:
/[org]/[repo]/tree/[branch]/[...file]
В этом примере запрос на /withastro/astro/tree/main/docs/public/favicon.svg
будет разбит на следующие именованные параметры:
{ org: "withastro", repo: "astro", branch: "main", file: "docs/public/favicon.svg"}
Пример: Динамические страницы на нескольких уровнях
Заголовок раздела Пример: Динамические страницы на нескольких уровняхВ следующем примере параметр rest ([...slug]
) и функция props
(EN) в getStaticPaths()
генерируют страницы для слагов разной глубины.
---export function getStaticPaths() { const pages = [ { slug: undefined, title: "Магазин Astro", text: "Добро пожаловать в магазин Astro!", }, { slug: "products", title: "Продукты Astro", text: "У нас есть множество продуктов для вас", }, { slug: "products/astro-handbook", title: "Исчерпывающее руководство по Astro", text: "Если вы хотите изучить Astro, обязательно прочитайте эту книгу.", }, ];
return pages.map(({ slug, title, text }) => { return { params: { slug }, props: { title, text }, }; });}
const { title, text } = Astro.props;---<html> <head> <title>{title}</title> </head> <body> <h1>{title}</h1> <p>{text}</p> </body></html>
Режим серверного рендеринга (SSR)
Заголовок раздела Режим серверного рендеринга (SSR)В режиме SSR (EN) динамические маршруты определяются точно так же: включите в имена файлов скобки [param]
или [...path]
для соответствия произвольным строкам или путям. Но поскольку маршруты больше не строятся заранее, страница будет обслуживаться по любому подходящему маршруту. Поскольку это не “статические” маршруты, getStaticPaths
не следует использовать.
Для маршрутов, отображаемых по запросу, в имени файла может использоваться только один параметр rest с использованием spread-нотации (например, src/pages/[locale]/[...slug].astro
или src/pages/[...locale]/[slug].astro
, но не src/pages/[...locale]/[...slug].astro
).
---const { resource, id } = Astro.params;---<h1>{resource}: {id}</h1>
Эта страница будет предоставлена для любого значения resource
и id
: resources/users/1
, resources/colors/blue
и т. д.
Модификация примера [...slug]
для SSR
Заголовок раздела Модификация примера [...slug] для SSRПоскольку страницы SSR не могут использовать getStaticPaths()
, они не могут получать props. Предыдущий пример может быть адаптирован для режима SSR путем поиска значения параметра slug
в объекте. Если маршрут находится в корне (”/”), параметр slug будет иметь значение undefined
. Если значение не существует в объекте, мы перенаправляем на страницу 404.
---const pages = [ { slug: undefined, title: "Магазин Astro", text: "Добро пожаловать в магазин Astro!", }, { slug: "products", title: "Продукты Astro", text: "У нас есть множество продуктов для вас", }, { slug: "products/astro-handbook", title: "Исчерпывающее руководство по Astro", text: "Если вы хотите изучить Astro, обязательно прочитайте эту книгу.", }];
const { slug } = Astro.params;const page = pages.find((page) => page.slug === slug);if (!page) return Astro.redirect("/404");const { title, text } = page;---<html><head> <title>{title}</title></head><body> <h1>{title}</h1> <p>{text}</p></body></html>
Переадресация
Заголовок раздела ПереадресацияИногда вам нужно перенаправить читателей на новую страницу, либо постоянно, потому что структура сайта изменилась, либо в ответ на действие, такое как вход в авторизованный маршрут.
Вы можете определить правила для перенаправления пользователей на постоянно перемещаемые страницы в конфигурации Astro. Или перенаправлять пользователей динамически по мере использования ими вашего сайта.
Настроенные переадресации
Заголовок раздела Настроенные переадресации
Добавлено в:
astro@2.9.0
Вы можете указать отображение постоянных переадресаций в конфигурации Astro с помощью значения redirects
(EN).
Для внутренних перенаправлений это сопоставление старого пути маршрута с новым. Начиная с Astro v5.2.0, также можно перенаправлять на внешние URL-адреса, начинающиеся с http
или https
, которые могут быть обработаны.
import { defineConfig } from 'astro/config';
export default defineConfig({ redirects: { "/old-page": "/new-page", "/blog": "https://example.com/blog" }});
Эти перенаправления следуют тем же правилам приоритета, что и маршруты на основе файлов и всегда будут иметь более низкий приоритет, чем существующий файл страницы с тем же именем в вашем проекте. Например, /old-page
не будет перенаправлено на /new-page
, если в вашем проекте содержится файл src/pages/old-page.astro
.
Динамические маршруты разрешены, при условии, что как новые, так и старые маршруты содержат одни и те же параметры, например:
{ "/blog/[...slug]": "/articles/[...slug]"}
Используя SSR или статический адаптер, вы также можете предоставить объект в качестве значения, что позволит вам указать код ответа status
в дополнение к новому адресу destination
:
import { defineConfig } from 'astro/config';
export default defineConfig({ redirects: { "/old-page": { status: 302, destination: "/new-page" }, "/news": { status: 302, destination: "https://example.com/news" } }});
При запуске astro build
, Astro по умолчанию выводит HTML-файлы с тегом meta refresh. Поддерживаемые адаптеры вместо этого будут выводить конфигурационный файл хоста с переадресацией.
По умолчанию код состояния будет 301
. При сборке в HTML-файлы код состояния не используется сервером.
Динамические переадресации
Заголовок раздела Динамические переадресацииВ глобальном объекте Astro
метод Astro.redirect
позволяет динамически перенаправлять на другую страницу. Вы можете сделать это после проверки того, вошел ли пользователь в систему, получив его сессию из куки.
---import { isLoggedIn } from '../utils';
const cookie = Astro.request.headers.get('cookie');
// Если пользователь не вошел в систему, перенаправляем его на страницу входаif (!isLoggedIn(cookie)) { return Astro.redirect("/login");}---
Переписывания
Заголовок раздела Переписывания
Добавлено в:
astro@4.13.0
Переписывание позволяет вам обслуживать другой маршрут без перенаправления браузера на другую страницу. Браузер будет показывать оригинальный адрес в строке URL, но вместо этого отобразит содержимое URL, предоставленного функции Astro.rewrite()
.
Для контента, который был перемещен навсегда, или для перенаправления пользователя на другую страницу с новым URL (например, на панель управления пользователя после входа в систему), используйте перенаправление.
Переписывания могут быть полезны для отображения одного и того же контента по нескольким путям (например, /products/shoes/men/
и /products/men/shoes/
), не требуя поддерживать два разных исходных файла.
Переписывания также полезны для SEO и пользовательского опыта. Они позволяют отображать контент, который в противном случае потребовал бы перенаправления вашего посетителя на другую страницу или вернул бы статус 404. Одним из распространённых способов использования переписываний является отображение одного и того же локализованного контента для различных вариантов языка.
Следующий пример использует переписывание для отображения версии страницы /es/
, когда посещается URL-путь /es-CU/
(кубинский испанский). Когда посетитель переходит по URL-адресу /es-cu/articles/introduction
, Astro отобразит содержимое, сгенерированное файлом src/pages/es/articles/introduction.astro
.
---return Astro.rewrite("/es/articles/introduction");---
Используйте context.rewrite()
в ваших файлах эндпойнтов, чтобы перенаправить на другую страницу:
export function GET(context) { if (!context.locals.allowed) { return context.rewrite("/"); }}
Если URL, переданный в Astro.rewrite()
, вызывает ошибку во время выполнения, Astro покажет ошибку в виде наложения в режиме разработки и вернет код состояния 500 в продакшен-среде. Если URL не существует в вашем проекте, будет возвращен код состояния 404.
Вы можете намеренно создать переписывание для отображения вашей страницы /404
, например, чтобы указать, что продукт в вашем интернет-магазине больше недоступен:
---const { item } = Astro.params;
if (!itemExists(item)) { return Astro.rewrite("/404");}---
Вы также можете условно переписывать на основе статуса HTTP-ответа, например, чтобы отобразить определённую страницу на вашем сайте при посещении URL, который не существует:
export const onRequest = async (context, next) => { const response = await next(); if (response.status === 404) { return context.rewrite("/"); } return response;}
Перед отображением содержимого из указанного пути переписывания функция Astro.rewrite()
запустит новую полную фазу отрисовки. Это повторно выполнит любой мидлвар для нового маршрута/запроса.
Astro.rewrite()
для получения дополнительной информации.
Порядок приоритетов маршрутов
Заголовок раздела Порядок приоритетов маршрутовВозможно, что несколько определённых маршрутов будут пытаться построить один и тот же путь URL. Например, все эти маршруты могут построить /posts/create
:
Директорияsrc/pages/
- […slug].astro
Директорияposts/
- create.astro
- [page].astro
- [pid].ts
- […slug].astro
Astro необходимо знать, какой маршрут должен быть использован для создания страницы. Для этого он сортирует их по порядку в соответствии со следующими правилами:
- Зарезервированные маршруты Astro
- Маршруты с большим количеством сегментов пути будут иметь приоритет перед менее специфичными маршрутами. В приведенном выше примере все маршруты в разделе
/posts/
имеют приоритет над корневым/[...slug].astro
. - Статические маршруты без параметров пути будут иметь приоритет над динамическими маршрутами. Например,
/posts/create.astro
имеет приоритет над всеми остальными маршрутами в примере. - Динамические маршруты с именованными параметрами имеют приоритет над остальными параметрами. Например,
/posts/[page].astro
имеет приоритет над/posts/[...slug].astro
. - Предрендеренные динамические маршруты имеют приоритет над серверными динамическими маршрутами.
- Эндпоинты имеют приоритет над страницами.
- Маршруты на основе файлов имеют приоритет над перенаправлениями.
- Если ни одно из вышеперечисленных правил не определяет порядок, маршруты сортируются в алфавитном порядке на основе локали по умолчанию вашей установки Node.
Учитывая приведённый выше пример, вот несколько примеров того, как правила будут сопоставлять запрашиваемый URL с маршрутом, используемым для построения HTML:
pages/posts/create.astro
- Будет построено только/posts/create
.pages/posts/[pid].ts
- Будет построено/posts/abc
,/posts/xyz
и т. д. Но не/posts/create
.pages/posts/[page].astro
- Построит/posts/1
,/posts/2
и т. д. Но не/posts/create
,/posts/abc
и/posts/xyz
.pages/posts/[...slug].astro
- Будет создавать/posts/1/2
,/posts/a/b/c
и т. д. Но не/posts/create
,/posts/1
,/posts/abc
и т. д.pages/[...slug].astro
- Будет создавать/abc
,/xyz
,/abc/xyz
и т. д. Но не/posts/create
,/posts/1
,/posts/abc
, и т. д.
Зарезервированные маршруты
Заголовок раздела Зарезервированные маршрутыВнутренние маршруты имеют приоритет над любыми маршрутами, определёнными пользователем или интеграцией, так как они необходимы для работы функций Astro. Вот зарезервированные маршруты Astro:
_astro/
: Обслуживает все статические ресурсы клиенту, включая CSS-документы, упакованные клиентские скрипты, оптимизированные изображения и любые ресурсы Vite._server_islands/
: Обслуживает динамические компоненты, отложенные в серверный остров (EN)._actions/
: Обслуживает любые определённые действия (EN).
Пагинация
Заголовок раздела ПагинацияAstro поддерживает встроенную пагинацию для больших коллекций данных, которые необходимо разбить на несколько страниц. Astro генерирует общие свойства пагинации, включая URL предыдущей/следующей страницы, общее количество страниц и т. д.
Имена пагинационных маршрутов должны использовать тот же синтаксис [скобка]
, что и стандартные динамические маршруты. Например, имя файла /astronauts/[page].astro
будет генерировать маршруты для /astronauts/1
, /astronauts/2
и т. д., где [page]
- это номер генерируемой страницы.
Вы можете использовать функцию paginate()
для генерации этих страниц для массива значений следующим образом:
---export function getStaticPaths({ paginate }) { const astronautPages = [ { astronaut: "Нил Армстронг" }, { astronaut: "Базз Олдрин" }, { astronaut: "Салли Райд" }, { astronaut: "Джон Гленн" }, ];
// Генерируем страницы из нашего массива астронавтов, по 2 на страницу return paginate(astronautPages, { pageSize: 2 });}// Все пагинированные данные передаются по пропсу «page»const { page } = Astro.props;---<!-- Отображаем номер текущей страницы. Также можно использовать `Astro.params.page`! --><h1>Страница {page.currentPage}</h1><ul> <!-- Перечисляем массив информации об астронавтах --> {page.data.map(({ astronaut }) => <li>{astronaut}</li>)}</ul>
Это генерирует следующие страницы, по 2 элемента на странице:
/astronauts/1
- Страница 1: Отображает “Neil Armstrong” и “Buzz Aldrin”./astronauts/2
- Страница 2: отображает “Sally Ride” и “John Glenn”.
Свойство page
Заголовок раздела Свойство pageКогда вы используете функцию paginate()
, каждой странице будут переданы данные через пропс page
. Пропс page
имеет множество полезных свойств, но вот основные из них:
interface Page<T = any> { /** массив, содержащий часть данных страницы, которую вы передали функции paginate() */ data: T[]; /** метаданные */ /** счетчик первого элемента на странице, начиная с 0 */ start: number; /** счетчик последнего элемента на странице, начиная с 0 */ end: number; /** общее количество результатов */ total: number; /** номер текущей страницы, начиная с 1 */ currentPage: number; /** количество элементов на странице (по умолчанию: 25) */ size: number; /** номер последней страницы */ lastPage: number; url: { /** url текущей страницы */ current: string; /** url предыдущей страницы (если она есть) */ prev: string | undefined; /** url следующей страницы (если она есть) */ next: string | undefined; /** url первой страницы (если текущая страница не является первой) */ first: string | undefined; /** url последней страницы (если текущая страница не является последней) */ last: string | undefined; };}
Следующий пример отображает текущую информацию для страницы вместе со ссылками для навигации между страницами:
---// Выводим на страницу тот же список объектов { astronaut }, что и в предыдущем примереexport function getStaticPaths({ paginate }) { /* ... */ }const { page } = Astro.props;---<h1>Страница {page.currentPage}</h1><ul> {page.data.map(({ astronaut }) => <li>{astronaut}</li>)}</ul>{page.url.first ? <a href={page.url.first}>Первая</a> : null}{page.url.prev ? <a href={page.url.prev}>Предыдущая</a> : null}{page.url.next ? <a href={page.url.next}>Следующая</a> : null}{page.url.last ? <a href={page.url.last}>Последняя</a> : null}
page
для пагинации (EN).
Вложенная пагинация
Заголовок раздела Вложенная пагинацияБолее продвинутым вариантом использования пагинации является вложенная пагинация. Это когда пагинация сочетается с другими динамическими параметрами маршрута. Вы можете использовать вложенную пагинацию для группировки коллекции пагинаций по какому-либо свойству или тегу.
Например, если вы хотите сгруппировать посты в Markdown по какому-то тегу, вы можете использовать вложенную пагинацию, создав страницу /src/pages/[tag]/[page].astro
, которая будет соответствовать следующим URLS:
/red/1
(tag=red)/red/2
(tag=red)/blue/1
(tag=blue)/green/1
(tag=green)
Вложенная пагинация работает путем возврата массива результатов paginate()
из getStaticPaths()
, по одному для каждой группировки.
В следующем примере мы реализуем вложенную пагинацию для построения URL-адресов, перечисленных выше:
---export function getStaticPaths({ paginate }) { const allTags = ["red", "blue", "green"]; const allPosts = Object.values(import.meta.glob("../pages/post/*.md", { eager: true })); // Для каждого тега возвращаем результат paginate(). // Убедитесь, что вы передали `{params: {tag}}` в `paginate()`. // чтобы Astro знал, для какой группы тегов получен результат. return allTags.flatMap((tag) => { const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === tag); return paginate(filteredPosts, { params: { tag }, pageSize: 10 }); });}
const { page } = Astro.props;const params = Astro.params;
Исключение страниц
Заголовок раздела Исключение страницВы можете исключить страницы или каталоги из сборки, добавив к их именам символ подчеркивания (_
). Файлы с префиксом _
не будут распознаны маршрутизатором и не будут помещены в каталог dist/
.
Это можно использовать для временного отключения страниц, а также для размещения тестов, утилит и компонентов в той же папке, что и связанные с ними страницы.
В этом примере только src/pages/index.astro
и src/pages/posts/post1.md
будут построены как маршруты страниц и HTML-файлы.
Директорияsrc/pages/
Директория_hidden-directory/
- page1.md
- page2.md
- _hidden-page.astro
- index.astro
Директорияposts/
- _SomeComponent.astro
- _utils.js
- post1.md