Astro 5.14

Автор
Matt Kane

🍂 Astro 5.14 — богатый урожай: новые инструменты маршрутизации, async Svelte, React 19 actions и многое другое!

Устройтесь с тёплым напитком:

Чтобы обновить существующий проект, используйте CLI @astrojs/upgrade. Или обновите вручную:

# Рекомендуется:
npx @astrojs/upgrade
# Вручную:
npm install astro@latest
pnpm upgrade astro --latest
yarn upgrade astro --latest

Prerendered route collision warnings

Astro 5.14 упрощает поиск коллизий dynamic routes до production.

Раньше /blog/[slug] и /blog/[...all] на одном пути — рендерился только приоритетный маршрут, второй молча игнорировался. Сборка успешна, но страницы могли рендериться неожиданными маршрутами.

Теперь предупреждение: какие маршруты и на каком пути. Флаг failOnPrerenderConflict — fail сборки с ошибкой:

astro.config.mjs
export default defineConfig({
experimental: {
failOnPrerenderConflict: true,
},
});

experimental prerender conflict error.

routePattern in getStaticPaths

Свойство routePattern в контексте getStaticPaths — оригинальное определение dynamic segments (например /[...locale]/[files]/[slug]).

src/pages/[...locale]/[files]/[slug].astro
---
import { getLocalizedData } from "../../../utils/i18n";
export async function getStaticPaths({ routePattern }) {
const response = await fetch('...');
const data = await response.json();
console.log(routePattern); // [...locale]/[files]/[slug]
return data.flatMap((file) => getLocalizedData(file, routePattern));
}
const { locale, files, slug } = Astro.params;
---

routing reference.

Спасибо Robin Bühler!

Async rendering support for Svelte

Поддержка async rendering Svelte 5.36+ — await в server-rendered Svelte в Astro.

svelte.config.js
export default {
compilerOptions: {
experimental: {
async: true,
},
},
};
src/components/MySvelteComponent.svelte
<script>
let data = await fetch('/api/data').then(res => res.json());
</script>
<h1>{data.title}</h1>

Svelte docs.

React 19 Actions integration

useActionState() + стабильные getActionState() и withState() для Astro Actions:

import { actions } from 'astro:actions';
import { withState } from '@astrojs/react/actions';
import { useActionState } from 'react';
export function Like({ postId }: { postId: string }) {
const [state, action, pending] = useActionState(
withState(actions.like),
0,
);
return (
<form action={action}>
<input type="hidden" name="postId" value={postId} />
<button disabled={pending}>{state} ❤️</button>
</form>
);
}
import { defineAction } from 'astro:actions';
import { z } from 'astro/zod';
import { getActionState } from '@astrojs/react/actions';
export const server = {
like: defineAction({
input: z.object({
postId: z.string(),
}),
handler: async ({ postId }, ctx) => {
const currentLikes = getActionState<number>(ctx);
return currentLikes + 1;
},
}),
};
import { experimental_getActionState, experimental_withState } from '@astrojs/react/actions';
import { getActionState, withState } from '@astrojs/react/actions';

React integration guide.

SvgComponent type

Встроенный тип SvgComponent из astro/types:

type SvgComponent = typeof import("*.svg")
import type { SvgComponent } from "astro/types"

SVG docs.

Спасибо ADTC!

Non-Node.js libSQL support for Astro DB

libSQL на Cloudflare и non-Node.js. Режим web для workerd и Deno. mode: 'node' (default) без изменений; mode: 'web':

import db from '@astrojs/db';
import { defineConfig } from 'astro/config';
export default defineConfig({
integrations: [db({ mode: 'web' })],
});

@astrojs/db documentation.

Спасибо Adam Matthiesen!

Sitemap namespaces configuration

Опция namespaces для news, xhtml, image, video — все включены по умолчанию:

astro.config.mjs
import { sitemap } from '@astrojs/sitemap';
export default {
integrations: [
sitemap({
namespaces: {
video: false,
},
}),
],
};

Спасибо Julián Colombo!

getFontData for programmatic font access

getFontData() из astro:assets:

import { getFontData } from 'astro:assets';
const data = getFontData('--font-roboto');

С satori для OpenGraph:

src/pages/og.png.ts
import type { APIRoute } from 'astro';
import { getFontData } from 'astro:assets';
import satori from 'satori';
export const GET: APIRoute = (context) => {
const data = getFontData('--font-roboto');
const svg = await satori(<div style={{ color: 'black' }}>hello, world</div>, {
width: 600,
height: 400,
fonts: [
{
name: 'Roboto',
data: await fetch(new URL(data[0].src[0].url, context.url.origin)).then(
(res) => res.arrayBuffer(),
),
weight: 400,
style: 'normal',
},
],
});
// ...
};

experimental Fonts API documentation.

Bug fixes

С релиза 5.13changelog.

Community

Команда Astro:

Alexander Niebuhr, Ben Holmes, Caleb Jasik, Chris Swithinbank, Emanuele Stoppa, Erika, Florian Lefebvre, Fred Schott, Fuzzy, HiDeoo, Luiz Ferraz, Matt Kane, Matthew Phillips, Reuben Tier, Sarah Rainsberger, and Yan Thomas.

Спасибо 0xJoeDev, Adam Matthiesen, ADTC, Álvaro Mondéjar Rubio, Andrey, Ariel K, Armand Philippot, Bugo, Dave Kiss, Eyozy, Felix Schneider, Fred K. Schott, Gabriel Woitechen, Gourav Khunger, Guan Un, Hadi Baalbaki, Hunter Bertoson, InertSloth 🦥, Jack Platten, Jack Smith, Joe, Jon Darby, julesyoungberg, Julián Colombo, Junseong Park, Justin Hall, knj, Light, liruifengv, Louis Escher, Manuel Meister, Martin Trapp, Matthew Conto, Matthew Justice, Maurici Abad Gutierrez, mcorrochanoa, Michael Hoser, Mikaël Sévigny, Oliver Speir, paul valladares, Platol, prajwal, Robin Bühler, Roman, Sebastian Beltran, Sherqo, Stephanie Lin, Tanishq Manuja, Tarik, Thomas Bonnet, ugu, vrabe, WavyCat, Waxer59, and Zubair Ibn Zamir