mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix(i18n): parse params and props correctly with fallback (#12709)
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
This commit is contained in:
parent
358eae83b7
commit
e3bfd93969
5 changed files with 104 additions and 10 deletions
5
.changeset/selfish-paws-play.md
Normal file
5
.changeset/selfish-paws-play.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes a bug where Astro couldn't correctly parse `params` and `props` when receiving i18n fallback URLs
|
|
@ -47,7 +47,8 @@ export async function getProps(opts: GetParamsAndPropsOptions): Promise<Props> {
|
|||
base,
|
||||
});
|
||||
|
||||
// The pathname used here comes from the server, which already encored.
|
||||
if (!staticPaths.length) return {};
|
||||
// The pathname used here comes from the server, which already encoded.
|
||||
// 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));
|
||||
|
@ -77,7 +78,11 @@ export function getParams(route: RouteData, pathname: string): Params {
|
|||
if (!route.params.length) return {};
|
||||
// The RegExp pattern expects a decoded string, but the pathname is encoded
|
||||
// when the URL contains non-English characters.
|
||||
const paramsMatch = route.pattern.exec(pathname);
|
||||
const paramsMatch =
|
||||
route.pattern.exec(pathname) ||
|
||||
route.fallbackRoutes
|
||||
.map((fallbackRoute) => fallbackRoute.pattern.exec(pathname))
|
||||
.find((x) => x);
|
||||
if (!paramsMatch) return {};
|
||||
const params: Params = {};
|
||||
route.params.forEach((key, i) => {
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
---
|
||||
// for SSR
|
||||
const blogs = {
|
||||
1: { content: "Hello world" },
|
||||
2: { content: "Eat Something" },
|
||||
3: { content: "How are you?" },
|
||||
}
|
||||
const id = Astro.params?.id;
|
||||
const ssrContent = id && blogs[id]?.content;
|
||||
|
||||
// for SSG
|
||||
export function getStaticPaths() {
|
||||
return [
|
||||
{params: {id: '1'}, props: { content: "Hello world" }},
|
||||
{params: {id: '2'}, props: { content: "Eat Something" }},
|
||||
{params: {id: '3'}, props: { content: "How are you?" }},
|
||||
];
|
||||
]
|
||||
}
|
||||
const { content } = Astro.props;
|
||||
const { content } = Astro.props
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
{content}
|
||||
{content || ssrContent}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
---
|
||||
const blogs = {
|
||||
1: { content: "Hola mundo" },
|
||||
2: { content: "Eat Something" },
|
||||
3: { content: "How are you?" },
|
||||
}
|
||||
const id = Astro.params?.id;
|
||||
const ssrContent = id && blogs[id]?.content;
|
||||
|
||||
export function getStaticPaths() {
|
||||
return [
|
||||
{params: {id: '1'}, props: { content: "Hola mundo" }},
|
||||
|
@ -13,6 +21,6 @@ const { content } = Astro.props;
|
|||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
{content}
|
||||
{content || ssrContent}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as cheerio from 'cheerio';
|
||||
import * as assert from 'node:assert/strict';
|
||||
import { after, afterEach, before, describe, it } from 'node:test';
|
||||
import * as cheerio from 'cheerio';
|
||||
import testAdapter from './test-adapter.js';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
|
@ -2000,12 +2000,14 @@ describe('Fallback rewrite dev server', () => {
|
|||
root: './fixtures/i18n-routing-fallback/',
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'fr'],
|
||||
locales: ['en', 'fr', 'es', 'it', 'pt'],
|
||||
routing: {
|
||||
prefixDefaultLocale: false,
|
||||
},
|
||||
fallback: {
|
||||
fr: 'en',
|
||||
it: 'en',
|
||||
es: 'pt',
|
||||
},
|
||||
fallbackType: 'rewrite',
|
||||
},
|
||||
|
@ -2021,6 +2023,27 @@ describe('Fallback rewrite dev server', () => {
|
|||
assert.match(html, /Hello/);
|
||||
// assert.fail()
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with path parameters correctly (fr)', async () => {
|
||||
let response = await fixture.fetch('/fr/blog/1');
|
||||
assert.equal(response.status, 200);
|
||||
const text = await response.text();
|
||||
assert.match(text, /Hello world/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with path parameters correctly (es)', async () => {
|
||||
let response = await fixture.fetch('/es/blog/1');
|
||||
assert.equal(response.status, 200);
|
||||
const text = await response.text();
|
||||
assert.match(text, /Hola mundo/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with query parameters correctly (it)', async () => {
|
||||
let response = await fixture.fetch('/it/blog/1');
|
||||
assert.equal(response.status, 200);
|
||||
const text = await response.text();
|
||||
assert.match(text, /Hello world/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Fallback rewrite SSG', () => {
|
||||
|
@ -2032,13 +2055,15 @@ describe('Fallback rewrite SSG', () => {
|
|||
root: './fixtures/i18n-routing-fallback/',
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'fr'],
|
||||
locales: ['en', 'fr', 'es', 'it', 'pt'],
|
||||
routing: {
|
||||
prefixDefaultLocale: false,
|
||||
fallbackType: 'rewrite',
|
||||
},
|
||||
fallback: {
|
||||
fr: 'en',
|
||||
it: 'en',
|
||||
es: 'pt',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -2051,6 +2076,21 @@ describe('Fallback rewrite SSG', () => {
|
|||
assert.match(html, /Hello/);
|
||||
// assert.fail()
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with path parameters correctly (fr)', async () => {
|
||||
const html = await fixture.readFile('/fr/blog/1/index.html');
|
||||
assert.match(html, /Hello world/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with path parameters correctly (es)', async () => {
|
||||
const html = await fixture.readFile('/es/blog/1/index.html');
|
||||
assert.match(html, /Hola mundo/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with query parameters correctly (it)', async () => {
|
||||
const html = await fixture.readFile('/it/blog/1/index.html');
|
||||
assert.match(html, /Hello world/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Fallback rewrite SSR', () => {
|
||||
|
@ -2066,13 +2106,15 @@ describe('Fallback rewrite SSR', () => {
|
|||
adapter: testAdapter(),
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'fr'],
|
||||
locales: ['en', 'fr', 'es', 'it', 'pt'],
|
||||
routing: {
|
||||
prefixDefaultLocale: false,
|
||||
fallbackType: 'rewrite',
|
||||
},
|
||||
fallback: {
|
||||
fr: 'en',
|
||||
it: 'en',
|
||||
es: 'pt',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -2087,4 +2129,28 @@ describe('Fallback rewrite SSR', () => {
|
|||
const html = await response.text();
|
||||
assert.match(html, /Hello/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with path parameters correctly (fr)', async () => {
|
||||
let request = new Request('http://example.com/new-site/fr/blog/1');
|
||||
let response = await app.render(request);
|
||||
assert.equal(response.status, 200);
|
||||
const text = await response.text();
|
||||
assert.match(text, /Hello world/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with path parameters correctly (es)', async () => {
|
||||
let request = new Request('http://example.com/new-site/es/blog/1');
|
||||
let response = await app.render(request);
|
||||
assert.equal(response.status, 200);
|
||||
const text = await response.text();
|
||||
assert.match(text, /Hola mundo/);
|
||||
});
|
||||
|
||||
it('should render fallback locale paths with query parameters correctly (it)', async () => {
|
||||
let request = new Request('http://example.com/new-site/it/blog/1');
|
||||
let response = await app.render(request);
|
||||
assert.equal(response.status, 200);
|
||||
const text = await response.text();
|
||||
assert.match(text, /Hello world/);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue