Astro Info
Astro v6.0.6
Vite v7.3.1
Node v22.21.1
System macOS (arm64)
Package Manager npm
Output server
Adapter @astrojs/vercel (v10.0.1)
Integrations none
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
When using domain-based i18n routing with trailingSlash: "never", requests to the root path (/) of a non-default locale's domain return 404.
The bug is in computePathnameFromDomain() in dist/core/app/base.js (lines 183-190). When a request arrives at the mapped domain, the method:
- Correctly resolves the locale from the domain and prepends it to the path:
/ → /en
- Then checks
if (url.pathname.endsWith("/")) and appends a trailing slash, producing /en/
Since the root path / inherently ends with /, this condition is always true for root-level requests. The resulting /en/ fails to match the route pattern ^\/en$ generated for trailingSlash: "never", causing a 404.
// base.js lines 183-190
if (locale) {
pathname = prependForwardSlash(
joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname))
);
if (url.pathname.endsWith("/")) {
pathname = appendForwardSlash(pathname);
}
}
The trailing slash append logic does not consult this.manifest.trailingSlash, so it conflicts with the route patterns when trailing slashes are disabled.
Config to reproduce:
export default defineConfig({
site: "https://example.fi",
output: "server",
trailingSlash: "never",
adapter: vercel(),
i18n: {
locales: ["fi", "en"],
defaultLocale: "fi",
domains: {
en: "https://example.com",
},
},
});
The default locale's domain works fine because computePathnameFromDomain() returns undefined for it, bypassing the buggy code path entirely.
Workaround: remove trailingSlash: "never" (use the default "ignore").
What's the expected result?
Requests to the root path of a domain-mapped locale (e.g., https://example.com/) should return 200 and render the correct page, regardless of the trailingSlash setting. The computePathnameFromDomain() method should respect the configured trailingSlash value when deciding whether to append a trailing slash to the locale-prefixed pathname.
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-khcpagmm?file=README.md
Participation
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
When using domain-based i18n routing with
trailingSlash: "never", requests to the root path (/) of a non-default locale's domain return 404.The bug is in
computePathnameFromDomain()indist/core/app/base.js(lines 183-190). When a request arrives at the mapped domain, the method:/→/enif (url.pathname.endsWith("/"))and appends a trailing slash, producing/en/Since the root path
/inherently ends with/, this condition is always true for root-level requests. The resulting/en/fails to match the route pattern^\/en$generated fortrailingSlash: "never", causing a 404.The trailing slash append logic does not consult
this.manifest.trailingSlash, so it conflicts with the route patterns when trailing slashes are disabled.Config to reproduce:
The default locale's domain works fine because
computePathnameFromDomain()returnsundefinedfor it, bypassing the buggy code path entirely.Workaround: remove
trailingSlash: "never"(use the default"ignore").What's the expected result?
Requests to the root path of a domain-mapped locale (e.g.,
https://example.com/) should return 200 and render the correct page, regardless of thetrailingSlashsetting. ThecomputePathnameFromDomain()method should respect the configuredtrailingSlashvalue when deciding whether to append a trailing slash to the locale-prefixed pathname.Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-khcpagmm?file=README.md
Participation