AstroEco is Contributing…
Display your GitHub pull requests using astro-loader-github-prs
Changes
Automatically injects Cache-Control: public, max-age=31536000, immutable into Cloudflare's _headers file for hashed Astro assets (/_astro/*), skipping when build.assetsPrefix is set or when the user already has a matching Cache-Control rule.
Testing
Unit tests.
Docs
/cc @withastro/maintainers-docs for feedback!
Changes
astro dev with @astrojs/cloudflare currently responds with HTTP 500 on every page request:
[ERROR] [vite] Internal server error: module is not defined
at runInRunnerObject (workers/runner-worker/index.js:106:3)
at _NonRunnablePipeline.getComponentByRoute (.vite/deps_ssr/astro_app_entrypoint_dev.js:196:20)
at matchRoute (.vite/deps_ssr/astro_app_entrypoint_dev.js:266:14)
at DevApp.devMatch (.vite/deps_ssr/astro_app_entrypoint_dev.js:375:26)
at Object.handle [as fetch] (.vite/deps_ssr/@astrojs_cloudflare_entrypoints_server.js:165:20)
at maybeCaptureError (workers/runner-worker/index.js:50:10)
The cause is the CJS debug package. Its entrypoint (node_modules/debug/src/index.js) reads module.exports at the top level, and module is not a global in the workerd runner that @cloudflare/vite-plugin uses for astro dev, SSR and prerender environments, so evaluation throws ReferenceError: module is not defined.
#15565 already addressed this for astro core by replacing its own debug usage with obug (an ESM fork) and documented adding a Vite alias for the rehype/remark rabbit hole. In practice though, debug is pulled by a much broader set of transitive dependencies — e.g. micromark (via @astrojs/markdown-remark → remark-parse → mdast-util-from-markdown), stylus (via Vite's peer dep), and many others — so any Astro 6 project that uses markdown content or stylus transitively still crashes on every request.
This PR extends the fix to user dependency graphs by aliasing debug to an adapter-owned ESM shim in the Vite config the adapter installs. The shim forwards to obug and also re-exposes a default export, because consumers do import debug from "debug" or require("debug") and obug only ships named exports.
What the shim looks like
// packages/integrations/cloudflare/src/shims/debug.ts
import { createDebug, disable, enable, enabled, namespaces } from 'obug';
export default createDebug;
export { createDebug, disable, enable, enabled, namespaces };Where the alias is applied
Top-level vite.resolve.alias inside the adapter's astro:config:setup hook, so it propagates to every Vite environment created by the adapter (astro, ssr, prerender):
const debugShim = fileURLToPath(new URL('./shims/debug.js', import.meta.url));
updateConfig({
// ...
vite: {
resolve: {
alias: { debug: debugShim },
},
plugins: [ /* ... */ ],
},
});obug is added as a direct dependency of @astrojs/cloudflare so the shim resolves inside the adapter's own package scope regardless of hoisting.
Reproduction
Minimal reproduction — any Astro 6 project using @astrojs/cloudflare@13 with Markdown content or stylus in its dep tree will hit this. Starting from npm create astro@latest with the Cloudflare adapter and one markdown page under src/content/ is enough.
Testing
- Manually verified against a real production blog (Astro 5 → 6 migration in progress, adapter
@astrojs/cloudflare@13.3.0, Node 22.22.2). Before the patch:/,/blog/,/posts/:slug/,/about/,/archive/,/projects/all return HTTP 500 with themodule is not definedtrace above. With the built adapter dropped intonode_modulesand no other workaround: all the same routes return HTTP 200 with full content. - Verified
pnpm --filter @astrojs/cloudflare build:ciproduces the expecteddist/shims/debug.jsalongside the patcheddist/index.js. - A dedicated unit test is tricky here because the failure only manifests when the workerd runner attempts to evaluate a module whose dep graph reaches
debug; happy to add an integration test underpackages/integrations/cloudflare/test/fixtures/modelled afterastro-dev-platform/code-test.astroif maintainers want one — just point me at the preferred shape.
Related
- #15284 — original "Astro v6 with cloudflare adapter does not work with
<Code>components" issue (closed) - #15565 — original logging overhaul that replaced astro core's
debugwithobug - #15906 — same workerd-runner class of failure, Svelte path
- expressive-code/expressive-code#439 — same error reported against expressive-code; upstream cause is the same.
Docs
N/A — internal adapter behavior change, transparent to users.
Changes
- Invalidates the
astro:data-layer-contentvirtual module in the SSR module runner'sevaluatedModulescache when the data store changes, not just in the server-side module graph. The existinginvalidateModulecall only clears the server'stransformResult, but a subsequenttransformRequest(triggered during module resolution) re-populates it before the runner'sfetchModulecheck, causing a false cache hit that returns stale data.
Closes #16561
Testing
- No new tests added. Manually verified with a content collection setup: deleting entries correctly updates
getCollection()results on the next page load in dev.
Docs
- No docs update needed; this is a bug fix with no API change.
Changes
- Fixes #16564 —
data-astro-prefetch="tap"silently failing when the user clicks a nested child element (e.g.<span>,<img>,<svg>, Astro<Image />) inside an anchor e.targetontouchstart/mousedownis the deepest element under the pointer, not necessarily the<a>— useclosest('a')to walk up to the anchor before checking the strategy- Particularly impactful on slow connections / data-saver mode, where all strategies collapse to
tap— meaning zero prefetching was happening for any link with nested content for the users who would benefit most
Testing
- Added e2e fixture link
<a data-astro-prefetch="tap"><span>tap nested</span></a>and a corresponding page - Added e2e test in
prefetch.test.tsthat clicks the inner<span>and asserts the prefetch request fires
Docs
No docs change needed — this is a bug fix restoring already-documented behavior, not a new feature or API change.
Closes #16563
Summary
Calling session.delete(key) as the first mutation in a request (no prior get, set, has, keys, etc.) did not write back to session storage. The session stayed dirty in memory, but [PERSIST_SYMBOL]() skipped the save path because #data was still undefined, so the backing store kept the old value and the next request could still read the “deleted” key.
Root cause
set()initializes the in-memory map withthis.#data ??= new Map();delete()only didthis.#data?.delete(key), so#datacould remainundefined.- Persistence gated saves on
if (this.#dirty && this.#data), so delete-only flows never calledsetItemand#toDeletewas never applied to storage.
Fix
- Initialize the map in
delete()the same way as inset():this.#data ??= new Map()before removing the key, so the persist path runs and#ensureData()can merge, apply deletions, and serialize to the driver.
Testing
- Added a unit test that pre-seeds backing storage, calls only
delete()then persist, and asserts a newAstroSessionwith the same storage/session id no longer returns the deleted key. - Adjusted an existing persistence test so the follow-up session’s storage
getreturns parsed JSON (matching real unstorage behavior) aftersetItemwrites a devalue JSON string.
Docs
No documentation change required; behavior now matches what the session API already promises.
Contributor checklist (see CONTRIBUTING.md)
-
pnpm exec changesetfor theastropackage (user-facing bugfix) - Tests:
pnpm -C packages/astro exec astro-scripts test "test/units/sessions/astro-session.test.ts"
Fixes #16553
Changes
- Fixes non-prerendered routes (e.g. SSR endpoints using
cloudflare:workers) failing when a dynamic prerendered route like[page].astroexists in the same project withprerenderEnvironment: 'node'. - The dev prerender middleware was using
matchAllRoutes(), which returns every route matching a pathname. A request to/ssrwould match bothssr.astro(non-prerendered) and[page].astro(prerendered), and since one match was prerendered, the request was incorrectly routed to the Node handler. Replaced withmatchRoute(), which returns only the highest-priority match.
Testing
- Added a dynamic prerendered route (
[page].astrowithgetStaticPaths) to the existingprerender-node-envfixture. The existing "renders SSR page through workerd" test now exercises this scenario.
Docs
- No docs needed.
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| withastro/automation | action | digest | 497c926 → e27ec6d |
Configuration
📅 Schedule: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
- If you want to rebase/retry this PR, check this box
This PR was generated by Mend Renovate. View the repository job log.
Changes
- Updates
./test-utils.jsimports to./test-utils.tsin three.test.jsfiles that were missed when #16492 renamedtest-utils.js→test-utils.ts.
Testing
- No new tests. This fixes the existing
test:integration:jssuite which fails immediately withERR_MODULE_NOT_FOUND.
Docs
- No docs needed — test-only change.
Changes
Simplify db's tsconfig by removing tsconfig.virtual.json.
Its only purpose is to prevent incorrect auto-imports from editor hints and doesn’t affect the runtime output, so it should be relatively safe to remove it.
This file makes it tricky for the TypeScript project references refactor.
Testing
Green CI
Docs
N/A
Changes
- Fixes a bug in
@astrojs/cloudflarewhere custom KV namespace bindings (e.g.MY_KV,CACHE) were silently removed when Astro's session functionality was enabled. - The root cause was in
packages/integrations/cloudflare/src/wrangler.ts: when injecting theSESSIONKV binding, the code returned a fresh single-item array instead of merging with the user's existingkv_namespaces. - Extracted a
withSessionKVBindinghelper that copies existing namespaces and appends the SESSION binding, preserving all user-defined bindings. - Fix applies to both the top-level config and the
previewsconfig (same code path). - Updated the existing test that was asserting the broken behavior, and added a new test covering the
previewscase.
Closes #16554
Testing
- Updated
packages/integrations/cloudflare/test/wrangler.test.ts: fixed the assertion in "adds SESSION binding when other KV bindings exist but not the session one" to verifyOTHER_KVis preserved alongsideSESSION. - Added a new test "preserves existing previews KV bindings when adding SESSION binding" covering the same scenario in the
previewsconfig. - No integration test needed: the bug and fix are fully exercised by the unit test suite for
cloudflareConfigCustomizer.
Docs
No docs change needed. This is a bug fix restoring behavior that users already rely on — their existing kv_namespaces entries in wrangler.toml now survive when sessions are enabled.
Changes
- Fixes a regex bug where
returnwas incorrectly rewritten inside string literals, template literals, and comments during esbuild's dep-scan / frontmatter error-check phase - Replaces the two-pass
\breturn\bregex with a single-pass state-machine regex that skips over all string/comment tokens before rewriting barereturnstatements - Fixes the primary report case:
gen.return(value)→ was producinggen.throw (value)(syntax error); now preserved correctly - Extracts a shared
replaceTopLevelReturns()helper intoutils.tsto deduplicate logic between the cloudflare esbuild plugin andcompile.ts
Affected files:
packages/integrations/cloudflare/src/esbuild-plugin-astro-frontmatter.tspackages/astro/src/vite-plugin-astro/utils.tspackages/astro/src/vite-plugin-astro/compile.ts
Closes #16551
Testing
The fix is a pure regex change with no new dependencies. Verified manually against the cases from the issue:
| Input | Before | After |
|---|---|---|
gen.return(val) |
gen.throw (val) ← syntax error |
unchanged ✓ |
"return value" |
"throw value" |
unchanged ✓ |
// return foo |
// throw foo |
unchanged ✓ |
`return ${x}` |
`throw ${x}` |
unchanged ✓ |
return foo |
return foo |
throw foo ✓ |
return; |
return; |
throw 0; ✓ |
No new tests added — the two affected code paths are internal-only (esbuild dep scan and compile-error enhancement), exercised by the existing integration test suite.
Docs
No user-facing behavior change — this only affects internal dep scanning and error reporting during compilation. No docs update needed.
This PR contains the following updates:
Release Notes
netlify/primitives (@netlify/blobs)
v10.7.4
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev-utils bumped from 4.4.2 to 4.4.3
- @netlify/otel bumped from ^5.1.4 to ^5.1.5
- dependencies
v10.7.3
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev-utils bumped from 4.4.1 to 4.4.2
- @netlify/otel bumped from ^5.1.3 to ^5.1.4
- dependencies
v10.7.2
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev-utils bumped from 4.4.0 to 4.4.1
- @netlify/otel bumped from ^5.1.2 to ^5.1.3
- dependencies
v10.7.1
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev-utils bumped from 4.3.3 to 4.4.0
- @netlify/otel bumped from ^5.1.1 to ^5.1.2
- dependencies
netlify/primitives (@netlify/functions)
v5.2.0
Features
v5.1.5
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/types bumped from 2.5.0 to 2.6.0
- dependencies
v5.1.4
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/types bumped from 2.4.0 to 2.5.0
- dependencies
v5.1.3
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/types bumped from 2.3.0 to 2.4.0
- dependencies
netlify/primitives (@netlify/vite-plugin)
v2.12.1
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.18.0 to 4.18.1
- dependencies
v2.12.0
Features
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.17.3 to 4.18.0
- dependencies
v2.11.7
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.17.2 to 4.17.3
- dependencies
v2.11.6
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.17.1 to 4.17.2
- dependencies
v2.11.5
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.17.0 to 4.17.1
- dependencies
v2.11.4
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.16.5 to 4.17.0
- dependencies
v2.11.3
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.16.4 to 4.16.5
- dependencies
v2.11.2
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.16.3 to 4.16.4
- @netlify/dev-utils bumped from ^4.4.2 to ^4.4.3
- dependencies
v2.11.1
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.16.2 to 4.16.3
- @netlify/dev-utils bumped from ^4.4.1 to ^4.4.2
- dependencies
v2.11.0
Features
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.16.1 to 4.16.2
- dependencies
v2.10.11
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.16.0 to 4.16.1
- @netlify/dev-utils bumped from ^4.4.0 to ^4.4.1
- dependencies
v2.10.10
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.15.0 to 4.16.0
- dependencies
v2.10.9
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.14.1 to 4.15.0
- @netlify/dev-utils bumped from ^4.3.3 to ^4.4.0
- dependencies
v2.10.8
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.14.0 to 4.14.1
- dependencies
v2.10.7
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.13.0 to 4.14.0
- dependencies
v2.10.6
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.12.1 to 4.13.0
- dependencies
v2.10.5
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.12.0 to 4.12.1
- dependencies
v2.10.4
Bug Fixes
Dependencies
- The following workspace dependencies were updated
- dependencies
- @netlify/dev bumped from 4.11.3 to 4.12.0
- dependencies
sveltejs/devalue (devalue)
v5.7.1
Patch Changes
8becc7c: fix: handle regexes consistently in uneval's value and reference formats
v5.7.0
Minor Changes
df2e284: feat: use native alternatives to encode/decode base64498656e: feat: addDataViewsupporta210130: feat: whitelistFloat16Arraydf2e284: feat: simplify TypedArray slices
Patch Changes
Configuration
📅 Schedule: (UTC)
- Branch creation
- Between 12:00 AM and 03:59 AM, only on Monday (
* 0-3 * * 1)
- Between 12:00 AM and 03:59 AM, only on Monday (
- Automerge
- At any time (no schedule defined)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.
- If you want to rebase/retry this PR, check this box
This PR was generated by Mend Renovate. View the repository job log.
Changes
fixes #16524.
with vite.css.transformer: 'lightningcss', scoped styles using a nested & selector inside :where(...) silently produce css where the scope attribute lands on the matched child instead of the intended parent. tailwind v4's space-x-*, space-y-*, and divide-* all expand to this shape and tailwind v4 ships with lightningcss in the loop, so any astro 6 + tailwind v4 project using these utilities in scoped <style> blocks targeting children from another component gets broken spacing in production while the css rule still looks present in the bundle.
what's happening: lightningcss runs inside vite's preprocessCSS() and lowers nesting before @astrojs/compiler injects scope attributes. by the time the compiler sees the css, .parent is buried inside :where(...) and isn't a top-level compound anymore, so the injector prepends [data-astro-cid-X] as a new leading compound — which constrains the wrong element.
fix in packages/astro/src/core/compile/style.ts: when the user has css.transformer: 'lightningcss', call preprocessCSS() with a shallow-cloned vite config whose css.lightningcss.exclude ORs in Features.Nesting, so lightningcss skips its nesting-lowering pass for this preprocess call. vite's final pipeline still lowers nesting for the bundle so output stays compatible with the user's targets. clone is non-mutating per call so it's safe under parallel .astro compiles. lightningcss is resolved from the user's project root via createRequire — same instance vite uses, no new dep added to packages/astro. falls back to the original config if lightningcss can't be resolved.
i think a better fix would live in @astrojs/compiler itself, teach the scope injector to recognize :where(<simple-compound>, ...) as a leading-compound wrapper and attach the cid to the inner compound instead of prepending a new one. similar in spirit to withastro/compiler#1153 but extended to cover the :where(...) case, and it'd cover any future css transform that produces a similarly shaped selector not just lightningcss.
Testing
added a regression fixture under packages/astro/test/:
lightningcss-scoped-nesting.test.ts— compiles the reporter's exact shape withvite.css.transformer: 'lightningcss'and asserts the scope id binds to.parent, not as a leading compound on the matched child.- fixture under
packages/astro/test/fixtures/lightningcss-scoped-nesting/— single page using the reporter's:where(& > :not(:last-child))selector inside a scoped<style>block.
reporter's reproduction repo: https://github.com/rklos/astro-css-bug-repro
Docs
no docs changes. silent regression in css output; behavior after the fix matches what the docs already describe for scoped styles + nested selectors.
Changes
upgrade/package.json has "build": "astro-scripts build \"src/index.ts\" --bundle && tsc". The output dist/index.js should be emitted by astro-scripts, while tsc should only emit .d.ts files.
In #16493, tsc emits both .js and .d.ts files, which overrides the bundled dist/index.js file that was just emitted by astro-scripts.
This PR updates upgrade/tsconfig.json to ensure that tsc won't emit any .js files.
Testing
Before this PR:
$ pnpm -w build
$ tree ./packages/upgrade/dist/
./packages/upgrade/dist/
├── actions
│ ├── context.d.ts
│ ├── context.js
│ ├── help.d.ts
│ ├── help.js
│ ├── install.d.ts
│ ├── install.js
│ ├── verify.d.ts
│ └── verify.js
├── index.d.ts
├── index.js
├── messages.d.ts
├── messages.js
├── shell.d.ts
└── shell.js
2 directories, 14 filesAfter this PR:
$ pnpm -w build
$ tree ./packages/upgrade/dist/
./packages/upgrade/dist/
├── actions
│ ├── context.d.ts
│ ├── help.d.ts
│ ├── install.d.ts
│ └── verify.d.ts
├── index.d.ts
├── index.js
├── messages.d.ts
└── shell.d.ts
2 directories, 8 filesAfter this PR, only one bundled dist/index.js file is emitted in dist/.
Docs
The previous and afterward outputs can both work, so there is no behavior change. No docs are needed.
Last fetched: | Scheduled refresh: Every Saturday
See Customizing GitHub Activity Pages to configure your own
Inspired by prs.atinux.com