Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update generator.ts to allow %23 (#) in dynamic urls #10965

Merged
merged 11 commits into from
May 16, 2024
5 changes: 5 additions & 0 deletions .changeset/mean-geckos-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": minor
Elias-Chairi marked this conversation as resolved.
Show resolved Hide resolved
---

Update generator.ts to allow %23 (#) in dynamic urls
19 changes: 17 additions & 2 deletions packages/astro/src/core/routing/manifest/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ import type { AstroConfig, RoutePart } from '../../../@types/astro.js';

import { compile } from 'path-to-regexp';

function sanitizeParams(params: Record<string, string | number | undefined>): Record<string, string | number | undefined> {
Elias-Chairi marked this conversation as resolved.
Show resolved Hide resolved
return Object.entries(params).reduce((acc, [key, value]) => {
Elias-Chairi marked this conversation as resolved.
Show resolved Hide resolved
if (typeof value === 'string') {
acc[key] = value
.normalize()
.replace(/#/g, '%23')
.replace(/\?/g, '%3F')
} else {
acc[key] = value;
}
return acc;
}, {} as Record<string, string | number | undefined>);
}

export function getRouteGenerator(
segments: RoutePart[][],
addTrailingSlash: AstroConfig['trailingSlash']
Expand Down Expand Up @@ -37,8 +51,9 @@ export function getRouteGenerator(
trailing = '/';
}
const toPath = compile(template + trailing);
return (params: object): string => {
const path = toPath(params);
return (params: Record<string, string | number | undefined>): string => {
const sanitizedParams = sanitizeParams(params);
const path = toPath(sanitizedParams);

// When generating an index from a rest parameter route, `path-to-regexp` will return an
// empty string instead "/". This causes an inconsistency with static indexes that may result
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/test/ssr-params.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ describe('Astro.params in SSR', () => {

it('No double URL decoding', async () => {
const app = await fixture.loadTestAdapterApp();
const request = new Request('http://example.com/users/houston/%25');
const request = new Request('http://example.com/users/houston/%25%23%3F');
const response = await app.render(request);
assert.equal(response.status, 200);
const html = await response.text();
const $ = cheerio.load(html);
assert.equal($('.category').text(), '%');
assert.equal($('.category').text(), '%#?');
});
});