Skip to content

Commit 5c78a93

Browse files
author
徐燕来
committed
fix(landing): preserve canonical event tutorial links
1 parent 1bf65e7 commit 5c78a93

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

apps/landing-page/app/i18n.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7093,6 +7093,12 @@ export function pageNameFromPath(pathname = '/'): string {
70937093
return segments.join('_').toLowerCase().replace(/[^a-z0-9_]+/g, '_');
70947094
}
70957095

7096+
// These pages intentionally ship only at their canonical English URL. Internal
7097+
// links must not acquire a locale prefix that points at an ungenerated route.
7098+
const LOCALE_CANONICAL_ONLY_PATHS = new Set([
7099+
'/tutorials/open-design-ai-ppt-tutorial/',
7100+
]);
7101+
70967102
export function localizedHref(
70977103
href: string,
70987104
locale: LandingLocaleCode,
@@ -7113,7 +7119,11 @@ export function localizedHref(
71137119
if (pathAndQuery === '') return hashSuffix || href;
71147120
const [path, query = ''] = pathAndQuery.split('?');
71157121
const querySuffix = query ? `?${query}` : '';
7116-
const localized = localePath(locale, path || '/');
7122+
const pathname = path || '/';
7123+
if (LOCALE_CANONICAL_ONLY_PATHS.has(pathname)) {
7124+
return `${pathname}${querySuffix}${hashSuffix}`;
7125+
}
7126+
const localized = localePath(locale, pathname);
71177127
return `${localized}${querySuffix}${hashSuffix}`;
71187128
}
71197129

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import assert from 'node:assert/strict';
2+
import { readFile } from 'node:fs/promises';
3+
import { test } from 'node:test';
4+
5+
import { LANDING_LOCALES, localizedHref } from '../app/i18n.ts';
6+
7+
const PPT_TUTORIAL_PATH = '/tutorials/open-design-ai-ppt-tutorial/';
8+
const EVENT_PARTIALS = [
9+
'open-design-osaka-meetup-main',
10+
'open-design-shanghai-workshop-main',
11+
] as const;
12+
13+
function localizeInternalLinks(html: string, locale: (typeof LANDING_LOCALES)[number]['code']) {
14+
return html.replace(
15+
/href="(\/[^\"]+)"/g,
16+
(_match, pathname: string) => `href="${localizedHref(pathname, locale)}"`,
17+
);
18+
}
19+
20+
test('event recaps keep canonical-only tutorial links valid in every active locale', async () => {
21+
for (const eventPartial of EVENT_PARTIALS) {
22+
for (const { code } of LANDING_LOCALES) {
23+
const localeSuffix = code === 'en' ? '' : `.${code}`;
24+
const partial = await readFile(
25+
new URL(`../app/_partials/${eventPartial}${localeSuffix}.html`, import.meta.url),
26+
'utf8',
27+
);
28+
const rendered = localizeInternalLinks(partial, code);
29+
30+
assert.match(
31+
partial,
32+
new RegExp(`href="${PPT_TUTORIAL_PATH}"`),
33+
`${eventPartial}.${code}: fixture no longer links to the canonical tutorial`,
34+
);
35+
assert.match(
36+
rendered,
37+
new RegExp(`href="${PPT_TUTORIAL_PATH}"`),
38+
`${eventPartial}.${code}: canonical tutorial link was rewritten`,
39+
);
40+
assert.doesNotMatch(
41+
rendered,
42+
new RegExp(`href="/${code}${PPT_TUTORIAL_PATH}"`),
43+
`${eventPartial}.${code}: generated link points at a missing localized tutorial route`,
44+
);
45+
}
46+
}
47+
});

0 commit comments

Comments
 (0)