From ed2b536aee7543dff912a91db7d97d331f2c62c1 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Wed, 25 Feb 2026 17:57:20 +0000 Subject: [PATCH 1/2] chore: update config reference (#15658) Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- packages/astro/src/types/public/config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index b79ea6e0adf9..fc14fd249953 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -661,7 +661,8 @@ export interface AstroUserConfig< * This feature comes with some limitations: * - External scripts and external styles are not supported out of the box, but you can [provide your own hashes](https://v6.docs.astro.build/en/reference/configuration-reference/#hashes). * - [Astro's view transitions](https://v6.docs.astro.build/en/guides/view-transitions/) using the `` are not supported, but you can [consider migrating to the browser native View Transition API](https://events-3bg.pages.dev/jotter/astro-view-transitions/) instead if you are not using Astro's enhancements to the native View Transitions and Navigation APIs. - * - Shiki isn't currently supported. By design, Shiki functions using inline styles. + * - Shiki isn't currently supported. By design, Shiki functions use inline styles that cannot work with Astro CSP implementation. Consider [using ``](https://v6.docs.astro.build/en/guides/syntax-highlighting/#prism-) when your project requires both CSP and syntax highlighting. + * - `unsafe-inline` directives are incompatible with Astro's CSP implementation. By default, Astro will emit hashes for all its bundled scripts (e.g. client islands) and all modern browsers will automatically reject `unsafe-inline` when it occurs in a directive with a hash or nonce. * * :::note * Due to the nature of the Vite dev server, this feature isn't supported while working in `dev` mode. Instead, you can test this in your Astro project using `build` and `preview`. From 7150a2e2aa022a9a957684ad8091f85aedb243f1 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Wed, 25 Feb 2026 19:19:27 +0000 Subject: [PATCH 2/2] fix(build): batch pages to avoid v8 limitations (#15661) * fix(build): batch Promise.all calls in concurrent page generation to avoid V8 element limit * add some comments * changeset --------- Co-authored-by: astrobot-houston --- .../fix-large-static-build-promise-all.md | 5 +++ packages/astro/src/core/build/generate.ts | 35 +++++++++++-------- 2 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 .changeset/fix-large-static-build-promise-all.md diff --git a/.changeset/fix-large-static-build-promise-all.md b/.changeset/fix-large-static-build-promise-all.md new file mode 100644 index 000000000000..f00975e925cc --- /dev/null +++ b/.changeset/fix-large-static-build-promise-all.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a build error when generating projects with 100k+ static routes. diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index b49e726be423..8d160bcfe356 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -153,22 +153,29 @@ export async function generatePages( // Generate each path if (config.build.concurrency > 1) { const limit = PLimit(config.build.concurrency); - const promises: Promise[] = []; - for (const { pathname, route } of filteredPaths) { - promises.push( - limit(() => - generatePathWithPrerenderer( - prerenderer, - pathname, - route, - options, - routeToHeaders, - logger, + // Process in batches to avoid V8's Promise.all element limit, which is around ~123k items + // + // NOTE: ideally we could consider an iterator to avoid the batching limitation + const BATCH_SIZE = 100_000; + for (let i = 0; i < filteredPaths.length; i += BATCH_SIZE) { + const batch = filteredPaths.slice(i, i + BATCH_SIZE); + const promises: Promise[] = []; + for (const { pathname, route } of batch) { + promises.push( + limit(() => + generatePathWithPrerenderer( + prerenderer, + pathname, + route, + options, + routeToHeaders, + logger, + ), ), - ), - ); + ); + } + await Promise.all(promises); } - await Promise.all(promises); } else { for (const { pathname, route } of filteredPaths) { await generatePathWithPrerenderer(