#17894b7a1bd9 Thanks @Princesseuh! - Adds a new --timings flag to astro build to help you find what slows down your builds
When a build takes longer than expected, it can be hard to tell whether the cause is an integration, a Markdown processor plugin, image processing, or even syntax highlighting. Add the --timings flag to your build command to print a summary once the build finishes:
astro build --timings
This is helpful to decide what to optimize first, or to compare build times before and after a change to your project.
Font providers can now expose the weights, styles, subsets and formats a font family actually has. Astro uses it when resolving your font configuration to warn about values a provider cannot serve, for example a weight a font family does not offer.
All built-in providers implement it. If you maintain a custom font provider, implementing this callback is optional for now but it will be required in Astro 8:
This function requests a provider API, retrying transient failures and more. It lets providers that wrap a 3rd-party unifont provider pass the context to it directly:
#180150b30239 Thanks @florian-lefebvre! - Adds experimental.redirectPage, letting you provide your own src/pages/3xx.astro in place of the redirect page Astro generates in static builds.
A static site has no server to send an HTTP Location header, so Astro generates a small HTML page with a <meta http-equiv="refresh"> tag for each redirect it builds:
Then create src/pages/3xx.astro. Astro renders it once per redirect, passing that redirect's details as props:
---
// src/pages/3xx.astro
import type { RedirectPageProps as Props } from 'astro';
const { from, to, status, delay } = Astro.props;
---
<html lang="en">
<head>
<meta http-equiv="refresh" content={`${delay};url=${to}`} />
<meta name="robots" content="noindex" />
<title>Redirecting…</title>
</head>
<body>
<p>This page has moved. <a href={to}>Continue to {to}</a>.</p>
</body>
</html>
Your page must render a <meta http-equiv="refresh"> tag pointing at to, because in a static build that tag is the redirect. Astro logs a warning during the build if it is missing.
#18265910ee69 Thanks @astro-factory! - Adds a notFound() handler to astro/fetch and astro/hono that renders the custom 404 page when no route matches, including a prerendered 404.astro
Add it before pages() in a custom worker or server entrypoint that does not run inside App.render, such as a Hono app used directly as a Cloudflare worker. Without it, pages() and middleware() return an empty 404 with an internal X-Astro-Error header for unmatched routes. astro() already includes this handling.
image.service now also accepts a build and a runtime service. The build service optimizes images on prerendered pages when you build your site, and is also used during development. The runtime service handles images on on-demand rendered pages and the image endpoint of your deployed site.
The following example uses Sharp to optimize images on prerendered pages, and an image CDN for on-demand rendered pages:
config.image.service keeps the shape the user configured it with. When a project sets build and runtime services, config.image.service.entrypoint and config.image.service.config are undefined.
If your integration reads image.service, check for the runtime property to get the service you need:
Setting image.service with updateConfig() replaces the existing service instead of merging with it when the two use different shapes. For example, setting a single service in a project that uses build and runtime services replaces both.
The minimum supported Node.js version is now 22.22.0, the latest Node.js 22 release supported by StackBlitz. This change is in line with Astro's Node.js support policy.
#1831371e2b24 Thanks @matthewp! - Allows integrations to control where Astro writes client, server, and prerender build output.
Custom prerenderers can access the final output locations through the new outputDirectories context:
Astro now generates images on prerendered pages from the image information that a prerenderer's getStaticPaths() and render() return. If your prerenderer wraps Astro's default one, pass this information through:
Returning a plain array from getStaticPaths() or a plain Response from render() still works, but is deprecated: images used on those pages are not generated.
This experimental feature makes astro build render your static pages in parallel, using multiple CPU cores at once instead of one. On sites with many pages, this can significantly reduce build times, at the cost of higher memory usage.
To enable this feature, add the experimental flag in your Astro config:
By default, Astro uses all available CPU cores but one. Each additional worker increases the memory used by your build. If your build runs out of memory, or does not get faster, set workers to a lower number:
Each worker renders as many pages at once as your build.concurrency setting allows.
This feature has no effect when your adapter provides its own way of prerendering pages. Among official adapters, this only applies to @astrojs/cloudflare. Astro logs a warning during the build when the flag is ignored.
#1835559b9cc0 Thanks @matthewp! - Fixes prerender errors being silently swallowed when using a custom src/fetch.ts with an adapter that prerenders in its own runtime, such as @astrojs/cloudflare. Previously, a page that threw during prerendering was written as an empty HTML file and the build succeeded. The build now fails with the underlying error.
#181777d814e5 Thanks @Princesseuh! - Fixes original images being kept despite only width or height being read.
#18353af54bfa Thanks @astro-factory! - Fixes glob() loader swallowing rendering errors during content sync, which allowed astro build to exit successfully (code 0) even when a remark/rehype plugin threw an error
#1827123e8e28 Thanks @ArmandPhilippot! - Fixes the sync command description in astro help, which only mentioned content collections.
Remove the deepmerge dependency, which was used only to combine tag-specific and * (all tags) entries in allowedClasses and allowedStyles. That is now done by a few lines of code within sanitize-html.
This is not a fix for a vulnerability in sanitize-html. Security scanners such as Snyk now report CVE-2026-93753 in deepmerge, which can affect applications that merge untrusted objects, such as parsed JSON request bodies. sanitize-html only ever merged the developer's own configuration, never anything taken from the HTML being sanitized, so it was not exploitable through sanitize-html. Since we needed only a small part of what deepmerge does, we removed the dependency so that these reports no longer appear for sanitize-html users.
Security
Since 2.18.0, the fallback markup of a discarded <iframe> was re-sanitized by a recursive call with no limit, one level per nested unclosed <iframe>. A few kilobytes of crafted input could throw RangeError: Maximum call stack size exceeded with the default options, and the nestingLimit option was not enforced across the fallback because each nested call started counting from zero. The fallback of a discarded <iframe> is still sanitized and kept, but only up to eight nested <iframe> elements (deeper fallback is escaped as text, as before 2.18.0), and the current nesting depth now carries into the nested call so nestingLimit applies to the whole output. Only 2.18.0 was affected, and the exception is thrown synchronously, so applications that catch errors from sanitizeHtml only lost the affected request (CWE-674, GHSA-c9rx-x947-fp3h).
This PR contains the following updates:
| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@astrojs/markdown-remark](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/markdown/remark)) | [`7.3.2` → `7.3.3`](https://renovatebot.com/diffs/npm/@astrojs%2fmarkdown-remark/7.3.2/7.3.3) |  |  |
| [astro](https://astro.build) ([source](https://github.com/withastro/astro/tree/HEAD/packages/astro)) | [`7.3.8` → `7.4.0`](https://renovatebot.com/diffs/npm/astro/7.3.8/7.4.0) |  |  |
| [sanitize-html](https://github.com/apostrophecms/apostrophe/tree/main/packages/sanitize-html#readme) ([source](https://github.com/apostrophecms/apostrophe/tree/HEAD/packages/sanitize-html)) | [`2.18.0` → `2.18.1`](https://renovatebot.com/diffs/npm/sanitize-html/2.18.0/2.18.1) |  |  |
| [satori](https://github.com/vercel/satori) | [`^0.56.0` → `^0.60.0`](https://renovatebot.com/diffs/npm/satori/0.56.1/0.60.0) |  |  |
---
### Release Notes
<details>
<summary>withastro/astro (@​astrojs/markdown-remark)</summary>
### [`v7.3.3`](https://github.com/withastro/astro/blob/HEAD/packages/markdown/remark/CHANGELOG.md#733)
[Compare Source](https://github.com/withastro/astro/compare/@astrojs/markdown-remark@7.3.2...@astrojs/markdown-remark@7.3.3)
##### Patch Changes
- [#​17894](https://github.com/withastro/astro/pull/17894) [`b7a1bd9`](https://github.com/withastro/astro/commit/b7a1bd99ac7c68cf36078058f15f1bd1fab4cbe8) Thanks [@​Princesseuh](https://github.com/Princesseuh)! - Adds the measurements that `astro build --timings` reports for Markdown processing and syntax highlighting.
- Updated dependencies \[[`b7a1bd9`](https://github.com/withastro/astro/commit/b7a1bd99ac7c68cf36078058f15f1bd1fab4cbe8), [`2715958`](https://github.com/withastro/astro/commit/2715958666b0a706b069d0592da3a070b3796a9b)]:
- [@​astrojs/internal-helpers](https://github.com/astrojs/internal-helpers)@0.13.0
- [@​astrojs/prism](https://github.com/astrojs/prism)@4.1.0
</details>
<details>
<summary>withastro/astro (astro)</summary>
### [`v7.4.0`](https://github.com/withastro/astro/blob/HEAD/packages/astro/CHANGELOG.md#740)
[Compare Source](https://github.com/withastro/astro/compare/astro@7.3.8...astro@7.4.0)
##### Minor Changes
- [#​17894](https://github.com/withastro/astro/pull/17894) [`b7a1bd9`](https://github.com/withastro/astro/commit/b7a1bd99ac7c68cf36078058f15f1bd1fab4cbe8) Thanks [@​Princesseuh](https://github.com/Princesseuh)! - Adds a new `--timings` flag to `astro build` to help you find what slows down your builds
When a build takes longer than expected, it can be hard to tell whether the cause is an integration, a Markdown processor plugin, image processing, or even syntax highlighting. Add the `--timings` flag to your build command to print a summary once the build finishes:
```sh
astro build --timings
```
This is helpful to decide what to optimize first, or to compare build times before and after a change to your project.
- [#​17830](https://github.com/withastro/astro/pull/17830) [`a937b0d`](https://github.com/withastro/astro/commit/a937b0d3ec236c8dd1c62a7a4da7c65b2fdbb7c1) Thanks [@​florian-lefebvre](https://github.com/florian-lefebvre)! - Adds a new optional `getFontProperties()` callback to font providers
Font providers can now expose the weights, styles, subsets and formats a font family actually has. Astro uses it when resolving your font configuration to warn about values a provider cannot serve, for example a weight a font family does not offer.
All built-in providers implement it. If you maintain a custom font provider, implementing this callback is optional for now but it will be required in Astro 8:
```ts
import type { FontProvider } from 'astro';
const provider: FontProvider = {
name: 'my-provider',
resolveFont: ({ familyName }) => {
// ...
},
getFontProperties: ({ familyName }) => ({
weights: ['400', '700'],
styles: ['normal', 'italic'],
subsets: ['latin'],
formats: ['woff2'],
}),
};
```
- [#​17830](https://github.com/withastro/astro/pull/17830) [`a937b0d`](https://github.com/withastro/astro/commit/a937b0d3ec236c8dd1c62a7a4da7c65b2fdbb7c1) Thanks [@​florian-lefebvre](https://github.com/florian-lefebvre)! - Adds a `fetch()` function to the font provider `init()` context
This function requests a provider API, retrying transient failures and more. It lets providers that wrap a 3rd-party unifont provider pass the context to it directly:
```ts
import type { FontProvider } from 'astro';
import type { InitializedProvider } from 'unifont';
import { acmeProvider } from '@acme/unifont-provider';
export function acmeFontProvider(): FontProvider {
const provider = acmeProvider();
let initializedProvider: InitializedProvider | undefined;
return {
name: provider._name,
async init(context) {
initializedProvider = await provider(context);
},
// ...
};
}
```
- [#​18015](https://github.com/withastro/astro/pull/18015) [`0b30239`](https://github.com/withastro/astro/commit/0b302391059dbc4f8ece24d7b44599c7ec9fef24) Thanks [@​florian-lefebvre](https://github.com/florian-lefebvre)! - Adds `experimental.redirectPage`, letting you provide your own `src/pages/3xx.astro` in place of the redirect page Astro generates in static builds.
A static site has no server to send an HTTP `Location` header, so Astro generates a small HTML page with a `<meta http-equiv="refresh">` tag for each redirect it builds:
- Your [`redirects`](https://docs.astro.build/en/reference/configuration-reference/#redirects) entries
- `Astro.redirect()` calls in prerendered pages
- i18n redirects
That page's markup, wording, and refresh delay were fixed, so you could not brand or translate it.
To enable this feature, add the experimental flag to your Astro config:
```js
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
redirectPage: true,
},
});
```
Then create `src/pages/3xx.astro`. Astro renders it once per redirect, passing that redirect's details as props:
```astro
---
// src/pages/3xx.astro
import type { RedirectPageProps as Props } from 'astro';
const { from, to, status, delay } = Astro.props;
---
<html lang="en">
<head>
<meta http-equiv="refresh" content={`${delay};url=${to}`} />
<meta name="robots" content="noindex" />
<title>Redirecting…</title>
</head>
<body>
<p>This page has moved. <a href={to}>Continue to {to}</a>.</p>
</body>
</html>
```
Your page must render a `<meta http-equiv="refresh">` tag pointing at `to`, because in a static build that tag is the redirect. Astro logs a warning during the build if it is missing.
See the [experimental redirect page documentation](https://docs.astro.build/en/reference/experimental-flags/redirect-page/) for more information.
- [#​18265](https://github.com/withastro/astro/pull/18265) [`910ee69`](https://github.com/withastro/astro/commit/910ee69147c4c2460f2b31a294bc70c5269f44d4) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Adds a `notFound()` handler to `astro/fetch` and `astro/hono` that renders the custom 404 page when no route matches, including a prerendered `404.astro`
Add it before `pages()` in a custom worker or server entrypoint that does not run inside `App.render`, such as a Hono app used directly as a Cloudflare worker. Without it, `pages()` and `middleware()` return an empty 404 with an internal `X-Astro-Error` header for unmatched routes. `astro()` already includes this handling.
```ts
import { Hono } from 'hono';
import { notFound, pages } from 'astro/hono';
import { cf } from '@astrojs/cloudflare/hono';
const app = new Hono();
app.use(cf());
app.use(notFound());
app.use(pages());
export default app;
```
- [#​18177](https://github.com/withastro/astro/pull/18177) [`7d814e5`](https://github.com/withastro/astro/commit/7d814e5ac3e7c84b4e4fd4e6c7cc6820f553742c) Thanks [@​Princesseuh](https://github.com/Princesseuh)! - Adds support for separate `build` and `runtime` image services
`image.service` now also accepts a `build` and a `runtime` service. The `build` service optimizes images on prerendered pages when you build your site, and is also used during development. The `runtime` service handles images on on-demand rendered pages and the image endpoint of your deployed site.
The following example uses Sharp to optimize images on prerendered pages, and an image CDN for on-demand rendered pages:
```js
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
image: {
service: {
build: { entrypoint: 'astro/assets/services/sharp' },
runtime: { entrypoint: 'my-image-cdn-service' },
},
},
});
```
##### Changes for integration authors
`config.image.service` keeps the shape the user configured it with. When a project sets `build` and `runtime` services, `config.image.service.entrypoint` and `config.image.service.config` are `undefined`.
If your integration reads `image.service`, check for the `runtime` property to get the service you need:
```ts
'astro:config:done': ({ config }) => {
const { service } = config.image;
const runtimeService = 'runtime' in service ? service.runtime : service;
if (runtimeService.entrypoint === 'astro/assets/services/sharp') {
// ...
}
},
```
Setting `image.service` with `updateConfig()` replaces the existing service instead of merging with it when the two use different shapes. For example, setting a single service in a project that uses `build` and `runtime` services replaces both.
- [#​18277](https://github.com/withastro/astro/pull/18277) [`2715958`](https://github.com/withastro/astro/commit/2715958666b0a706b069d0592da3a070b3796a9b) Thanks [@​florian-lefebvre](https://github.com/florian-lefebvre)! - Increases the minimum Node.js version to 22.22.0
The minimum supported Node.js version is now 22.22.0, the latest Node.js 22 release supported by StackBlitz. This change is in line with Astro's [Node.js support policy](https://docs.astro.build/en/upgrade-astro/#support).
- [#​18313](https://github.com/withastro/astro/pull/18313) [`71e2b24`](https://github.com/withastro/astro/commit/71e2b24bb365e5a8809fc0432716f91ecc6d8ab5) Thanks [@​matthewp](https://github.com/matthewp)! - Allows integrations to control where Astro writes client, server, and prerender build output.
Custom prerenderers can access the final output locations through the new `outputDirectories` context:
```ts
setPrerenderer((defaultPrerenderer, { outputDirectories }) => {
const { client, server, prerender } = outputDirectories
return createPrerenderer({
defaultPrerenderer,
client,
server,
prerender,
})
})
```
- [#​18177](https://github.com/withastro/astro/pull/18177) [`7d814e5`](https://github.com/withastro/astro/commit/7d814e5ac3e7c84b4e4fd4e6c7cc6820f553742c) Thanks [@​Princesseuh](https://github.com/Princesseuh)! - Lets custom prerenderers report the images used on prerendered pages
Astro now generates images on prerendered pages from the image information that a prerenderer's `getStaticPaths()` and `render()` return. If your prerenderer wraps Astro's default one, pass this information through:
```js
setPrerenderer((defaultPrerenderer) => ({
name: 'my-prerenderer',
async setup() {
await defaultPrerenderer.setup?.();
},
async getStaticPaths() {
const result = await defaultPrerenderer.getStaticPaths();
const { paths, metadata } = Array.isArray(result) ? { paths: result } : result;
return { paths: paths.filter(({ pathname }) => !pathname.startsWith('/drafts')), metadata };
},
render(request, options) {
return defaultPrerenderer.render(request, options);
},
async teardown() {
await defaultPrerenderer.teardown?.();
},
}));
```
Returning a plain array from `getStaticPaths()` or a plain `Response` from `render()` still works, but is deprecated: images used on those pages are not generated.
- [#​17932](https://github.com/withastro/astro/pull/17932) [`b905ff1`](https://github.com/withastro/astro/commit/b905ff1a8649b7a9a9056d9b05ca25ae7b3c07a1) Thanks [@​Princesseuh](https://github.com/Princesseuh)! - Adds support for experimental parallel prerendering
This experimental feature makes `astro build` render your static pages in parallel, using multiple CPU cores at once instead of one. On sites with many pages, this can significantly reduce build times, at the cost of higher memory usage.
To enable this feature, add the experimental flag in your Astro config:
```js
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
parallelPrerender: true,
},
});
```
By default, Astro uses all available CPU cores but one. Each additional worker increases the memory used by your build. If your build runs out of memory, or does not get faster, set `workers` to a lower number:
```js
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
parallelPrerender: {
workers: 4,
},
},
});
```
Each worker renders as many pages at once as your [`build.concurrency`](https://docs.astro.build/en/reference/configuration-reference/#buildconcurrency) setting allows.
This feature has no effect when your adapter provides its own way of prerendering pages. Among official adapters, this only applies to `@astrojs/cloudflare`. Astro logs a warning during the build when the flag is ignored.
For more information on enabling and using this feature in your project, see the [experimental parallel prerendering docs](https://docs.astro.build/en/reference/experimental-flags/parallel-prerender/).
##### Patch Changes
- [#​18313](https://github.com/withastro/astro/pull/18313) [`71e2b24`](https://github.com/withastro/astro/commit/71e2b24bb365e5a8809fc0432716f91ecc6d8ab5) Thanks [@​matthewp](https://github.com/matthewp)! - Fixes deployment integrations being unable to use Vite manifests when preparing build output
- [#​18270](https://github.com/withastro/astro/pull/18270) [`0c3bf11`](https://github.com/withastro/astro/commit/0c3bf116ee70aae4772313fc167a372c7d54869e) Thanks [@​ArmandPhilippot](https://github.com/ArmandPhilippot)! - Fixes the JSDoc for CSP utilities to point to the render context reference in docs.
- [#​18368](https://github.com/withastro/astro/pull/18368) [`1f04637`](https://github.com/withastro/astro/commit/1f04637a6ca23b59e8982424248ead47d6a3ec31) Thanks [@​43081j](https://github.com/43081j)! - Replaces internal use of `find-proc` with `tinyps`.
- [#​18355](https://github.com/withastro/astro/pull/18355) [`59b9cc0`](https://github.com/withastro/astro/commit/59b9cc00726495bb45f5c4b000dbbb7b5a19d662) Thanks [@​matthewp](https://github.com/matthewp)! - Fixes prerender errors being silently swallowed when using a custom `src/fetch.ts` with an adapter that prerenders in its own runtime, such as `@astrojs/cloudflare`. Previously, a page that threw during prerendering was written as an empty HTML file and the build succeeded. The build now fails with the underlying error.
- [#​18177](https://github.com/withastro/astro/pull/18177) [`7d814e5`](https://github.com/withastro/astro/commit/7d814e5ac3e7c84b4e4fd4e6c7cc6820f553742c) Thanks [@​Princesseuh](https://github.com/Princesseuh)! - Fixes original images being kept despite only `width` or `height` being read.
- [#​18353](https://github.com/withastro/astro/pull/18353) [`af54bfa`](https://github.com/withastro/astro/commit/af54bfaebff9180cb96822c0da11737b4b26e65a) Thanks [@​astro-factory](https://github.com/apps/astro-factory)! - Fixes `glob()` loader swallowing rendering errors during content sync, which allowed `astro build` to exit successfully (code 0) even when a remark/rehype plugin threw an error
- [#​18271](https://github.com/withastro/astro/pull/18271) [`23e8e28`](https://github.com/withastro/astro/commit/23e8e28c22effe006fe19abb193802e2fec8eaab) Thanks [@​ArmandPhilippot](https://github.com/ArmandPhilippot)! - Fixes the `sync` command description in `astro help`, which only mentioned content collections.
- Updated dependencies \[[`b7a1bd9`](https://github.com/withastro/astro/commit/b7a1bd99ac7c68cf36078058f15f1bd1fab4cbe8), [`2715958`](https://github.com/withastro/astro/commit/2715958666b0a706b069d0592da3a070b3796a9b)]:
- [@​astrojs/internal-helpers](https://github.com/astrojs/internal-helpers)@0.13.0
- [@​astrojs/markdown-satteri](https://github.com/astrojs/markdown-satteri)@0.4.4
- [@​astrojs/telemetry](https://github.com/astrojs/telemetry)@3.4.0
</details>
<details>
<summary>apostrophecms/apostrophe (sanitize-html)</summary>
### [`v2.18.1`](https://github.com/apostrophecms/apostrophe/blob/HEAD/packages/sanitize-html/CHANGELOG.md#2181-2026-10-14)
[Compare Source](https://github.com/apostrophecms/apostrophe/compare/sanitize-html@2.18.0...sanitize-html@2.18.1)
##### Changes
- Remove the `deepmerge` dependency, which was used only to combine tag-specific and `*` (all tags) entries in `allowedClasses` and `allowedStyles`. That is now done by a few lines of code within sanitize-html.
This is not a fix for a vulnerability in sanitize-html. Security scanners such as Snyk now report [CVE-2026-93753](https://security.snyk.io/vuln/SNYK-JS-DEEPMERGE-19964053) in `deepmerge`, which can affect applications that merge untrusted objects, such as parsed JSON request bodies. sanitize-html only ever merged the developer's own configuration, never anything taken from the HTML being sanitized, so it was not exploitable through sanitize-html. Since we needed only a small part of what `deepmerge` does, we removed the dependency so that these reports no longer appear for sanitize-html users.
##### Security
- Since 2.18.0, the fallback markup of a discarded `<iframe>` was re-sanitized by a recursive call with no limit, one level per nested unclosed `<iframe>`. A few kilobytes of crafted input could throw `RangeError: Maximum call stack size exceeded` with the default options, and the `nestingLimit` option was not enforced across the fallback because each nested call started counting from zero. The fallback of a discarded `<iframe>` is still sanitized and kept, but only up to eight nested `<iframe>` elements (deeper fallback is escaped as text, as before 2.18.0), and the current nesting depth now carries into the nested call so `nestingLimit` applies to the whole output. Only 2.18.0 was affected, and the exception is thrown synchronously, so applications that catch errors from `sanitizeHtml` only lost the affected request (CWE-674, GHSA-c9rx-x947-fp3h).
Thanks to [hkmj19](https://github.com/hkmj19), [JohnBeckley](https://github.com/JohnBeckley), and [amikhailovstiltsoft](https://github.com/amikhailovstiltsoft) for reporting the vulnerability.
</details>
<details>
<summary>vercel/satori (satori)</summary>
### [`v0.60.0`](https://github.com/vercel/satori/releases/tag/0.60.0)
[Compare Source](https://github.com/vercel/satori/compare/0.59.2...0.60.0)
##### Bug Fixes
- Don't inherit registered custom properties without initial values ([#​930](https://github.com/vercel/satori/issues/930)) ([18207e7](https://github.com/vercel/satori/commit/18207e75d53e0e0c557fd38c885d786d3b4fa1e8)), closes [#​921](https://github.com/vercel/satori/issues/921)
##### Features
- Support container units ([#​926](https://github.com/vercel/satori/issues/926)) ([b75a07b](https://github.com/vercel/satori/commit/b75a07b3b90327f349d2e56657a984ddd2ebe33e))
### [`v0.59.2`](https://github.com/vercel/satori/releases/tag/0.59.2)
[Compare Source](https://github.com/vercel/satori/compare/0.59.1...0.59.2)
##### Bug Fixes
- Avoid quadratic backtracking in number patterns ([#​929](https://github.com/vercel/satori/issues/929)) ([070eeca](https://github.com/vercel/satori/commit/070eecaeefe80917c0eae9ba7e3be98fdd0e912a)), closes [#​926](https://github.com/vercel/satori/issues/926)
### [`v0.59.1`](https://github.com/vercel/satori/releases/tag/0.59.1)
[Compare Source](https://github.com/vercel/satori/compare/0.59.0...0.59.1)
##### Bug Fixes
- Don't change the size of text with text-wrap: balance ([#​925](https://github.com/vercel/satori/issues/925)) ([e723cdb](https://github.com/vercel/satori/commit/e723cdb4a7145b499a43a609c98fb15eb6e2baa6))
- Support math functions in line-height ([#​928](https://github.com/vercel/satori/issues/928)) ([0e52a95](https://github.com/vercel/satori/commit/0e52a9528ce45ef1934dbccfe03807d69843014f)), closes [#​927](https://github.com/vercel/satori/issues/927) [#​927](https://github.com/vercel/satori/issues/927)
### [`v0.59.0`](https://github.com/vercel/satori/releases/tag/0.59.0)
[Compare Source](https://github.com/vercel/satori/compare/0.58.0...0.59.0)
##### Features
- Render the value or placeholder of text inputs ([#​923](https://github.com/vercel/satori/issues/923)) ([7394b9b](https://github.com/vercel/satori/commit/7394b9bee9d6883a9a96b9db6981cda8e147f568))
### [`v0.58.0`](https://github.com/vercel/satori/releases/tag/0.58.0)
[Compare Source](https://github.com/vercel/satori/compare/0.57.2...0.58.0)
##### Bug Fixes
- Use the width of 0 in the font for the ch unit ([#​922](https://github.com/vercel/satori/issues/922)) ([97649cc](https://github.com/vercel/satori/commit/97649cc0cca5aa93ecf52fe9f47ab3dadee1b312))
##### Features
- Support [@​property](https://github.com/property) in stylesheets ([#​921](https://github.com/vercel/satori/issues/921)) ([6d78b67](https://github.com/vercel/satori/commit/6d78b67ccf275df8d920f3d92fc41ea1b55ac052))
### [`v0.57.2`](https://github.com/vercel/satori/releases/tag/0.57.2)
[Compare Source](https://github.com/vercel/satori/compare/0.57.1...0.57.2)
##### Bug Fixes
- Don't report the internal container prop of hidden elements ([#​920](https://github.com/vercel/satori/issues/920)) ([dc42783](https://github.com/vercel/satori/commit/dc42783f5317bce03582049b561534fd55a699d1)), closes [#​908](https://github.com/vercel/satori/issues/908) [#​914](https://github.com/vercel/satori/issues/914)
### [`v0.57.1`](https://github.com/vercel/satori/releases/tag/0.57.1)
[Compare Source](https://github.com/vercel/satori/compare/0.57.0...0.57.1)
##### Bug Fixes
- Don't render white space between flex and grid items ([#​915](https://github.com/vercel/satori/issues/915)) ([e236985](https://github.com/vercel/satori/commit/e2369851226455287fedd511a614aa69788955a9))
- Place text in line boxes like Chrome ([#​917](https://github.com/vercel/satori/issues/917)) ([fd600ac](https://github.com/vercel/satori/commit/fd600ac8b84238f345a2bca0a3aec15a161e1ba4)), closes [#​915](https://github.com/vercel/satori/issues/915)
- Support math functions in grid track sizes ([#​918](https://github.com/vercel/satori/issues/918)) ([646eec2](https://github.com/vercel/satori/commit/646eec2971cd7942c1b71b33a3606118f5a2ae92)), closes [#​915](https://github.com/vercel/satori/issues/915) [#​917](https://github.com/vercel/satori/issues/917) [#​915](https://github.com/vercel/satori/issues/915) [#​915](https://github.com/vercel/satori/issues/915) [#​917](https://github.com/vercel/satori/issues/917) [#​919](https://github.com/vercel/satori/issues/919)
##### Performance Improvements
- Don't lay out the content of elements that aren't displayed ([#​908](https://github.com/vercel/satori/issues/908)) ([df9e2b5](https://github.com/vercel/satori/commit/df9e2b512de023304b9488e18c1358a1a5a1576f))
### [`v0.57.0`](https://github.com/vercel/satori/releases/tag/0.57.0)
[Compare Source](https://github.com/vercel/satori/compare/0.56.2...0.57.0)
##### Bug Fixes
- Support more viewport units, lh and max sizes of none ([#​913](https://github.com/vercel/satori/issues/913)) ([b0348a2](https://github.com/vercel/satori/commit/b0348a242cfd308d74cf17df7b6e82e558c73b11))
##### Features
- Support container queries in stylesheets ([#​914](https://github.com/vercel/satori/issues/914)) ([7a5b152](https://github.com/vercel/satori/commit/7a5b152b47e66b02669ae2be95cbce1e193927f7))
### [`v0.56.2`](https://github.com/vercel/satori/releases/tag/0.56.2)
[Compare Source](https://github.com/vercel/satori/compare/0.56.1...0.56.2)
##### Bug Fixes
- Move to the start of closed SVG subpaths that continue ([#​912](https://github.com/vercel/satori/issues/912)) ([59361dd](https://github.com/vercel/satori/commit/59361ddc24833b3f383352a04caeb8053f8dbf72))
- Size text with the points scale factor ([#​910](https://github.com/vercel/satori/issues/910)) ([bb3d658](https://github.com/vercel/satori/commit/bb3d658ba13b72af7a18f59865b05af9526e9aaf))
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNjQuNyIsInVwZGF0ZWRJblZlciI6IjQ0LjE2NC43IiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbImF1dG9tYXRlZCIsImRlcGVuZGVuY2llcyJdfQ==-->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This PR contains the following updates:
7.3.2→7.3.37.3.8→7.4.02.18.0→2.18.1^0.56.0→^0.60.0Release Notes
withastro/astro (@astrojs/markdown-remark)
v7.3.3Compare Source
Patch Changes
b7a1bd9Thanks @Princesseuh! - Adds the measurements thatastro build --timingsreports for Markdown processing and syntax highlighting.b7a1bd9,2715958]:withastro/astro (astro)
v7.4.0Compare Source
Minor Changes
#17894
b7a1bd9Thanks @Princesseuh! - Adds a new--timingsflag toastro buildto help you find what slows down your buildsWhen a build takes longer than expected, it can be hard to tell whether the cause is an integration, a Markdown processor plugin, image processing, or even syntax highlighting. Add the
--timingsflag to your build command to print a summary once the build finishes:This is helpful to decide what to optimize first, or to compare build times before and after a change to your project.
#17830
a937b0dThanks @florian-lefebvre! - Adds a new optionalgetFontProperties()callback to font providersFont providers can now expose the weights, styles, subsets and formats a font family actually has. Astro uses it when resolving your font configuration to warn about values a provider cannot serve, for example a weight a font family does not offer.
All built-in providers implement it. If you maintain a custom font provider, implementing this callback is optional for now but it will be required in Astro 8:
#17830
a937b0dThanks @florian-lefebvre! - Adds afetch()function to the font providerinit()contextThis function requests a provider API, retrying transient failures and more. It lets providers that wrap a 3rd-party unifont provider pass the context to it directly:
#18015
0b30239Thanks @florian-lefebvre! - Addsexperimental.redirectPage, letting you provide your ownsrc/pages/3xx.astroin place of the redirect page Astro generates in static builds.A static site has no server to send an HTTP
Locationheader, so Astro generates a small HTML page with a<meta http-equiv="refresh">tag for each redirect it builds:redirectsentriesAstro.redirect()calls in prerendered pagesThat page's markup, wording, and refresh delay were fixed, so you could not brand or translate it.
To enable this feature, add the experimental flag to your Astro config:
Then create
src/pages/3xx.astro. Astro renders it once per redirect, passing that redirect's details as props:Your page must render a
<meta http-equiv="refresh">tag pointing atto, because in a static build that tag is the redirect. Astro logs a warning during the build if it is missing.See the experimental redirect page documentation for more information.
#18265
910ee69Thanks @astro-factory! - Adds anotFound()handler toastro/fetchandastro/honothat renders the custom 404 page when no route matches, including a prerendered404.astroAdd it before
pages()in a custom worker or server entrypoint that does not run insideApp.render, such as a Hono app used directly as a Cloudflare worker. Without it,pages()andmiddleware()return an empty 404 with an internalX-Astro-Errorheader for unmatched routes.astro()already includes this handling.#18177
7d814e5Thanks @Princesseuh! - Adds support for separatebuildandruntimeimage servicesimage.servicenow also accepts abuildand aruntimeservice. Thebuildservice optimizes images on prerendered pages when you build your site, and is also used during development. Theruntimeservice handles images on on-demand rendered pages and the image endpoint of your deployed site.The following example uses Sharp to optimize images on prerendered pages, and an image CDN for on-demand rendered pages:
Changes for integration authors
config.image.servicekeeps the shape the user configured it with. When a project setsbuildandruntimeservices,config.image.service.entrypointandconfig.image.service.configareundefined.If your integration reads
image.service, check for theruntimeproperty to get the service you need:Setting
image.servicewithupdateConfig()replaces the existing service instead of merging with it when the two use different shapes. For example, setting a single service in a project that usesbuildandruntimeservices replaces both.#18277
2715958Thanks @florian-lefebvre! - Increases the minimum Node.js version to 22.22.0The minimum supported Node.js version is now 22.22.0, the latest Node.js 22 release supported by StackBlitz. This change is in line with Astro's Node.js support policy.
#18313
71e2b24Thanks @matthewp! - Allows integrations to control where Astro writes client, server, and prerender build output.Custom prerenderers can access the final output locations through the new
outputDirectoriescontext:#18177
7d814e5Thanks @Princesseuh! - Lets custom prerenderers report the images used on prerendered pagesAstro now generates images on prerendered pages from the image information that a prerenderer's
getStaticPaths()andrender()return. If your prerenderer wraps Astro's default one, pass this information through:Returning a plain array from
getStaticPaths()or a plainResponsefromrender()still works, but is deprecated: images used on those pages are not generated.#17932
b905ff1Thanks @Princesseuh! - Adds support for experimental parallel prerenderingThis experimental feature makes
astro buildrender your static pages in parallel, using multiple CPU cores at once instead of one. On sites with many pages, this can significantly reduce build times, at the cost of higher memory usage.To enable this feature, add the experimental flag in your Astro config:
By default, Astro uses all available CPU cores but one. Each additional worker increases the memory used by your build. If your build runs out of memory, or does not get faster, set
workersto a lower number:Each worker renders as many pages at once as your
build.concurrencysetting allows.This feature has no effect when your adapter provides its own way of prerendering pages. Among official adapters, this only applies to
@astrojs/cloudflare. Astro logs a warning during the build when the flag is ignored.For more information on enabling and using this feature in your project, see the experimental parallel prerendering docs.
Patch Changes
#18313
71e2b24Thanks @matthewp! - Fixes deployment integrations being unable to use Vite manifests when preparing build output#18270
0c3bf11Thanks @ArmandPhilippot! - Fixes the JSDoc for CSP utilities to point to the render context reference in docs.#18368
1f04637Thanks @43081j! - Replaces internal use offind-procwithtinyps.#18355
59b9cc0Thanks @matthewp! - Fixes prerender errors being silently swallowed when using a customsrc/fetch.tswith an adapter that prerenders in its own runtime, such as@astrojs/cloudflare. Previously, a page that threw during prerendering was written as an empty HTML file and the build succeeded. The build now fails with the underlying error.#18177
7d814e5Thanks @Princesseuh! - Fixes original images being kept despite onlywidthorheightbeing read.#18353
af54bfaThanks @astro-factory! - Fixesglob()loader swallowing rendering errors during content sync, which allowedastro buildto exit successfully (code 0) even when a remark/rehype plugin threw an error#18271
23e8e28Thanks @ArmandPhilippot! - Fixes thesynccommand description inastro help, which only mentioned content collections.Updated dependencies [
b7a1bd9,2715958]:apostrophecms/apostrophe (sanitize-html)
v2.18.1Compare Source
Changes
Remove the
deepmergedependency, which was used only to combine tag-specific and*(all tags) entries inallowedClassesandallowedStyles. That is now done by a few lines of code within sanitize-html.This is not a fix for a vulnerability in sanitize-html. Security scanners such as Snyk now report CVE-2026-93753 in
deepmerge, which can affect applications that merge untrusted objects, such as parsed JSON request bodies. sanitize-html only ever merged the developer's own configuration, never anything taken from the HTML being sanitized, so it was not exploitable through sanitize-html. Since we needed only a small part of whatdeepmergedoes, we removed the dependency so that these reports no longer appear for sanitize-html users.Security
Since 2.18.0, the fallback markup of a discarded
<iframe>was re-sanitized by a recursive call with no limit, one level per nested unclosed<iframe>. A few kilobytes of crafted input could throwRangeError: Maximum call stack size exceededwith the default options, and thenestingLimitoption was not enforced across the fallback because each nested call started counting from zero. The fallback of a discarded<iframe>is still sanitized and kept, but only up to eight nested<iframe>elements (deeper fallback is escaped as text, as before 2.18.0), and the current nesting depth now carries into the nested call sonestingLimitapplies to the whole output. Only 2.18.0 was affected, and the exception is thrown synchronously, so applications that catch errors fromsanitizeHtmlonly lost the affected request (CWE-674, GHSA-c9rx-x947-fp3h).Thanks to hkmj19, JohnBeckley, and amikhailovstiltsoft for reporting the vulnerability.
vercel/satori (satori)
v0.60.0Compare Source
Bug Fixes
Features
v0.59.2Compare Source
Bug Fixes
v0.59.1Compare Source
Bug Fixes
v0.59.0Compare Source
Features
v0.58.0Compare Source
Bug Fixes
Features
v0.57.2Compare Source
Bug Fixes
v0.57.1Compare Source
Bug Fixes
Performance Improvements
v0.57.0Compare Source
Bug Fixes
Features
v0.56.2Compare Source
Bug Fixes
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.
This PR has been generated by Mend Renovate CLI.