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

Обновление до Astro v5

Это руководство поможет вам перейти с Astro v4 на Astro v5.

Нужно сначала обновить более старый проект до v4? Ознакомьтесь с нашим предыдущим руководством по миграции.

Нужно ознакомиться с документацией v4? Посетите старую версию сайта документации (неподдерживаемый снимок v4.16).

Обновите версию Astro в вашем проекте до самой последней, используя менеджер пакетов:

Окно терминала
# Обновляем Astro вместе с официальными интеграциями
npx @astrojs/upgrade

Вы также можете обновить интеграции Astro вручную, если это необходимо, а также может потребоваться обновить другие зависимости в вашем проекте.

Astro v5.0 включает потенциально критические изменения, а также удаление и устаревание некоторых функций.

Если ваш проект не работает как ожидалось после обновления до v5.0, проверьте это руководство для обзора всех критических изменений и инструкций по обновлению вашей кодовой базы.

Смотрите журнал изменений Astro для полного списка изменений.

Любые крупные обновления зависимостей Astro могут вызвать критические изменения в вашем проекте.

Astro v5.0 обновляет Vite до версии v6.0 в качестве сервера разработки и сборщика для продакшена.

Если вы используете специфичные для Vite плагины, конфигурацию или API, проверьте руководство по миграции Vite для их критических изменений и обновите ваш проект при необходимости.

В Astro v4.x обработка JSX для интеграции @astrojs/mdx выполнялась внутри Astro.

В Astro v5.0 ответственность за обработку и рендеринг JSX и MDX была передана непосредственно пакету @astrojs/mdx. Это означает, что Astro 5.0 больше не совместим с более старыми версиями интеграции MDX.

Если ваш проект включает файлы .mdx, вам необходимо обновить @astrojs/mdx до последней версии (v4.0.0), чтобы ваш JSX мог корректно обрабатываться интеграцией.

Если вы используете MDX-рендерер сервера с экспериментальным Astro Container API (EN), вам необходимо обновить импорт, чтобы он соответствовал новому расположению:

import mdxRenderer from "astro/jsx/server.js";
import mdxRenderer from "@astrojs/mdx/server.js";

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

В Astro 4.x коллекции контента определялись, запрашивались и рендерились с использованием API коллекций контента, впервые представленного в Astro v2.0. Все записи коллекций были локальными файлами в зарезервированной папке src/content/. Кроме того, соглашение об именах файлов для исключения построения отдельных страниц в Astro было встроено в API коллекций контента.

Astro 5.0 представляет новую версию коллекций контента с использованием API Content Layer, которая приносит несколько улучшений производительности и дополнительные возможности. Хотя старые (устаревшие) и новые (API Content Layer) коллекции могут сосуществовать в этом выпуске, есть потенциальные критические изменения для существующих устаревших коллекций.

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

Мы рекомендуем преобразовать существующие коллекции в новый API Content Layer как можно скорее и создавать новые коллекции с использованием API Content Layer.

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

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

Узнайте больше об обновленных коллекциях контента.

Ознакомьтесь с инструкциями ниже для обновления существующей коллекции контента (type: 'content' или type: 'data') для использования API Content Layer.

Пошаговые инструкции по обновлению коллекции
  1. Переместите файл конфигурации контента. Этот файл больше не должен находиться в папке src/content/. Теперь он должен располагаться в src/content.config.ts.

  2. Отредактируйте определение коллекции. Ваша обновленная коллекция требует указания loader, который определяет папку для расположения коллекции (base) и шаблон (pattern), описывающий имена файлов и расширения, которые должны соответствовать записям коллекции. (Возможно, вам потребуется обновить пример ниже в соответствии с вашими данными. Вы можете использовать globster.xyz, чтобы проверить ваш glob-шаблон.) Опция выбора type коллекции больше недоступна.

    src/content.config.ts
    import { defineCollection, z } from 'astro:content';
    import { glob } from 'astro/loaders';
    const blog = defineCollection({
    // Для Content Layer больше не нужно определять `type`
    type: 'content',
    loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/data/blog" }),
    schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    }),
    });
  3. Замените ссылки с slug на id. В коллекциях Content Layer больше нет зарезервированного поля slug. Вместо этого все обновленные коллекции будут иметь поле id:

    src/pages/[slug].astro
    ---
    export async function getStaticPaths() {
    const posts = await getCollection('blog');
    return posts.map((post) => ({
    params: { slug: post.slug },
    params: { slug: post.id },
    props: post,
    }));
    }
    ---

    Вы также можете обновить имена файлов для динамической маршрутизации, чтобы они соответствовали значению изменённого параметра getStaticPaths().

  4. Перейдите на новую функцию render(). Записи больше не имеют метода render(), так как теперь они являются сериализуемыми простыми объектами. Вместо этого импортируйте функцию render() из astro:content.

    src/pages/index.astro
    ---
    import { getEntry, render } from 'astro:content';
    const post = await getEntry('blog', params.slug);
    const { Content, headings } = await post.render();
    const { Content, headings } = await render(post);
    ---
    <Content />
Критические изменения для устаревших коллекций content и data
Заголовок раздела Критические изменения для устаревших коллекций content и data

По умолчанию коллекции, которые используют старое свойство type (content или data) и не определяют loader, теперь реализованы «под капотом» с использованием встроенного загрузчика glob() API Content Layer, с дополнительной обработкой для обратной совместимости.

Кроме того, временная обратная совместимость позволяет сохранить файл конфигурации контента в его исходном расположении src/content/config.ts.

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

  • В предыдущих версиях Astro коллекции создавались для всех папок в src/content/, даже если они не были определены в src/content/config.ts. Это поведение теперь устарело, и коллекции всегда должны быть определены в src/content.config.ts. Для существующих коллекций это могут быть просто пустые объявления (например, const blog = defineCollection({})), и Astro неявно определит вашу устаревшую коллекцию способом, совместимым с новым поведением загрузки.
  • Специальное поле layout не поддерживается в записях коллекций Markdown. Это свойство предназначено только для отдельных файлов страниц, расположенных в src/pages/, и вряд ли используется в ваших коллекциях. Однако, если вы использовали это свойство, теперь вам нужно создавать динамические маршруты, включающие стилизацию страницы.
  • Порядок сортировки сгенерированных коллекций недетерминирован и зависит от платформы. Это означает, что если вы вызываете getCollection(), порядок возвращаемых записей может отличаться от предыдущего. Если вам нужен определённый порядок, вы должны самостоятельно сортировать записи коллекции.
  • image().refine() не поддерживается. Если вам нужно проверить свойства изображения, это следует делать во время выполнения в вашей странице или компоненте.
  • Аргумент key в getEntry(collection, key) типизирован как string, а не имеет типов для каждой записи.
  • Ранее при вызове getEntry(collection, key) со статической строкой в качестве ключа возвращаемый тип не был nullable. Теперь тип включает undefined, поэтому вы должны проверить, определена ли запись, прежде чем использовать результат, иначе возникнут ошибки типов.

Если вы ещё не готовы обновить существующие коллекции, вы можете включить флаг legacy.collections (EN), и ваши существующие коллекции продолжат работать как раньше.

Следующие устаревшие функции больше не поддерживаются и не документируются. Пожалуйста, обновите ваш проект соответствующим образом.

Некоторые устаревшие функции могут временно продолжать работать до их полного удаления. Другие могут либо не оказывать никакого эффекта без предупреждений, либо вызывать ошибку, предлагающую вам обновить код.

В Astro v4.x вы могли использовать Astro.glob() в своих компонентах .astro для запроса нескольких файлов в вашем проекте. Это имело некоторые ограничения (где это можно использовать, производительность и т. д.), и использование функций запросов из API Content Collections или собственного import.meta.glob() от Vite часто предоставляло больше функций и гибкости.

Astro 5.0 делает функцию Astro.glob() устаревшей в пользу использования getCollection() для запроса ваших коллекций и import.meta.glob() для запроса других исходных файлов в вашем проекте.

Замените все использования Astro.glob() на import.meta.glob(). Обратите внимание, что import.meta.glob() больше не возвращает Promise, поэтому вам, возможно, придется обновить ваш код соответствующим образом. Вам не потребуется вносить изменения в ваши glob-шаблоны (EN).

src/pages/blog.astro
---
const posts = await Astro.glob('./posts/*.md');
const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
---
{posts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}

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

Вы также можете рассмотреть возможность использования glob-пакетов из NPM, таких как fast-glob.

В Astro v4.x вы могли выбрать создание отдельного файла для каждого маршрута, определённого в проекте, отражая структуру вашей папки src/pages/ в папке сборки. По умолчанию Astro создавал один файл entry.mjs, который отвечал за рендеринг страницы при каждом запросе.

Astro v5.0 удаляет возможность отключения поведения по умолчанию. Теперь это поведение является стандартным и не настраиваемым.

Удалите свойство functionPerRoute из вашей конфигурации adapterFeatures. Оно больше недоступно.

my-adapter.mjs
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
adapterFeatures: {
functionPerRoute: true
}
});
},
},
};
}
Узнайте больше об API адаптера (EN) для создания интеграций адаптеров.

Устаревшее: routes в хуке astro:build:done (API интеграций)

Заголовок раздела Устаревшее: routes в хуке astro:build:done (API интеграций)

В Astro v4.x интеграции получали доступ к маршрутам через хук astro:build:done.

Astro v5.0 делает массив routes, передаваемый в этот хук, устаревшим. Вместо этого предоставляется новый хук astro:routes:resolved, который выполняется перед astro:config:done и при каждом изменении маршрута в режиме разработки. Он имеет те же свойства, что и устаревший список routes, за исключением distURL, который доступен только во время сборки.

Удалите все упоминания routes, передаваемые в astro:build:done, и замените их новым хуком astro:routes:resolved. Доступ к distURL можно получить через новую карту assets:

my-integration.mjs
const integration = () => {
let routes
return {
name: 'my-integration',
hooks: {
'astro:routes:resolved': (params) => {
routes = params.routes
},
'astro:build:done': ({
routes
assets
}) => {
for (const route of routes) {
const distURL = assets.get(route.pattern)
if (distURL) {
Object.assign(route, { distURL })
}
}
console.log(routes)
}
}
}
}
Узнайте больше о хуке astro:routes:resolved в API интеграций для создания интеграций.

Следующие функции были полностью удалены из кодовой базы и больше не могут использоваться. Некоторые из этих функций могли продолжать работать в вашем проекте даже после устаревания. Другие могли не оказывать никакого эффекта без предупреждений.

Проекты, содержащие эти удалённые функции, теперь не смогут быть собраны, и больше не будет документации, напоминающей вам об удалении этих функций.

В Astro v4.x Lit был основной поддерживаемой библиотекой фреймворка через пакет @astrojs/lit.

Astro v5.0 удаляет эту интеграцию, и она больше не будет получать обновлений для совместимости с версиями 5.x и выше.

Вы можете продолжать использовать Lit для клиентских компонентов, добавив клиентский тег скрипта. Например:

<script>
import "../components/MyTabs";
</script>
<my-tabs title="Это мои вкладки">...</my-tabs>

Если вы заинтересованы в поддержке интеграции Lit самостоятельно, вы можете использовать последнюю опубликованную версию @astrojs/lit в качестве отправной точки и обновить соответствующие пакеты.

Узнайте больше об официальных интеграциях Astro.

В Astro v4.x были доступны три режима рендеринга output: 'static', 'hybrid' и 'server'.

Astro v5.0 объединяет конфигурации output: 'hybrid' и output: 'static' в одну конфигурацию (теперь называемую 'static'), которая работает так же, как предыдущий гибридный вариант.

Теперь нет необходимости указывать output: 'hybrid' в вашей конфигурации Astro для использования серверно-рендеренных страниц. Новая конфигурация output: 'static' включает эту возможность.

Теперь Astro автоматически позволяет вам отказаться от предварительного рендеринга в статическом сайте без необходимости изменения конфигурации output. Любой маршрут страницы или эндпойнт могут включать export const prerender = false, чтобы быть рендеренными на сервере по запросу, в то время как остальная часть вашего сайта будет статически сгенерирована.

Если ваш проект использовал гибридный рендеринг, теперь вам нужно удалить опцию output: 'hybrid' из вашей конфигурации Astro, так как она больше не существует. Однако никаких других изменений в ваш проект вносить не требуется, и у вас не должно быть критических изменений. Поведение предыдущего 'hybrid' теперь является поведением по умолчанию под новым именем 'static'.

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
output: 'hybrid',
});

Если вы использовали параметр output: 'static' (по умолчанию), вы можете продолжать использовать его как раньше. По умолчанию все ваши страницы будут предварительно отрисованы, и у вас будет полностью статический сайт. Ваш проект не должен претерпеть никаких критических изменений.

Для развёртывания Astro-проекта с серверной отрисовкой страниц по-прежнему требуется адаптер, независимо от режима output, используемого в проекте. Если адаптер не будет добавлен, в режиме разработки появится предупреждение, а на этапе сборки произойдет ошибка.

В Astro 4.x вы могли настроить image.service: squooshImageService(), чтобы использовать Squoosh для обработки изображений вместо Sharp. Однако базовая библиотека libsquoosh больше не поддерживается и имеет проблемы с памятью и производительностью.

Astro 5.0 полностью удаляет сервис оптимизации изображений Squoosh.

Чтобы переключиться на встроенный сервис изображений Sharp, удалите импорт squooshImageService из конфигурации Astro. По умолчанию для astro:assets будет использоваться Sharp.

astro.config.mjs
import { squooshImageService } from "astro/config";
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
service: squooshImageService()
}
});

Если вы используете строгий менеджер пакетов, такой как pnpm, вам может потребоваться вручную установить пакет sharp, чтобы использовать сервис изображений Sharp, даже несмотря на то, что он встроен в Astro по умолчанию.

Если ваш адаптер не поддерживает встроенную оптимизацию изображений Sharp в Astro, вы можете настроить сервис изображений без операций (EN), чтобы продолжить использовать компоненты <Image /> и <Picture />.

Кроме того, если вы не можете использовать сервис изображений Sharp, вы можете рассмотреть поддерживаемый сообществом сервис изображений Squoosh.

Если ваш адаптер ранее указывал свою совместимость со Squoosh, теперь следует удалить эту информацию из его конфигурации.

my-adapter.mjs
supportedAstroFeatures: {
assets: {
isSquooshCompatible: true
}
}

В Astro v4.x файл @types/astro.ts открывал для пользователей все типы, независимо от того, использовались ли они активно или предназначались только для внутреннего использования.

Astro v5.0 перерабатывает этот файл, удаляя устаревшие и внутренние типы. Этот рефакторинг улучшает работу редактора (например, ускоряет автодополнение, снижает потребление памяти и делает список вариантов автодополнения более релевантным). Однако в некоторых проектах это может вызвать ошибки, если они использовали больше недоступные публичные типы.

Удалите любые типы, которые теперь вызывают ошибки в вашем проекте, так как у вас больше нет к ним доступа. В основном это API, которые ранее были устаревшими и удалены, но также могут включать типы, ставшие внутренними.

Следующие экспериментальные флаги были удалены в Astro v5.0, и теперь эти функции доступны для использования:

  • env
  • serverIslands

Кроме того, следующие экспериментальные флаги были удалены и теперь являются поведением по умолчанию или рекомендуемым в Astro v5.0.

Следующие экспериментальные флаги были удалены, и их соответствующие функции не входят в Astro v5.0.

  • contentCollectionsCache

Удалите эти экспериментальные флаги, если вы использовали их ранее, и переместите вашу конфигурацию env в корень конфигурационного файла Astro:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
directRenderScript: true,
globalRoutePriority: true,
contentLayer: true,
serverIslands: true,
contentCollectionsCache: true,
env: {
schema: {...}
}
},
env: {
schema: {...}
}
})

Эти функции теперь доступны по умолчанию в Astro v5.0.

Узнайте больше об этих нововведениях в записи блога о v5.0.

Некоторые параметры по умолчанию изменились в Astro v5.0, и возможно, вам потребуется обновить код вашего проекта, чтобы учесть эти изменения.

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

Защита CSRF теперь включена по умолчанию

Заголовок раздела Защита CSRF теперь включена по умолчанию

В Astro v4.x значение по умолчанию для параметра security.checkOrigin было false. Ранее вам нужно было явно установить это значение в true, чтобы включить защиту от подделки межсайтовых запросов (CSRF).

Astro v5.0 изменяет значение по умолчанию для этого параметра на true, и теперь автоматически проверяется, что заголовок «origin» совпадает с URL, отправленным с каждым запросом на страницах с рендерингом по требованию.

Если вы ранее настроили security.checkOrigin: true, теперь вам не нужно добавлять эту строку в конфигурацию Astro. Это теперь является значением по умолчанию.

Чтобы отключить это поведение, вам нужно явно установить security.checkOrigin: false.

astro.config.mjs
export default defineConfig({
output: "server",
security: {
checkOrigin: false
}
})

Приоритет маршрутов для внедряемых маршрутов и перенаправлений

Заголовок раздела Приоритет маршрутов для внедряемых маршрутов и перенаправлений

В Astro v4.x флаг experimental.globalRoutePriority был необязательным и гарантировал, что внедрённые маршруты, маршруты на основе файлов и перенаправления будут иметь приоритет в соответствии с порядком приоритетов маршрутов. Это позволяло больше контролировать маршрутизацию в проекте, не устанавливая автоматически приоритет для определённых типов маршрутов и стандартизируя порядок приоритетов маршрутов.

Astro v5.0 удаляет этот экспериментальный флаг и делает это поведение стандартным для Astro: перенаправления и внедрённые маршруты теперь имеют такой же приоритет, как и маршруты, основанные на файлах.

Обратите внимание, что это уже было стандартным поведением в Starlight и не должно повлиять на обновлённые проекты Starlight.

Если ваш проект включает внедрённые маршруты или перенаправления, убедитесь, что ваши маршруты строят URL-адреса страниц, как ожидается. Пример нового ожидаемого поведения приведен ниже.

В проекте со следующими маршрутами:

  • Маршрут на основе файлов: /blog/post/[pid]
  • Маршрут на основе файлов: /[page]
  • Внедрённый маршрут: /blog/[...slug]
  • Перенаправление: /blog/tags/[tag] -> /[tag]
  • Перенаправление: /posts -> /blog

Следующие URL-адреса будут построены (вместо следования порядку приоритетов маршрутов Astro v4.x):

  • /blog/tags/astro строится с помощью перенаправления на /tags/[tag] (вместо внедрённого маршрута /blog/[...slug])
  • /blog/post/0 строится с помощью маршрута на основе файлов /blog/post/[pid] (вместо внедрённого маршрута /blog/[...slug])
  • /posts строится с помощью перенаправления на /blog (вместо маршрута на основе файлов /[page])

В случае пересечения маршрутов, когда два маршрута с одинаковым приоритетом пытаются построить один и тот же URL, Astro выведет предупреждение, идентифицируя конфликтующие маршруты.

Теги <script> теперь рендерятся напрямую в порядке их объявления

Заголовок раздела Теги &lt;script&gt; теперь рендерятся напрямую в порядке их объявления

В Astro v4.x флаг experimental.directRenderScript был необязательным и позволял напрямую рендерить теги <script> в .astro файлах (включая такие возможности, как TypeScript, импорт node_modules и дедубликация скриптов). Эта стратегия предотвращала выполнение скриптов в местах, где они не использовались. Кроме того, условно рендеримые скрипты ранее автоматически вставлялись инлайн, как если бы к ним был автоматически добавлен атрибут is:inline.

Astro 5.0 удаляет этот экспериментальный флаг и делает это стандартным поведением в Astro: скрипты больше не перемещаются в <head>, несколько скриптов на странице больше не объединяются в один файл, и тег <script> может вмешиваться в стилизацию CSS. Кроме того, условно рендеримые скрипты больше не вставляются инлайн по умолчанию.

Проверьте ваши теги <script> и убедитесь, что они ведут себя так, как вам нужно.

Если у вас ранее были условно рендеримые теги <script>, вам нужно будет добавить атрибут is:inline, чтобы сохранить прежнее поведение:

src/components/MyComponent.astro
---
type Props = {
showAlert: boolean
}
const { showAlert } = Astro.props;
---
{
showAlert && <script is:inline>alert("Некоторый очень важный код!!")</script>
}
Узнайте больше об использовании тегов script в Astro.

Следующие изменения считаются критическими в Astro v5.0. Критические изменения могут предоставлять временную обратную совместимость, а могут и не предоставлять. Если вы использовали эти функции, вам, возможно, придется обновить ваш код, как рекомендуется в каждом пункте.

В Astro 4.x API View Transitions включала компонент маршрутизатора <ViewTransitions /> для включения маршрутизации на стороне клиента, переходов между страницами и других функций.

Astro 5.0 переименовывает этот компонент в <ClientRouter />, чтобы уточнить роль компонента в API. Это делает более очевидным, что функции, предоставляемые компонентом маршрутизатора <ClientRouter /> в Astro, немного отличаются от родного маршрутизатора MPA на основе CSS.

Функциональность не изменилась. Изменилось только имя компонента.

Замените все вхождения импорта и компонента ViewTransitions на ClientRouter:

src/layouts/MyLayout.astro
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
<html>
<head>
...
<ViewTransitions />
<ClientRouter />
</head>
</html>

В Astro v4.x Astro использовал файл src/env.d.ts для вывода типов и определения модулей для функций, которые зависели от сгенерированных типов.

Astro 5.0 теперь использует файл .astro/types.d.ts для вывода типов и рекомендует установить параметры include и exclude в tsconfig.json, чтобы воспользоваться типами Astro и избежать проверки сгенерированных файлов.

Запуск команды astro sync больше не создает и не обновляет src/env.d.ts, так как этот файл не требуется для проверки типов в стандартных проектах Astro.

Чтобы обновить ваш проект до рекомендованных настроек TypeScript для Astro, добавьте следующие свойства include и exclude в ваш текущий файл tsconfig.json:

tsconfig.json
{
"extends": "astro/tsconfigs/base",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}

Обратите внимание, что файл src/env.d.ts необходим только в случае, если вы добавили пользовательские настройки или если вы не используете файл tsconfig.json.

Изменено: Действия, отправленные через HTML-формы, больше не используют перенаправления с помощью cookies

Заголовок раздела Изменено: Действия, отправленные через HTML-формы, больше не используют перенаправления с помощью cookies

В Astro v4.x действия, вызываемые из HTML-формы, приводили к перенаправлению с результатом, переданным через куки. Это вызывало проблемы с большими ошибками формы и значениями возврата, которые превышали лимит хранения в 4 КБ для куки-файлов.

Astro 5.0 теперь рендерит результат действия как POST-результат без перенаправлений. Это приведет к появлению диалогового окна «Подтверждаете повторную отправку формы?», если пользователь попытается обновить страницу. Однако теперь не существует ограничения на 4 КБ для значения возврата действия.

Необходимо обновить обработку результатов действий, которые зависят от перенаправлений, и при необходимости обработать диалоговое окно «Подтверждаете повторную отправку формы?» с помощью мидлваров.

Чтобы перенаправить на предыдущий маршрут при ошибке
Заголовок раздела Чтобы перенаправить на предыдущий маршрут при ошибке

Если действие вашей HTML-формы направлено на другой маршрут (например, action={"/success-page" + actions.name}), Astro больше не будет перенаправлять на предыдущий маршрут при ошибке. Вы можете реализовать это поведение вручную с помощью перенаправлений в вашем компоненте Astro. Этот пример вместо этого перенаправляет на новый маршрут при успехе и обрабатывает ошибки на текущей странице:

src/pages/newsletter.astro
---
import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.newsletter);
if (!result?.error) {
// Вставьте соответствующие данные результата в URL, если это необходимо
// пример: redirect(`/confirmation?email=${result.data.email}`);
return redirect('/confirmation');
}
---
<form method="POST" action={'/confirmation' + actions.newsletter}>
<label>Имейл <input required type="email" name="email" /></label>
<button>Регистрация</button>
</form>
(Необязательно) Удаление диалога подтверждения при обновлении
Заголовок раздела (Необязательно) Удаление диалога подтверждения при обновлении

Чтобы избавиться от диалога «Подтверждаете повторную отправку формы?» при обновлении страницы или чтобы сохранить результаты действия между сессиями, вы можете настроить обработку результатов действия через мидлвары (EN).

Мы рекомендуем использовать поставщика хранилища сессии как описано в примере Netlify Blob (EN). Однако если вы предпочитаете поведение с перенаправлением куки, как в 4.X, и принимаете ограничение размера 4 КБ, вы можете реализовать этот паттерн, как показано в этом примере:

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
// Пропускаем запросы для предварительно рендеренных страниц
if (context.isPrerendered) return next();
const { action, setActionResult, serializeActionResult } = getActionContext(context);
// Если результат действия был передан как куки, установите результат,
// чтобы он был доступен через `Astro.getActionResult()`
const payload = context.cookies.get('ACTION_PAYLOAD');
if (payload) {
const { actionName, actionResult } = payload.json();
setActionResult(actionName, actionResult);
context.cookies.delete('ACTION_PAYLOAD');
return next();
}
// Если действие было вызвано из действия HTML-формы,
// вызовите обработчик действия и перенаправьте с результатом как куки
if (action?.calledFrom === 'form') {
const actionResult = await action.handler();
context.cookies.set('ACTION_PAYLOAD', {
actionName: action.name,
actionResult: serializeActionResult(actionResult),
});
if (actionResult.error) {
// Перенаправляем обратно на предыдущую страницу при ошибке
const referer = context.request.headers.get('Referer');
if (!referer) {
throw new Error('Internal: Referer unexpectedly missing from Action POST request.');
}
return context.redirect(referer);
}
// Перенаправляем на целевую страницу при успехе
return context.redirect(context.originPathname);
}
return next();
})

Изменено: compiledContent() теперь является асинхронной функцией

Заголовок раздела Изменено: compiledContent() теперь является асинхронной функцией

В Astro 4.x топ-уровневый await использовался в модулях Markdown. Это вызывало некоторые проблемы с пользовательскими сервисами изображений и изображениями внутри Markdown, что приводило к неожиданному завершению работы Node без сообщения об ошибке.

Astro 5.0 делает свойство compiledContent() в импорте Markdown асинхронной функцией, требующей использования await для разрешения контента.

Обновите ваш код, чтобы использовать await, при вызове compiledContent().

src/pages/post.astro
---
import * as myPost from "../blog/post.md";
const content = myPost.compiledContent();
const content = await myPost.compiledContent();
---
<Fragment set:html={content} />
Узнайте больше о функции compiledContent() для получения скомпилированного Markdown.

Изменено: astro:content больше нельзя использовать на клиенте

Заголовок раздела Изменено: astro:content больше нельзя использовать на клиенте

В Astro 4.x было возможно получить доступ к модулю astro:content на клиенте.

Astro 5.0 удаляет этот доступ, так как он никогда не предназначался для использования на клиенте. Использование astro:content таким образом имело ограничения и увеличивало размер клиентских сборок.

Если вы в настоящее время используете astro:content на клиенте, передавайте необходимые данные через пропсы в ваши клиентские компоненты:

src/pages/blog.astro
---
import { getCollection } from 'astro:content';
import ClientComponent from '../components/ClientComponent';
const posts = await getCollection('blog');
const postsData = posts.map(post => post.data);
---
<ClientComponent posts={postsData} />
Узнайте больше об API astro:content (EN).

Переименовано: Названия цветовых токенов темы css-variables в Shiki

Заголовок раздела Переименовано: Названия цветовых токенов темы css-variables в Shiki

В Astro v4.x тема Shiki css-variables использовала токены --astro-code-color-text и --astro-code-color-background для стилизации цвета текста и фона блоков кода соответственно.

Astro v5.0 переименовывает их в --astro-code-foreground и --astro-code-background, чтобы лучше соответствовать значениям по умолчанию в Shiki v1.

Выполните глобальную замену в вашем проекте, чтобы перейти на новые названия токенов.

src/styles/global.css
:root {
--astro-code-color-text: #000;
--astro-code-color-background: #fff;
--astro-code-foreground: #000;
--astro-code-background: #fff;
}

Изменено: внутренний плагин Shiki для подсветки кода в rehype

Заголовок раздела Изменено: внутренний плагин Shiki для подсветки кода в rehype

В Astro v4.x внутренний плагин Shiki для rehype подсвечивал блоки кода как HTML.

Astro 5.0 обновляет этот плагин, чтобы подсвечивать код в формате hast. Это позволяет более эффективно обрабатывать Markdown и MDX и улучшает производительность сборки проекта. Однако это может вызвать проблемы с существующими трансформерами Shiki.

Если вы используете трансформеры Shiki, передаваемые в markdown.shikiConfig.transformers, убедитесь, что они не используют хук postprocess. Этот хук больше не выполняется для блоков кода в .md и .mdx файлах. (Подробнее в документации Shiki о хуках трансформеров).

Блоки кода в файлах .mdoc и встроенный компонент Astro <Code /> не используют внутренний плагин Shiki для rehype и не затронуты этим изменением.

Изменено: Автоматическое поведение charset=utf-8 для страниц Markdown и MDX

Заголовок раздела Изменено: Автоматическое поведение charset=utf-8 для страниц Markdown и MDX

В Astro 4.0 страницы Markdown и MDX (расположенные в src/pages/) автоматически отвечали с charset=utf-8 в заголовке Content-Type, что позволяло отображать не-ASCII символы на ваших страницах.

Astro 5.0 обновляет это поведение, добавляя тег <meta charset="utf-8"> вместо этого, и только для страниц, которые не используют специальное свойство layout в метаданных. Аналогично для страниц MDX, Astro добавит тег только в том случае, если содержимое MDX не импортирует компонент Layout.

Если ваши страницы Markdown или MDX используют свойство layout в метаданных, или если содержимое MDX импортирует компонент Layout, то кодировка HTML будет обрабатываться указанным компонентом макета, и тег <meta charset="utf-8"> не будет добавлен на вашу страницу по умолчанию.

Если вам требуется charset=utf-8 для корректного отображения страницы, убедитесь, что ваши компоненты макета содержат тег <meta charset="utf-8">. Возможно, вам потребуется добавить его, если вы ещё этого не сделали.

Узнайте больше о макетах Markdown.

Изменено: Astro-специфичные метаданные в плагинах remark и rehype

Заголовок раздела Изменено: Astro-специфичные метаданные в плагинах remark и rehype

В Astro 4.x специфичные метаданные, прикреплённые к vfile.data в плагинах remark и rehype, находились в разных местах и имели непоследовательные имена.

Astro 5 упрощает API, и метаданные теперь переименованы следующим образом:

  • vfile.data.__astroHeadings -> vfile.data.astro.headings
  • vfile.data.imagePaths -> vfile.data.astro.imagePaths

Тип imagePaths также обновлен с Set<string> на string[]. Метаданные vfile.data.astro.frontmatter остаются без изменений.

Хотя мы не считаем эти API публичными, они могут быть доступны для плагинов remark и rehype, которые хотят повторно использовать метаданные Astro. Если вы используете эти API, убедитесь, что обращаетесь к ним в новых местах.

Изменено: конфигурация эндпойнта изображений

Заголовок раздела Изменено: конфигурация эндпойнта изображений

В Astro 4.x вы могли указать эндпойнт в конфигурации image для использования при оптимизации изображений.

Astro 5.0 позволяет настраивать route и entrypoint в конфигурации image.endpoint. Это может быть полезно в специфических ситуациях, когда маршрут по умолчанию /_image конфликтует с существующим маршрутом или вашей локальной настройкой сервера.

Если вы ранее настраивали image.endpoint, переместите этот эндпойнт в новое свойство endpoint.entrypoint. При желании вы можете настроить route:

astro.config.mjs
import { defineConfig } from "astro/config";
defineConfig({
image: {
endpoint: './src/image-endpoint.ts',
endpoint: {
route: "/image",
entrypoint: "./src/image_endpoint.ts"
}
},
})

Изменено: поведение разрешения build.client и build.server

Заголовок раздела Изменено: поведение разрешения build.client и build.server

В Astro v4.x опции build.client и build.server были задокументированы как разрешаемые относительно опции outDir, но это не всегда работало так, как ожидалось.

Astro 5.0 исправляет это поведение, чтобы правильно разрешать пути относительно опции outDir. Например, если outDir установлен в ./dist/nested/, то по умолчанию:

  • build.client будет разрешен в <root>/dist/nested/client/
  • build.server будет разрешен в <root>/dist/nested/server/

Ранее значения разрешались неправильно:

  • build.client разрешался в <root>/dist/nested/dist/client/
  • build.server разрешался в <root>/dist/nested/dist/server/

Если вы полагались на предыдущие пути сборки, убедитесь, что ваш проект обновлен для работы с новыми путями.

Узнайте больше о настройках build в Astro (EN).

Изменено: JS-зависимости в конфигурационном файле больше не обрабатываются Vite

Заголовок раздела Изменено: JS-зависимости в конфигурационном файле больше не обрабатываются Vite

В Astro 4.x локально связанные JS-зависимости (например, npm link, в монорепозитории и т. д.) могли использовать функции Vite, такие как import.meta.glob, при импорте через конфигурационный файл Astro.

Astro 5 обновляет процесс загрузки конфигурации Astro, чтобы игнорировать обработку локально связанных JS-зависимостей с помощью Vite. Зависимости, экспортирующие сырые TypeScript-файлы, не затрагиваются. Вместо этого эти JS-зависимости будут нормально импортироваться средой выполнения Node.js так же, как и другие зависимости из node_modules.

Это изменение было сделано, так как предыдущее поведение вызывало путаницу среди авторов интеграций, которые тестировали пакет, работающий локально, но не работающий после публикации. Оно также ограничивало использование зависимостей, поддерживающих только CJS, поскольку Vite требовал, чтобы код был в формате ESM. Хотя это изменение затрагивает только JS-зависимости, также рекомендуется экспортировать JavaScript вместо сырых TypeScript-файлов, где это возможно, чтобы предотвратить случайное использование специфичных для Vite функций, так как это деталь реализации процесса загрузки конфигурации Astro.

Убедитесь, что ваши локально связанные JS-зависимости собраны перед запуском вашего проекта Astro. Тогда загрузка конфигурации должна работать как раньше.

Изменено: URL-адреса, возвращаемые paginate()

Заголовок раздела Изменено: URL-адреса, возвращаемые paginate()

В Astro v4.x URL-адрес, возвращаемый функцией paginate() (например, page.url.next, page.url.first и т. д.), не включал значение, установленное для base в вашей конфигурации Astro. Вам приходилось вручную добавлять значение base к пути URL.

Astro 5.0 автоматически включает значение base в page.url.

Если вы используете функцию paginate() для этих URL-адресов, удалите любое существующее значение base, так как теперь оно добавляется автоматически:

---
export async function getStaticPaths({ paginate }) {
const astronautPages = [{
astronaut: 'Нил Армстронг',
}, {
astronaut: 'Базз Олдрин',
}, {
astronaut: 'Салли Райд',
}, {
astronaut: 'Джон Гленн',
}];
return paginate(astronautPages, { pageSize: 1 });
}
const { page } = Astro.props;
// `base: /'docs'` configured in `astro.config.mjs`
const prev = "/docs" + page.url.prev;
const prev = page.url.prev;
---
<a id="prev" href={prev}>Back</a>
Узнайте больше о пагинации в Astro.

Изменено: небулевые значения HTML-атрибутов

Заголовок раздела Изменено: небулевые значения HTML-атрибутов

В Astro v4.x не-булевые HTML-атрибуты могли не включать свои значения при рендеринге в HTML.

Astro v5.0 теперь явно рендерит значения как ="true" или ="false", что соответствует правильной обработке атрибутов в браузерах.

В следующих примерах .astro только allowfullscreen является булевым атрибутом:

src/pages/index.astro
<!-- `allowfullscreen` — булевый атрибут -->
<p allowfullscreen={true}></p>
<p allowfullscreen={false}></p>
<!-- `inherit` — *не* булевый атрибут -->
<p inherit={true}></p>
<p inherit={false}></p>
<!-- `data-*` атрибуты не являются булевыми -->
<p data-light={true}></p>
<p data-light={false}></p>

Astro v5.0 теперь сохраняет полный атрибут данных с его значением при рендеринге HTML для небулевых атрибутов:

<p allowfullscreen></p>
<p></p>
<p inherit="true"></p>
<p inherit></p>
<p inherit="false"></p>
<p data-light></p>
<p data-light="true"></p>
<p></p>
<p data-light="false"></p>

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

el.getAttribute('inherit') === ''
el.getAttribute('inherit') === 'false'
el.hasAttribute('data-light')
el.dataset.light === 'true'

Изменено: добавление значений в context.locals

Заголовок раздела Изменено: добавление значений в context.locals

В Astro 4.x можно было полностью заменить весь объект locals в мидлварах, API-эндпоинтах и страницах при добавлении новых значений.

Astro 5.0 требует, чтобы вы добавляли значения к существующему объекту locals, не удаляя его. Объект locals в мидлварах, API-эндпоинтах и страницах больше не может быть полностью перезаписан.

Там, где вы ранее перезаписывали объект, теперь вы должны присваивать значения ему:

src/middleware.js
ctx.locals = {
Object.assign(ctx.locals, {
one: 1,
two: 2
}
})
Узнайте больше о хранении данных в context.locals.

В Astro v4.x params, передаваемые в getStaticPath(), автоматически декодировались с использованием decodeURIComponent.

Astro v5.0 больше не декодирует значения params, передаваемые в getStaticPaths. Если это необходимо, вы должны вручную декодировать их самостоятельно.

Если вы ранее полагались на автоматическое декодирование, используйте decodeURI при передаче params.

src/pages/[id].astro
---
export function getStaticPaths() {
return [
{ params: { id: "%5Bpage%5D" } },
{ params: { id: decodeURI("%5Bpage%5D") } },
]
}
const { id } = Astro.params;
---

Обратите внимание, что использование decodeURIComponent для getStaticPaths не рекомендуется, так как оно декодирует больше символов, чем следует, например, /, ?, # и другие.

Изменено: тип RouteData заменен на IntegrationsRouteData (API интеграций)

Заголовок раздела Изменено: тип RouteData заменен на IntegrationsRouteData (API интеграций)

В Astro v4.x тип entryPoints внутри хуков astro:build:ssr и astro:build:done был RouteData.

В Astro v5.0 тип entryPoints теперь IntegrationRouteData, который содержит подмножество типа RouteData. Поля isIndex и fallbackRoutes были удалены.

Обновите ваш адаптер, изменив тип entryPoints с RouteData на IntegrationRouteData.

import type {RouteData} from 'astro';
import type {IntegrationRouteData} from "astro"
function useRoute(route: RouteData) {
function useRoute(route: IntegrationRouteData) {
}

Изменено: distURL теперь является массивом (API интеграций)

Заголовок раздела Изменено: distURL теперь является массивом (API интеграций)

В Astro v4.x RouteData.distURL был undefined или URL.

Astro 5.0 обновляет структуру IntegrationRouteData.distURL, чтобы она была undefined или массивом URL. Это исправляет предыдущую ошибку, так как маршрут может генерировать несколько файлов на диске, особенно при использовании динамических маршрутов, таких как [slug] или [...slug].

Обновите ваш код для обработки IntegrationRouteData.distURL как массива.

if (route.distURL) {
if (route.distURL.endsWith('index.html')) {
// что-то делаем
}
for (const url of route.distURL) {
if (url.endsWith('index.html')) {
// что-то делаем
}
}
}

Изменено: Аргументы, передаваемые в app.render() (API адаптера)

Заголовок раздела Изменено: Аргументы, передаваемые в app.render() (API адаптера)

В Astro 4.x метод API адаптера app.render() мог принимать три аргумента: обязательный request, объект опций или объект routeData, и locals.

Astro 5.0 объединяет эти два последних аргумента в один аргумент с именем renderOptions.

Передайте объект в качестве второго аргумента в app.render(), который может включать свойства routeData и locals.

const response = await app.render(request, routeData, locals);
const response = await app.render(request, {routeData, locals});

Изменено: Свойства supportedAstroFeatures (API адаптера)

Заголовок раздела Изменено: Свойства supportedAstroFeatures (API адаптера)

В Astro 4.x supportedAstroFeatures, который позволяет авторам адаптеров указывать, какие функции поддерживает их интеграция, включал свойство assets для указания, какие из сервисов изображений Astro поддерживаются.

Astro 5.0 заменяет это свойство на специальное свойство sharpImageService, используемое для определения совместимости адаптера со встроенным сервисом изображений sharp.

v5.0 также добавляет новое значение limited для различных свойств supportedAstroFeatures для адаптеров, что указывает на то, что адаптер совместим с функцией, но с некоторыми ограничениями. Это полезно для адаптеров, которые поддерживают функцию, но не во всех случаях или со всеми опциями.

Кроме того, значение различных свойств supportedAstroFeatures для адаптеров теперь может быть объектом с свойствами support и message. Содержимое свойства message будет отображать полезное сообщение в Astro CLI, если адаптер не совместим с функцией. Это особенно полезно с новым значением limited, чтобы объяснить пользователю, почему поддержка ограничена.

Если вы использовали свойство assets, удалите его, так как оно теперь недоступно. Чтобы указать, что ваш адаптер поддерживает встроенный сервис изображений sharp, замените его на sharpImageService.

Вы также можете обновить поддерживаемые функции с новым значением limited и включить сообщение о поддержке вашего адаптера.

my-adapter.mjs
supportedAstroFeatures: {
assets: {
supportKind: "stable",
isSharpCompatible: true,
isSquooshCompatible: true,
},
sharpImageService: {
support: "limited",
message: 'Этот адаптер поддерживает встроенный сервис изображений sharp, но с некоторыми ограничениями.'
}
}

Удалено: Устаревшая форма определения для приложений Dev Toolbar (API Dev Toolbar)

Заголовок раздела Удалено: Устаревшая форма определения для приложений Dev Toolbar (API Dev Toolbar)

В Astro 4.x при создании приложения Dev Toolbar всё ещё можно было использовать устаревшую сигнатуру addDevToolbarApp(string);. Свойства id, title и icon для определения приложения затем предоставлялись через экспорт по умолчанию в entrypoint приложения.

Astro 5.0 полностью удаляет эту возможность в пользу текущей формы объекта при определении приложения Dev Toolbar в интеграции, что более интуитивно и позволяет Astro предоставлять более точные ошибки, если приложения панели инструментов не загружаются корректно.

Если вы использовали устаревшую форму, обновите ваше приложение Dev Toolbar, чтобы использовать новую форму:

my-integration.mjs
// Старая форма
addDevToolbarApp("./my-dev-toolbar-app.mjs");
// Новая форма
addDevToolbarApp({
id: "my-app",
name: "My App",
icon: "<svg>...</svg>",
entrypoint: "./my-dev-toolbar-app.mjs",
});
my-dev-toolbar-app.mjs
export default {
id: 'my-dev-toolbar-app',
title: 'My Dev Toolbar App',
icon: '🚀',
init() {
// ...
}
}

Удалено: настройка TypeScript во время create-astro

Заголовок раздела Удалено: настройка TypeScript во время create-astro

В Astro v4.x можно было выбрать одну из трех настроек TypeScript при создании нового проекта с помощью create astro, либо ответив на вопрос, либо передав соответствующий флаг --typescript с желаемой настройкой TypeScript.

Astro 5.0 обновляет команду CLI create astro, удаляя вопрос о TypeScript и связанный с ним флаг --typescript. Теперь «строгий» пресет является значением по умолчанию для всех новых проектов, созданных с помощью командной строки, и больше нет возможности настраивать это во время создания. Однако шаблон TypeScript всё ещё можно изменить вручную в tsconfig.json.

Если вы использовали флаг --typescript с create-astro, удалите его из вашей команды.

Окно терминала
npm create astro@latest -- --template <example-name> --typescript strict
npm create astro@latest -- --template <example-name>

Знаете хороший ресурс для Astro v5.0? Отредактируйте эту страницу и добавьте ссылку ниже!

Пожалуйста, проверьте проблемы Astro на GitHub для получения информации о зарегистрированных проблемах или чтобы создать новую проблему самостоятельно.

Внести свой вклад Сообщество Sponsor