Skip to content

Commit 049da87

Browse files
feat!: trailing slash never for endpoints with file extension (#14457)
* feat!: trailing slash never for endpoints with file extension * Update giant-areas-press.md * Update .changeset/giant-areas-press.md Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --------- Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com>
1 parent 55a1a91 commit 049da87

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

.changeset/giant-areas-press.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'astro': major
3+
---
4+
5+
Updates trailing slash behavior of endpoint URLs.
6+
7+
In Astro v5.0, custom endpoints whose URL ended in a file extension (e.g. `/src/pages/sitemap.xml.ts` ) could be accessed with a trailing slash (`/sitemap.xml/`) or without (`/sitemap.xml`), regardless of the value configured for `build.trailingSlash`.
8+
9+
In Astro v6.0, these endpoints can only be accessed without a trailing slash. This is true regardless of your `build.trailingSlash` configuration.
10+
11+
#### What should I do?
12+
13+
Review your links to your custom endpoints that include a file extension in the URL and remove any trailing slashes:
14+
15+
```diff
16+
-<a href="/sitemap.xml/">Sitemap</a>
17+
+<a href="/sitemap.xml">Sitemap</a>
18+
```

packages/astro/src/core/routing/manifest/create.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,11 @@ function createFileBasedRoutes(
255255
}
256256

257257
// Get trailing slash rule for a path, based on the config and whether the path has an extension.
258-
// TODO: in Astro 6, change endpoints with extentions to use 'never'
259258
const trailingSlashForPath = (
260259
pathname: string | null,
261260
config: AstroConfig,
262261
): AstroConfig['trailingSlash'] =>
263-
pathname && hasFileExtension(pathname) ? 'ignore' : config.trailingSlash;
262+
pathname && hasFileExtension(pathname) ? 'never' : config.trailingSlash;
264263

265264
function createInjectedRoutes({ settings, cwd }: CreateRouteManifestParams): RouteData[] {
266265
const { config } = settings;

packages/astro/test/units/routing/trailing-slash.test.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,15 @@ describe('trailingSlash', () => {
171171
assert.equal(json, '{"success":true}');
172172
});
173173

174-
it('should match the API route when request has a trailing slash, with a file extension', async () => {
174+
it('should NOT match the API route when request has a trailing slash, with a file extension', async () => {
175175
const { req, res, text } = createRequestAndResponse({
176176
method: 'GET',
177177
url: '/dot.json/',
178178
});
179179
container.handle(req, res);
180-
const json = await text();
181-
assert.equal(json, '{"success":true}');
180+
const html = await text();
181+
assert.equal(html.includes(`<span class="statusMessage">Not found</span>`), true);
182+
assert.equal(res.statusCode, 404);
182183
});
183184

184185
it('should also match the API route when request lacks a trailing slash, with a file extension', async () => {

0 commit comments

Comments
 (0)