From c610cda44b273c15a6e7eaa4a84fa194002643e1 Mon Sep 17 00:00:00 2001 From: "Houston (Bot)" <108291165+astrobot-houston@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:30:22 -0700 Subject: [PATCH 1/2] Fix dynamic route parameters in domain-based i18n routing (#16855) * fix(i18n): pass domain pathname to FetchState for dynamic route param extraction (#16854) * chore: better fix and changeset * chore: improve fix --------- Co-authored-by: ematipico --- .changeset/fix-i18n-domain-dynamic-params.md | 5 + .changeset/rare-bikes-open.md | 5 + packages/astro/src/core/app/base.ts | 87 ++------ packages/astro/src/core/fetch/fetch-state.ts | 41 +++- packages/astro/src/core/i18n/domain.ts | 109 ++++++++++ packages/astro/test/units/i18n/domain.test.ts | 198 ++++++++++++++++++ .../astro/test/units/i18n/i18n-app.test.ts | 69 ++++++ 7 files changed, 437 insertions(+), 77 deletions(-) create mode 100644 .changeset/fix-i18n-domain-dynamic-params.md create mode 100644 .changeset/rare-bikes-open.md create mode 100644 packages/astro/src/core/i18n/domain.ts create mode 100644 packages/astro/test/units/i18n/domain.test.ts diff --git a/.changeset/fix-i18n-domain-dynamic-params.md b/.changeset/fix-i18n-domain-dynamic-params.md new file mode 100644 index 000000000000..7635409eac67 --- /dev/null +++ b/.changeset/fix-i18n-domain-dynamic-params.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes dynamic routes returning 500 "TypeError: Missing parameter" when using domain-based i18n routing in SSR. diff --git a/.changeset/rare-bikes-open.md b/.changeset/rare-bikes-open.md new file mode 100644 index 000000000000..2cfc1de75d77 --- /dev/null +++ b/.changeset/rare-bikes-open.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes `Astro.currentLocale` returning the default locale instead of the domain's locale on dynamic routes served from a mapped domain. diff --git a/packages/astro/src/core/app/base.ts b/packages/astro/src/core/app/base.ts index aa5670c7a8d7..941d0d602fbf 100644 --- a/packages/astro/src/core/app/base.ts +++ b/packages/astro/src/core/app/base.ts @@ -1,12 +1,10 @@ import { - appendForwardSlash, collapseDuplicateLeadingSlashes, - joinPaths, prependForwardSlash, removeTrailingForwardSlash, } from '@astrojs/internal-helpers/path'; import { matchPattern } from '@astrojs/internal-helpers/remote'; -import { normalizeTheLocale } from '../../i18n/index.js'; +import { computePathnameFromDomain } from '../i18n/domain.js'; import type { RoutesList } from '../../types/astro.js'; import type { RemotePattern, RouteData } from '../../types/public/index.js'; import { type Pipeline, PipelineFeatures } from '../base-pipeline.js'; @@ -339,76 +337,14 @@ export abstract class BaseApp

{ } private computePathnameFromDomain(request: Request): string | undefined { - let pathname: string | undefined = undefined; - const url = new URL(request.url); - - if ( - this.manifest.i18n && - (this.manifest.i18n.strategy === 'domains-prefix-always' || - this.manifest.i18n.strategy === 'domains-prefix-other-locales' || - this.manifest.i18n.strategy === 'domains-prefix-always-no-redirect') - ) { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host - let host = request.headers.get('X-Forwarded-Host'); - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto - let protocol = request.headers.get('X-Forwarded-Proto'); - if (protocol) { - // this header doesn't have a colon at the end, so we add to be in line with URL#protocol, which does have it - protocol = protocol + ':'; - } else { - // we fall back to the protocol of the request - protocol = url.protocol; - } - if (!host) { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host - host = request.headers.get('Host'); - } - // If we don't have a host and a protocol, it's impossible to proceed - if (host && protocol) { - // The header might have a port in their name, so we remove it - host = host.split(':')[0]; - try { - let locale; - const hostAsUrl = new URL(`${protocol}//${host}`); - for (const [domainKey, localeValue] of Object.entries( - this.manifest.i18n.domainLookupTable, - )) { - // This operation should be safe because we force the protocol via zod inside the configuration - // If not, then it means that the manifest was tampered - const domainKeyAsUrl = new URL(domainKey); - - if ( - hostAsUrl.host === domainKeyAsUrl.host && - hostAsUrl.protocol === domainKeyAsUrl.protocol - ) { - locale = localeValue; - break; - } - } - - if (locale) { - pathname = prependForwardSlash( - joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname)), - ); - if (this.manifest.trailingSlash === 'always') { - pathname = appendForwardSlash(pathname); - } else if (this.manifest.trailingSlash === 'never') { - pathname = removeTrailingForwardSlash(pathname); - } else if (url.pathname.endsWith('/')) { - // trailingSlash === 'ignore': preserve the original trailing slash - pathname = appendForwardSlash(pathname); - } - } - } catch (e: any) { - this.logger.error( - 'router', - `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`, - ); - this.logger.error('router', `Error: ${e}`); - } - } - } - return pathname; + return computePathnameFromDomain( + request, + new URL(request.url), + this.manifest.i18n, + this.manifest.base, + this.manifest.trailingSlash, + this.logger, + ); } public async render( @@ -454,8 +390,9 @@ export abstract class BaseApp

{ }); } } - // For domain-based i18n, compute the locale-prefixed pathname from - // the Host header and pass it so FetchState can match correctly. + // For domain-based i18n, match against the locale-prefixed pathname + // derived from the Host header. FetchState recomputes this pathname + // itself for param/locale resolution, so it isn't threaded through here. if (!routeData) { const domainPathname = this.computePathnameFromDomain(request); if (domainPathname) { diff --git a/packages/astro/src/core/fetch/fetch-state.ts b/packages/astro/src/core/fetch/fetch-state.ts index e072f65a8f57..729a169cf82b 100644 --- a/packages/astro/src/core/fetch/fetch-state.ts +++ b/packages/astro/src/core/fetch/fetch-state.ts @@ -35,6 +35,7 @@ import { Rewrites } from '../rewrites/handler.js'; import { isRoute404or500, isRouteServerIsland } from '../routing/match.js'; import { normalizeUrl } from '../util/normalized-url.js'; import { getOriginPathname, setOriginPathname } from '../routing/rewrite.js'; +import { computePathnameFromDomain } from '../i18n/domain.js'; import { getCustom404Route, routeHasHtmlExtension } from '../routing/helpers.js'; import type { ResolvedRenderOptions } from '../app/base.js'; import { getRenderOptions } from '../app/render-options.js'; @@ -236,6 +237,13 @@ export class FetchState implements AstroFetchState { #rewrites: Rewrites | undefined; /** Memoized Astro page partial. */ #astroPagePartial?: Omit; + /** + * Locale-prefixed pathname derived from the Host header for domain-based + * i18n routing (e.g. `/en/boats/1/foo`), or `undefined` when the request + * isn't served from a locale-mapped domain. When set, `this.pathname` is + * derived from it so locale/param resolution match the route pattern. + */ + #domainPathname: string | undefined; /** Memoized current locale. */ #currentLocale: APIContext['currentLocale']; /** Memoized preferred locale. */ @@ -263,7 +271,29 @@ export class FetchState implements AstroFetchState { this.slots = undefined; // Parse the URL once and derive both pathname and url from it. const url = new URL(request.url); - this.pathname = this.#computePathname(url); + // For domain-based i18n routing, the locale prefix is derived from the + // request's Host header rather than its URL. When a locale is detected, + // the resulting pathname includes the prefix (e.g. /en/boats/1/foo) that + // the matched route pattern expects — use it instead of the raw URL + // pathname so param and locale resolution produce correct values. + const domainPathname = computePathnameFromDomain( + request, + url, + pipeline.manifest.i18n, + pipeline.manifest.base, + pipeline.manifest.trailingSlash, + pipeline.logger, + ); + if (domainPathname) { + this.#domainPathname = domainPathname; + try { + this.pathname = decodeURI(domainPathname); + } catch { + this.pathname = domainPathname; + } + } else { + this.pathname = this.#computePathname(url); + } this.timeStart = performance.now(); this.clientAddress = options?.clientAddress; this.locals = (options?.locals ?? {}) as App.Locals; @@ -627,7 +657,14 @@ export class FetchState implements AstroFetchState { } } else { let pathname = routeData.pathname; - if (url && !routeData.pattern.test(url.pathname)) { + // For domain-based i18n the locale prefix comes from the Host header, + // not the URL. `this.pathname` carries the locale-prefixed path the + // route matched against (e.g. `/en/boats/1/foo`), whereas `url.pathname` + // does not. This matters for dynamic routes, which have no static + // `routeData.pathname` to fall back to. See #16854. + if (this.#domainPathname) { + pathname = this.pathname; + } else if (url && !routeData.pattern.test(url.pathname)) { for (const fallbackRoute of routeData.fallbackRoutes) { if (fallbackRoute.pattern.test(url.pathname)) { pathname = fallbackRoute.pathname; diff --git a/packages/astro/src/core/i18n/domain.ts b/packages/astro/src/core/i18n/domain.ts new file mode 100644 index 000000000000..028222fcf532 --- /dev/null +++ b/packages/astro/src/core/i18n/domain.ts @@ -0,0 +1,109 @@ +import { + appendForwardSlash, + collapseDuplicateLeadingSlashes, + joinPaths, + prependForwardSlash, + removeTrailingForwardSlash, +} from '@astrojs/internal-helpers/path'; +import { normalizeTheLocale } from '../../i18n/index.js'; +import type { SSRManifest } from '../app/types.js'; +import type { AstroLogger } from '../logger/core.js'; + +/** + * For domain-based i18n routing strategies, derives the locale-prefixed + * pathname from the request's `Host` header rather than its URL. For example, + * a request for `/foo` served from `https://example.fr` resolves to `/fr/foo`. + * + * Returns `undefined` when the strategy isn't domain-based or the host isn't + * mapped to a locale — in which case normal pathname routing applies. + * + */ +export function computePathnameFromDomain( + request: Request, + url: URL, + i18n: SSRManifest['i18n'], + base: SSRManifest['base'], + trailingSlash: SSRManifest['trailingSlash'], + logger: AstroLogger, +): string | undefined { + let pathname: string | undefined = undefined; + + if ( + i18n && + (i18n.strategy === 'domains-prefix-always' || + i18n.strategy === 'domains-prefix-other-locales' || + i18n.strategy === 'domains-prefix-always-no-redirect') + ) { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host + let host = request.headers.get('X-Forwarded-Host'); + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto + let protocol = request.headers.get('X-Forwarded-Proto'); + if (protocol) { + // this header doesn't have a colon at the end, so we add to be in line with URL#protocol, which does have it + protocol = protocol + ':'; + } else { + // we fall back to the protocol of the request + protocol = url.protocol; + } + if (!host) { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host + host = request.headers.get('Host'); + } + // If we don't have a host and a protocol, it's impossible to proceed + if (host && protocol) { + // The header might have a port in their name, so we remove it + host = host.split(':')[0]; + try { + let locale; + const hostAsUrl = new URL(`${protocol}//${host}`); + for (const [domainKey, localeValue] of Object.entries(i18n.domainLookupTable)) { + // This operation should be safe because we force the protocol via zod inside the configuration + // If not, then it means that the manifest was tampered + const domainKeyAsUrl = new URL(domainKey); + + if ( + hostAsUrl.host === domainKeyAsUrl.host && + hostAsUrl.protocol === domainKeyAsUrl.protocol + ) { + locale = localeValue; + break; + } + } + + if (locale) { + pathname = prependForwardSlash( + joinPaths(normalizeTheLocale(locale), removeBase(url.pathname, base)), + ); + if (trailingSlash === 'always') { + pathname = appendForwardSlash(pathname); + } else if (trailingSlash === 'never') { + pathname = removeTrailingForwardSlash(pathname); + } else if (url.pathname.endsWith('/')) { + // trailingSlash === 'ignore': preserve the original trailing slash + pathname = appendForwardSlash(pathname); + } + } + } catch (e: any) { + logger.error( + 'router', + `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`, + ); + logger.error('router', `Error: ${e}`); + } + } + } + return pathname; +} + +/** + * Mirror of `BaseApp.removeBase`, including the + * `collapseDuplicateLeadingSlashes` fix that prevents middleware + * authorization bypass when the URL starts with `//`. + */ +function removeBase(pathname: string, base: string): string { + pathname = collapseDuplicateLeadingSlashes(pathname); + if (pathname.startsWith(base)) { + return pathname.slice(removeTrailingForwardSlash(base).length + 1); + } + return pathname; +} diff --git a/packages/astro/test/units/i18n/domain.test.ts b/packages/astro/test/units/i18n/domain.test.ts new file mode 100644 index 000000000000..dc54e52005a8 --- /dev/null +++ b/packages/astro/test/units/i18n/domain.test.ts @@ -0,0 +1,198 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { computePathnameFromDomain } from '../../../dist/core/i18n/domain.js'; +import type { SSRManifestI18n } from '../../../dist/core/app/types.js'; +import type { RoutingStrategies } from '../../../dist/core/app/common.js'; +import type { Locales } from '../../../dist/types/public/config.js'; +import { defaultLogger, SpyLogger } from '../test-utils.ts'; + +interface I18nOverrides { + strategy?: RoutingStrategies; + locales?: Locales; + defaultLocale?: string; + domainLookupTable?: Record; +} + +function makeI18n(overrides: I18nOverrides = {}): SSRManifestI18n { + return { + fallback: undefined, + fallbackType: 'rewrite', + strategy: overrides.strategy ?? 'domains-prefix-other-locales', + locales: overrides.locales ?? (['en', 'fr'] as Locales), + defaultLocale: overrides.defaultLocale ?? 'en', + domainLookupTable: overrides.domainLookupTable ?? { 'https://example.fr': 'fr' }, + domains: undefined, + }; +} + +/** Builds a request + parsed URL pair, the two positional args the fn takes. */ +function reqAndUrl(url: string, headers: Record = {}) { + const request = new Request(url, { headers }); + return [request, new URL(request.url)] as const; +} + +function run( + url: string, + headers: Record, + opts: { + i18n?: SSRManifestI18n | undefined; + base?: string; + trailingSlash?: 'always' | 'never' | 'ignore'; + logger?: typeof defaultLogger; + } = {}, +) { + // Resolve i18n via key presence so an explicit `i18n: undefined` is honored + // (a destructuring default would replace it with the configured fallback). + const i18n = 'i18n' in opts ? opts.i18n : makeI18n(); + const base = opts.base ?? '/'; + const trailingSlash = opts.trailingSlash ?? 'ignore'; + const logger = opts.logger ?? defaultLogger; + const [request, parsedUrl] = reqAndUrl(url, headers); + return computePathnameFromDomain(request, parsedUrl, i18n, base, trailingSlash, logger); +} + +describe('computePathnameFromDomain', () => { + it('returns undefined when i18n is not configured', () => { + assert.equal( + run('https://example.fr/about', { 'X-Forwarded-Host': 'example.fr' }, { i18n: undefined }), + undefined, + ); + }); + + it('returns undefined for non domain-based strategies', () => { + const i18n = makeI18n({ strategy: 'pathname-prefix-other-locales' }); + assert.equal( + run('https://example.fr/about', { 'X-Forwarded-Host': 'example.fr' }, { i18n }), + undefined, + ); + }); + + it('returns undefined when the host is not mapped to a locale', () => { + assert.equal( + run('https://example.com/about', { 'X-Forwarded-Host': 'example.com' }), + undefined, + ); + }); + + it('returns undefined when neither Host nor X-Forwarded-Host is present', () => { + // `new Request` always derives a Host from the URL, so build a request + // whose URL host is unmapped and pass no forwarding headers. + assert.equal(run('https://example.com/about', {}), undefined); + }); + + it('prepends the locale prefix derived from X-Forwarded-Host', () => { + assert.equal( + run('https://example.fr/about', { + 'X-Forwarded-Host': 'example.fr', + 'X-Forwarded-Proto': 'https', + }), + '/fr/about', + ); + }); + + it('falls back to the Host header when X-Forwarded-Host is absent', () => { + assert.equal(run('https://example.fr/about', { Host: 'example.fr' }), '/fr/about'); + }); + + it('strips a port from the forwarded host before matching', () => { + assert.equal( + run('https://example.fr/about', { + 'X-Forwarded-Host': 'example.fr:8443', + 'X-Forwarded-Proto': 'https', + }), + '/fr/about', + ); + }); + + it('returns undefined on protocol mismatch with the mapped domain', () => { + // domainLookupTable maps https://example.fr; an http request must not match. + assert.equal( + run('http://example.fr/about', { + 'X-Forwarded-Host': 'example.fr', + 'X-Forwarded-Proto': 'http', + }), + undefined, + ); + }); + + it('appends a trailing slash when trailingSlash is "always"', () => { + assert.equal( + run( + 'https://example.fr/about', + { 'X-Forwarded-Host': 'example.fr' }, + { trailingSlash: 'always' }, + ), + '/fr/about/', + ); + }); + + it('removes the trailing slash when trailingSlash is "never"', () => { + assert.equal( + run( + 'https://example.fr/about/', + { 'X-Forwarded-Host': 'example.fr' }, + { trailingSlash: 'never' }, + ), + '/fr/about', + ); + }); + + it('preserves the request trailing slash when trailingSlash is "ignore"', () => { + assert.equal( + run( + 'https://example.fr/about/', + { 'X-Forwarded-Host': 'example.fr' }, + { trailingSlash: 'ignore' }, + ), + '/fr/about/', + ); + assert.equal( + run( + 'https://example.fr/about', + { 'X-Forwarded-Host': 'example.fr' }, + { trailingSlash: 'ignore' }, + ), + '/fr/about', + ); + }); + + it('strips the configured base before prepending the locale', () => { + assert.equal( + run('https://example.fr/shop/about', { 'X-Forwarded-Host': 'example.fr' }, { base: '/shop' }), + '/fr/about', + ); + }); + + it('returns the locale-prefixed pathname without decoding (encoding preserved)', () => { + assert.equal( + run('https://example.fr/caf%C3%A9', { 'X-Forwarded-Host': 'example.fr' }), + '/fr/caf%C3%A9', + ); + }); + + it('works for the domains-prefix-always strategy', () => { + const i18n = makeI18n({ strategy: 'domains-prefix-always' }); + assert.equal( + run('https://example.fr/about', { 'X-Forwarded-Host': 'example.fr' }, { i18n }), + '/fr/about', + ); + }); + + it('works for the domains-prefix-always-no-redirect strategy', () => { + const i18n = makeI18n({ strategy: 'domains-prefix-always-no-redirect' }); + assert.equal( + run('https://example.fr/about', { 'X-Forwarded-Host': 'example.fr' }, { i18n }), + '/fr/about', + ); + }); + + it('logs an error and returns undefined when the host cannot be parsed as a URL', () => { + const logger = new SpyLogger(); + const result = run('https://example.fr/about', { 'X-Forwarded-Host': '[' }, { logger }); + assert.equal(result, undefined); + assert.ok( + logger.logs.some((entry) => entry.level === 'error' && entry.label === 'router'), + 'expected a router error to be logged', + ); + }); +}); diff --git a/packages/astro/test/units/i18n/i18n-app.test.ts b/packages/astro/test/units/i18n/i18n-app.test.ts index 31691f608a2a..fea75188f7fa 100644 --- a/packages/astro/test/units/i18n/i18n-app.test.ts +++ b/packages/astro/test/units/i18n/i18n-app.test.ts @@ -35,6 +35,11 @@ const localePage = createComponent((result, props, slots) => { return render`

${Astro.currentLocale}

${Astro.url.pathname}

`; }); +const paramsPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + return render`

${Astro.currentLocale}

${Astro.params.id}${Astro.params.slug}`; +}); + const notFoundPage = createComponent(() => { return render`

404 Not Found

`; }); @@ -412,6 +417,70 @@ describe('i18n via App - domains-prefix-other-locales', () => { }); }); +// #16854: Dynamic routes with non-spread params should work with domain-based i18n +describe('i18n via App - domains-prefix-other-locales with dynamic params (#16854)', () => { + const i18n = makeI18nConfig({ + strategy: 'domains-prefix-other-locales', + locales: ['fi', 'en'], + defaultLocale: 'fi', + }); + i18n.domainLookupTable = { 'https://en.example.com': 'en' }; + i18n.domains = { en: 'https://en.example.com' }; + + const middleware = createI18nMiddleware(i18n, '/', 'ignore', 'directory'); + + function createDomainApp() { + const fiPage = createPage(paramsPage, { + route: '/boats/[id]/[slug]', + segments: [[staticPart('boats')], [dynamicPart('id')], [dynamicPart('slug')]], + }); + const enPage = createPage(paramsPage, { + route: '/en/boats/[id]/[slug]', + segments: [ + [staticPart('en')], + [staticPart('boats')], + [dynamicPart('id')], + [dynamicPart('slug')], + ], + }); + // Real Astro leaves `pathname` undefined for dynamic routes, but the mock + // defaults it to the route string (which contains the `/en/` prefix). That + // would mask the `Astro.currentLocale` bug, since locale detection would + // find the prefix in routeData.pathname instead of relying on the + // domain-derived pathname. Null it out so the test reproduces #16854. + fiPage.routeData.pathname = undefined; + enPage.routeData.pathname = undefined; + return createTestApp([fiPage, enPage], { + i18n, + middleware: () => ({ onRequest: middleware }), + }); + } + + it('resolves params and currentLocale for dynamic route on non-default locale domain', async () => { + const app = createDomainApp(); + const res = await app.render( + new Request('https://en.example.com/boats/1/sunset-cruiser', { + headers: { 'X-Forwarded-Host': 'en.example.com', 'X-Forwarded-Proto': 'https' }, + }), + ); + assert.equal(res.status, 200); + const $ = cheerio.load(await res.text()); + assert.equal($('#id').text(), '1'); + assert.equal($('#slug').text(), 'sunset-cruiser'); + assert.equal($('#locale').text(), 'en'); + }); + + it('resolves params and currentLocale for dynamic route on default locale domain', async () => { + const app = createDomainApp(); + const res = await app.render(new Request('http://example.com/boats/2/blue-wave')); + assert.equal(res.status, 200); + const $ = cheerio.load(await res.text()); + assert.equal($('#id').text(), '2'); + assert.equal($('#slug').text(), 'blue-wave'); + assert.equal($('#locale').text(), 'fi'); + }); +}); + // #15098: Invalid locale in URL should render 404, not the [locale] page describe('i18n via App - invalid locale with dynamic [locale] route (#15098)', () => { const i18n = makeI18nConfig({ From fd7784e3403981c524206a52d7d80eec572c5e89 Mon Sep 17 00:00:00 2001 From: "Houston (Bot)" <108291165+astrobot-houston@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:34:30 -0700 Subject: [PATCH 2/2] [ci] release (#16950) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/fix-app-match-malformed-uri.md | 5 -- .changeset/fix-client-hmr-program-reload.md | 5 -- .changeset/fix-endpoint-html-params.md | 5 -- .changeset/fix-i18n-domain-dynamic-params.md | 5 -- .changeset/fix-route-pattern-casing.md | 5 -- .changeset/lazy-jeans-brake.md | 5 -- .changeset/normalize-filename-case.md | 5 -- .changeset/rare-bikes-open.md | 5 -- .changeset/satteri-gfm-math-options.md | 6 --- examples/advanced-routing/package.json | 2 +- examples/basics/package.json | 2 +- examples/blog/package.json | 4 +- examples/component/package.json | 2 +- examples/container-with-vitest/package.json | 2 +- examples/framework-alpine/package.json | 2 +- examples/framework-multiple/package.json | 2 +- examples/framework-preact/package.json | 2 +- examples/framework-react/package.json | 2 +- examples/framework-solid/package.json | 2 +- examples/framework-svelte/package.json | 2 +- examples/framework-vue/package.json | 2 +- examples/hackernews/package.json | 2 +- examples/integration/package.json | 2 +- examples/minimal/package.json | 2 +- examples/portfolio/package.json | 2 +- examples/ssr/package.json | 2 +- examples/starlog/package.json | 2 +- examples/toolbar-app/package.json | 2 +- examples/with-markdoc/package.json | 2 +- examples/with-mdx/package.json | 4 +- examples/with-nanostores/package.json | 2 +- examples/with-tailwindcss/package.json | 4 +- examples/with-vitest/package.json | 2 +- packages/astro/CHANGELOG.md | 20 ++++++++ packages/astro/package.json | 2 +- packages/integrations/mdx/CHANGELOG.md | 9 ++++ packages/integrations/mdx/package.json | 2 +- packages/markdown/satteri/CHANGELOG.md | 6 +++ packages/markdown/satteri/package.json | 2 +- pnpm-lock.yaml | 54 ++++++++++---------- 40 files changed, 92 insertions(+), 103 deletions(-) delete mode 100644 .changeset/fix-app-match-malformed-uri.md delete mode 100644 .changeset/fix-client-hmr-program-reload.md delete mode 100644 .changeset/fix-endpoint-html-params.md delete mode 100644 .changeset/fix-i18n-domain-dynamic-params.md delete mode 100644 .changeset/fix-route-pattern-casing.md delete mode 100644 .changeset/lazy-jeans-brake.md delete mode 100644 .changeset/normalize-filename-case.md delete mode 100644 .changeset/rare-bikes-open.md delete mode 100644 .changeset/satteri-gfm-math-options.md diff --git a/.changeset/fix-app-match-malformed-uri.md b/.changeset/fix-app-match-malformed-uri.md deleted file mode 100644 index e6858fde45e5..000000000000 --- a/.changeset/fix-app-match-malformed-uri.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Prevents `App.match()` from throwing on request paths that contain an invalid percent-sequence. diff --git a/.changeset/fix-client-hmr-program-reload.md b/.changeset/fix-client-hmr-program-reload.md deleted file mode 100644 index 00daf20677c3..000000000000 --- a/.changeset/fix-client-hmr-program-reload.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes an issue where editing a client-side component (e.g. with `client:idle`, `client:load`, etc.) caused an unnecessary full program reload of the backend during development. diff --git a/.changeset/fix-endpoint-html-params.md b/.changeset/fix-endpoint-html-params.md deleted file mode 100644 index f0f5fe88ff9b..000000000000 --- a/.changeset/fix-endpoint-html-params.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes a bug where static file endpoints using `getStaticPaths` with `.html` in dynamic param values (e.g. `{ path: 'file.html' }`) would fail with a `NoMatchingStaticPathFound` error during build. The `.html` suffix is no longer incorrectly stripped from endpoint route pathnames. diff --git a/.changeset/fix-i18n-domain-dynamic-params.md b/.changeset/fix-i18n-domain-dynamic-params.md deleted file mode 100644 index 7635409eac67..000000000000 --- a/.changeset/fix-i18n-domain-dynamic-params.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes dynamic routes returning 500 "TypeError: Missing parameter" when using domain-based i18n routing in SSR. diff --git a/.changeset/fix-route-pattern-casing.md b/.changeset/fix-route-pattern-casing.md deleted file mode 100644 index b6df67b69bfa..000000000000 --- a/.changeset/fix-route-pattern-casing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes `Astro.routePattern` to preserve original casing of dynamic parameter names from filenames. Previously, a file at `src/pages/blog/[postId].astro` would return `/blog/[postid]` for `Astro.routePattern` due to an internal `.toLowerCase()` call. It now correctly returns `/blog/[postId]`. diff --git a/.changeset/lazy-jeans-brake.md b/.changeset/lazy-jeans-brake.md deleted file mode 100644 index d49080a13bb1..000000000000 --- a/.changeset/lazy-jeans-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"astro": patch ---- - -Fix an issue where dynamic routes would return the string `[object Object]` instead of the expected content, in certain runtimes. diff --git a/.changeset/normalize-filename-case.md b/.changeset/normalize-filename-case.md deleted file mode 100644 index f004c318e59d..000000000000 --- a/.changeset/normalize-filename-case.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes styles being stripped when the project root is started with a path whose case differs from the actual filesystem case (e.g. running `astro dev` from `d:\dev\app` while the folder on disk is `D:\dev\app`). diff --git a/.changeset/rare-bikes-open.md b/.changeset/rare-bikes-open.md deleted file mode 100644 index 2cfc1de75d77..000000000000 --- a/.changeset/rare-bikes-open.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes `Astro.currentLocale` returning the default locale instead of the domain's locale on dynamic routes served from a mapped domain. diff --git a/.changeset/satteri-gfm-math-options.md b/.changeset/satteri-gfm-math-options.md deleted file mode 100644 index e09777b0c7a3..000000000000 --- a/.changeset/satteri-gfm-math-options.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@astrojs/markdown-satteri': patch -'@astrojs/mdx': patch ---- - -Updates Sätteri processor to v0.8.0. See [its changelog](https://github.com/bruits/satteri/blob/main/packages/satteri/CHANGELOG.md#080--2026-06-03) for details on bugs fixed and features added. diff --git a/examples/advanced-routing/package.json b/examples/advanced-routing/package.json index 651f8ae20e21..05e8d2d0b7ea 100644 --- a/examples/advanced-routing/package.json +++ b/examples/advanced-routing/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@astrojs/node": "^10.1.3", - "astro": "^6.4.3", + "astro": "^6.4.4", "hono": "^4.12.14" } } diff --git a/examples/basics/package.json b/examples/basics/package.json index 3d3bfd6704f9..7da5504b3ad2 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -13,6 +13,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^6.4.3" + "astro": "^6.4.4" } } diff --git a/examples/blog/package.json b/examples/blog/package.json index a77697ca619f..02655aa8289e 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -13,10 +13,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^6.0.1", + "@astrojs/mdx": "^6.0.2", "@astrojs/rss": "^4.0.18", "@astrojs/sitemap": "^3.7.3", - "astro": "^6.4.3", + "astro": "^6.4.4", "sharp": "^0.34.3" } } diff --git a/examples/component/package.json b/examples/component/package.json index 637cf89665a4..3313757b8e30 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -18,7 +18,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^6.4.3" + "astro": "^6.4.4" }, "peerDependencies": { "astro": "^5.0.0 || ^6.0.0" diff --git a/examples/container-with-vitest/package.json b/examples/container-with-vitest/package.json index 7aa9066ed94e..c3002b50e601 100644 --- a/examples/container-with-vitest/package.json +++ b/examples/container-with-vitest/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@astrojs/react": "^5.0.7", - "astro": "^6.4.3", + "astro": "^6.4.4", "react": "^18.3.1", "react-dom": "^18.3.1", "vitest": "^4.1.0" diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index 30a870dda1e9..b32bc3bbf2bf 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -16,6 +16,6 @@ "@astrojs/alpinejs": "^0.5.0", "@types/alpinejs": "^3.13.11", "alpinejs": "^3.15.8", - "astro": "^6.4.3" + "astro": "^6.4.4" } } diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index ce9230233a02..bf8ece2d5e83 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -20,7 +20,7 @@ "@astrojs/vue": "^6.0.1", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", - "astro": "^6.4.3", + "astro": "^6.4.4", "preact": "^10.28.4", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index 3ca4ce35f07b..b8addf1cef89 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -15,7 +15,7 @@ "dependencies": { "@astrojs/preact": "^5.1.5", "@preact/signals": "^2.8.1", - "astro": "^6.4.3", + "astro": "^6.4.4", "preact": "^10.28.4" } } diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index 8f9ae9245cd7..0fc95b68dfa5 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -16,7 +16,7 @@ "@astrojs/react": "^5.0.7", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", - "astro": "^6.4.3", + "astro": "^6.4.4", "react": "^18.3.1", "react-dom": "^18.3.1" } diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index 136b9ee4ce9d..3195f7affbd9 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@astrojs/solid-js": "^6.0.1", - "astro": "^6.4.3", + "astro": "^6.4.4", "solid-js": "^1.9.11" } } diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 535283683379..9e8d0209d120 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@astrojs/svelte": "^8.1.2", - "astro": "^6.4.3", + "astro": "^6.4.4", "svelte": "^5.53.5" } } diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index 3b9eff1f0490..17a7cd0d63a1 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@astrojs/vue": "^6.0.1", - "astro": "^6.4.3", + "astro": "^6.4.4", "vue": "^3.5.29" } } diff --git a/examples/hackernews/package.json b/examples/hackernews/package.json index 22bef2ec20b2..cbf008d9dfb0 100644 --- a/examples/hackernews/package.json +++ b/examples/hackernews/package.json @@ -14,6 +14,6 @@ }, "dependencies": { "@astrojs/node": "^10.1.3", - "astro": "^6.4.3" + "astro": "^6.4.4" } } diff --git a/examples/integration/package.json b/examples/integration/package.json index 7e4fb41b86dc..51d64e9c74f8 100644 --- a/examples/integration/package.json +++ b/examples/integration/package.json @@ -18,7 +18,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^6.4.3" + "astro": "^6.4.4" }, "peerDependencies": { "astro": "^4.0.0" diff --git a/examples/minimal/package.json b/examples/minimal/package.json index a775378d7163..07e7a8c232c9 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -13,6 +13,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^6.4.3" + "astro": "^6.4.4" } } diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index 39fde75051b0..94546a9c751b 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -13,6 +13,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^6.4.3" + "astro": "^6.4.4" } } diff --git a/examples/ssr/package.json b/examples/ssr/package.json index 990d4cbb4097..1f81e877547b 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -16,7 +16,7 @@ "dependencies": { "@astrojs/node": "^10.1.3", "@astrojs/svelte": "^8.1.2", - "astro": "^6.4.3", + "astro": "^6.4.4", "svelte": "^5.53.5" } } diff --git a/examples/starlog/package.json b/examples/starlog/package.json index 4000c2cddfeb..fbf9e9f7d90d 100644 --- a/examples/starlog/package.json +++ b/examples/starlog/package.json @@ -9,7 +9,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^6.4.3", + "astro": "^6.4.4", "sass": "^1.97.3", "sharp": "^0.34.3" }, diff --git a/examples/toolbar-app/package.json b/examples/toolbar-app/package.json index d3e038d8f7b4..3ae6009de43a 100644 --- a/examples/toolbar-app/package.json +++ b/examples/toolbar-app/package.json @@ -16,7 +16,7 @@ }, "devDependencies": { "@types/node": "^22.10.6", - "astro": "^6.4.3" + "astro": "^6.4.4" }, "engines": { "node": ">=22.12.0" diff --git a/examples/with-markdoc/package.json b/examples/with-markdoc/package.json index 97b044850a93..c3104cca5d2e 100644 --- a/examples/with-markdoc/package.json +++ b/examples/with-markdoc/package.json @@ -14,6 +14,6 @@ }, "dependencies": { "@astrojs/markdoc": "^1.0.6", - "astro": "^6.4.3" + "astro": "^6.4.4" } } diff --git a/examples/with-mdx/package.json b/examples/with-mdx/package.json index d01039d9401c..9511a95eba68 100644 --- a/examples/with-mdx/package.json +++ b/examples/with-mdx/package.json @@ -13,9 +13,9 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^6.0.1", + "@astrojs/mdx": "^6.0.2", "@astrojs/preact": "^5.1.5", - "astro": "^6.4.3", + "astro": "^6.4.4", "preact": "^10.28.4" } } diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index 9781c2953127..1cd24d6c6ab5 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -15,7 +15,7 @@ "dependencies": { "@astrojs/preact": "^5.1.5", "@nanostores/preact": "^1.0.0", - "astro": "^6.4.3", + "astro": "^6.4.4", "nanostores": "^1.1.1", "preact": "^10.28.4" } diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index b3d86b20edc7..9e67815e6e07 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -13,10 +13,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^6.0.1", + "@astrojs/mdx": "^6.0.2", "@tailwindcss/vite": "^4.2.1", "@types/canvas-confetti": "^1.9.0", - "astro": "^6.4.3", + "astro": "^6.4.4", "canvas-confetti": "^1.9.4", "tailwindcss": "^4.2.1" } diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json index 17a6db6b6f2c..1b7177563553 100644 --- a/examples/with-vitest/package.json +++ b/examples/with-vitest/package.json @@ -14,7 +14,7 @@ "test": "vitest" }, "dependencies": { - "astro": "^6.4.3", + "astro": "^6.4.4", "vitest": "^4.1.0" } } diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index a66ae650e470..c62ead96df70 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,25 @@ # astro +## 6.4.4 + +### Patch Changes + +- [#16926](https://github.com/withastro/astro/pull/16926) [`1b39ae8`](https://github.com/withastro/astro/commit/1b39ae8485406937501d8a734afe2a464d671064) Thanks [@narendraio](https://github.com/narendraio)! - Prevents `App.match()` from throwing on request paths that contain an invalid percent-sequence. + +- [#16924](https://github.com/withastro/astro/pull/16924) [`2c0bc94`](https://github.com/withastro/astro/commit/2c0bc943d96d602b429ce3ecbb379d01a46903b5) Thanks [@astrobot-houston](https://github.com/astrobot-houston)! - Fixes an issue where editing a client-side component (e.g. with `client:idle`, `client:load`, etc.) caused an unnecessary full program reload of the backend during development. + +- [#16958](https://github.com/withastro/astro/pull/16958) [`2c1d50f`](https://github.com/withastro/astro/commit/2c1d50f5f9d557d7cdc17fd75f3a10fd203699c9) Thanks [@fkatsuhiro](https://github.com/fkatsuhiro)! - Fixes a bug where static file endpoints using `getStaticPaths` with `.html` in dynamic param values (e.g. `{ path: 'file.html' }`) would fail with a `NoMatchingStaticPathFound` error during build. The `.html` suffix is no longer incorrectly stripped from endpoint route pathnames. + +- [#16855](https://github.com/withastro/astro/pull/16855) [`c610cda`](https://github.com/withastro/astro/commit/c610cda44b273c15a6e7eaa4a84fa194002643e1) Thanks [@astrobot-houston](https://github.com/astrobot-houston)! - Fixes dynamic routes returning 500 "TypeError: Missing parameter" when using domain-based i18n routing in SSR. + +- [#16946](https://github.com/withastro/astro/pull/16946) [`606c37b`](https://github.com/withastro/astro/commit/606c37b886a9e25170ba82634cc81a8a775e8ac6) Thanks [@ematipico](https://github.com/ematipico)! - Fixes `Astro.routePattern` to preserve original casing of dynamic parameter names from filenames. Previously, a file at `src/pages/blog/[postId].astro` would return `/blog/[postid]` for `Astro.routePattern` due to an internal `.toLowerCase()` call. It now correctly returns `/blog/[postId]`. + +- [#16720](https://github.com/withastro/astro/pull/16720) [`16d49b6`](https://github.com/withastro/astro/commit/16d49b694071be212fb8c5a141ade72e8717a30e) Thanks [@thomas-callahan-collibra](https://github.com/thomas-callahan-collibra)! - Fix an issue where dynamic routes would return the string `[object Object]` instead of the expected content, in certain runtimes. + +- [#16703](https://github.com/withastro/astro/pull/16703) [`17390a6`](https://github.com/withastro/astro/commit/17390a6184d5cbd5ff85b7f652a92f5a6a7b0557) Thanks [@henrybrewer00-dotcom](https://github.com/henrybrewer00-dotcom)! - Fixes styles being stripped when the project root is started with a path whose case differs from the actual filesystem case (e.g. running `astro dev` from `d:\dev\app` while the folder on disk is `D:\dev\app`). + +- [#16855](https://github.com/withastro/astro/pull/16855) [`c610cda`](https://github.com/withastro/astro/commit/c610cda44b273c15a6e7eaa4a84fa194002643e1) Thanks [@astrobot-houston](https://github.com/astrobot-houston)! - Fixes `Astro.currentLocale` returning the default locale instead of the domain's locale on dynamic routes served from a mapped domain. + ## 6.4.3 ### Patch Changes diff --git a/packages/astro/package.json b/packages/astro/package.json index 403b13674d0c..e799ca9269aa 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "6.4.3", + "version": "6.4.4", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", diff --git a/packages/integrations/mdx/CHANGELOG.md b/packages/integrations/mdx/CHANGELOG.md index 383123ef4b82..68000080e1f4 100644 --- a/packages/integrations/mdx/CHANGELOG.md +++ b/packages/integrations/mdx/CHANGELOG.md @@ -1,5 +1,14 @@ # @astrojs/mdx +## 6.0.2 + +### Patch Changes + +- [#16955](https://github.com/withastro/astro/pull/16955) [`9a93d68`](https://github.com/withastro/astro/commit/9a93d68429aa15e76f07268863badfbda7b59d23) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Updates Sätteri processor to v0.8.0. See [its changelog](https://github.com/bruits/satteri/blob/main/packages/satteri/CHANGELOG.md#080--2026-06-03) for details on bugs fixed and features added. + +- Updated dependencies [[`9a93d68`](https://github.com/withastro/astro/commit/9a93d68429aa15e76f07268863badfbda7b59d23)]: + - @astrojs/markdown-satteri@0.2.2 + ## 6.0.1 ### Patch Changes diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json index 6d18eb293ba6..d0a809a9a1d1 100644 --- a/packages/integrations/mdx/package.json +++ b/packages/integrations/mdx/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/mdx", "description": "Add support for MDX pages in your Astro site", - "version": "6.0.1", + "version": "6.0.2", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", diff --git a/packages/markdown/satteri/CHANGELOG.md b/packages/markdown/satteri/CHANGELOG.md index cefabbcfada1..72f98b3765ff 100644 --- a/packages/markdown/satteri/CHANGELOG.md +++ b/packages/markdown/satteri/CHANGELOG.md @@ -1,5 +1,11 @@ # @astrojs/markdown-satteri +## 0.2.2 + +### Patch Changes + +- [#16955](https://github.com/withastro/astro/pull/16955) [`9a93d68`](https://github.com/withastro/astro/commit/9a93d68429aa15e76f07268863badfbda7b59d23) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Updates Sätteri processor to v0.8.0. See [its changelog](https://github.com/bruits/satteri/blob/main/packages/satteri/CHANGELOG.md#080--2026-06-03) for details on bugs fixed and features added. + ## 0.2.1 ### Patch Changes diff --git a/packages/markdown/satteri/package.json b/packages/markdown/satteri/package.json index 058e89c729f9..43ed79dabba4 100644 --- a/packages/markdown/satteri/package.json +++ b/packages/markdown/satteri/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/markdown-satteri", - "version": "0.2.1", + "version": "0.2.2", "type": "module", "author": "withastro", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 604b8d3e3f57..51e1549cbdd9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -197,7 +197,7 @@ importers: specifier: ^10.1.3 version: link:../../packages/integrations/node astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro hono: specifier: ^4.12.14 @@ -206,13 +206,13 @@ importers: examples/basics: dependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/blog: dependencies: '@astrojs/mdx': - specifier: ^6.0.1 + specifier: ^6.0.2 version: link:../../packages/integrations/mdx '@astrojs/rss': specifier: ^4.0.18 @@ -221,7 +221,7 @@ importers: specifier: ^3.7.3 version: link:../../packages/integrations/sitemap astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro sharp: specifier: ^0.34.3 @@ -230,7 +230,7 @@ importers: examples/component: devDependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/container-with-vitest: @@ -239,7 +239,7 @@ importers: specifier: ^5.0.7 version: link:../../packages/integrations/react astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro react: specifier: ^18.3.1 @@ -270,7 +270,7 @@ importers: specifier: ^3.15.8 version: 3.15.8 astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/framework-multiple: @@ -297,7 +297,7 @@ importers: specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.28) astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro preact: specifier: ^10.28.4 @@ -327,7 +327,7 @@ importers: specifier: ^2.8.1 version: 2.8.2(preact@10.29.0) astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro preact: specifier: ^10.28.4 @@ -345,7 +345,7 @@ importers: specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.28) astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro react: specifier: ^18.3.1 @@ -360,7 +360,7 @@ importers: specifier: ^6.0.1 version: link:../../packages/integrations/solid astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro solid-js: specifier: ^1.9.11 @@ -372,7 +372,7 @@ importers: specifier: ^8.1.2 version: link:../../packages/integrations/svelte astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro svelte: specifier: ^5.53.5 @@ -384,7 +384,7 @@ importers: specifier: ^6.0.1 version: link:../../packages/integrations/vue astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro vue: specifier: ^3.5.29 @@ -396,25 +396,25 @@ importers: specifier: ^10.1.3 version: link:../../packages/integrations/node astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/integration: devDependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/minimal: dependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/portfolio: dependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/ssr: @@ -426,7 +426,7 @@ importers: specifier: ^8.1.2 version: link:../../packages/integrations/svelte astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro svelte: specifier: ^5.53.5 @@ -435,7 +435,7 @@ importers: examples/starlog: dependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro sass: specifier: ^1.97.3 @@ -450,7 +450,7 @@ importers: specifier: ^22.19.0 version: 22.19.19 astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/with-markdoc: @@ -459,19 +459,19 @@ importers: specifier: ^1.0.6 version: link:../../packages/integrations/markdoc astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro examples/with-mdx: dependencies: '@astrojs/mdx': - specifier: ^6.0.1 + specifier: ^6.0.2 version: link:../../packages/integrations/mdx '@astrojs/preact': specifier: ^5.1.5 version: link:../../packages/integrations/preact astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro preact: specifier: ^10.28.4 @@ -486,7 +486,7 @@ importers: specifier: ^1.0.0 version: 1.0.0(nanostores@1.1.1)(preact@10.29.0) astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro nanostores: specifier: ^1.1.1 @@ -498,7 +498,7 @@ importers: examples/with-tailwindcss: dependencies: '@astrojs/mdx': - specifier: ^6.0.1 + specifier: ^6.0.2 version: link:../../packages/integrations/mdx '@tailwindcss/vite': specifier: ^4.2.1 @@ -507,7 +507,7 @@ importers: specifier: ^1.9.0 version: 1.9.0 astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro canvas-confetti: specifier: ^1.9.4 @@ -519,7 +519,7 @@ importers: examples/with-vitest: dependencies: astro: - specifier: ^6.4.3 + specifier: ^6.4.4 version: link:../../packages/astro vitest: specifier: ^4.1.0