diff --git a/.changeset/metal-birds-admire.md b/.changeset/metal-birds-admire.md new file mode 100644 index 0000000000..56ee190d1e --- /dev/null +++ b/.changeset/metal-birds-admire.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes a bug where the params weren't correctly computed when rendering URLs with non-English characters diff --git a/packages/astro/src/core/render/params-and-props.ts b/packages/astro/src/core/render/params-and-props.ts index 5eabbc0d43..588969eb47 100644 --- a/packages/astro/src/core/render/params-and-props.ts +++ b/packages/astro/src/core/render/params-and-props.ts @@ -47,7 +47,10 @@ export async function getProps(opts: GetParamsAndPropsOptions): Promise { base, }); - const params = getParams(route, pathname); + // The pathname used here comes from the server, which already encored. + // Since we decided to not mess up with encoding anymore, we need to decode them back so the parameters can match + // the ones expected from the users + const params = getParams(route, decodeURI(pathname)); const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger); if (!matchedStaticPath && (serverLike ? route.prerender : true)) { throw new AstroError({ diff --git a/packages/astro/test/fixtures/ssr-params/src/pages/[category].astro b/packages/astro/test/fixtures/ssr-params/src/pages/[category].astro index d5bdfd3a65..2e2ca3a82d 100644 --- a/packages/astro/test/fixtures/ssr-params/src/pages/[category].astro +++ b/packages/astro/test/fixtures/ssr-params/src/pages/[category].astro @@ -6,6 +6,7 @@ export function getStaticPaths() { { params: { category: "%2Fsomething" } }, { params: { category: "%3Fsomething" } }, { params: { category: "[page]" } }, + { params: { category: "你好" } }, ] } --- diff --git a/packages/astro/test/params.test.js b/packages/astro/test/params.test.js index 14addbb96c..7508b73528 100644 --- a/packages/astro/test/params.test.js +++ b/packages/astro/test/params.test.js @@ -1,5 +1,5 @@ import assert from 'node:assert/strict'; -import { before, describe, it } from 'node:test'; +import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; import testAdapter from './test-adapter.js'; import { loadFixture } from './test-utils.js'; @@ -90,6 +90,31 @@ describe('Astro.params in SSR', () => { }); }); +describe('Astro.params in dev mode', () => { + /** @type {import('./test-utils.js').Fixture} */ + let fixture; + let devServer; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/ssr-params/', + adapter: testAdapter(), + output: 'server', + }); + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('should handle non-english URLs', async () => { + const html = await fixture.fetch('/你好').then((res) => res.text()); + const $ = cheerio.load(html); + assert.equal($('.category').text(), '你好'); + }); +}); + describe('Astro.params in static mode', () => { let fixture;