Skip to content

Commit

Permalink
enhance(i18n): i18nRedirectorにdefaultLocaleのページのmetaを反映
Browse files Browse the repository at this point in the history
  • Loading branch information
kakkokari-gtyih committed Jan 6, 2025
1 parent deaaf47 commit e299cc3
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 22 deletions.
25 changes: 22 additions & 3 deletions .vitepress/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { shared } from './shared';
import { ja } from './ja';
import { en } from './en';

import { genI18nRedirector } from '../scripts/gen-i18n-redirector';
import { createGenI18nRedirector } from '../scripts/gen-i18n-redirector';

const locales = {
ja: { label: '日本語', ...ja },
Expand All @@ -16,14 +16,24 @@ export const mainLocale = 'ja' as const satisfies keyof typeof locales;

export const baseUrl = 'https://aiscript-dev.github.io';

const { registerRouteMeta, genI18nRedirector } = createGenI18nRedirector();

export default defineConfig({
...shared,
locales,
transformHead(context) {
const head: HeadConfig[] = [];
const head: HeadConfig[] = [ ...context.head ];
if (!context.pageData.isNotFound) {
const localesRegex = new RegExp(`^/(${Object.keys(locales).join('|')})`);
const canonical = '/' + context.page.replace(/\.md$/, '.html').replace(/\/index\.html$/, '/');
const canonical = '/' + context.page.replace(/index\.(md|html)$/, '').replace(/\.md$/, context.siteConfig.cleanUrls ? '' : '.html');
const defaultLocalePath = canonical.replace(localesRegex, `/${mainLocale}`);

if (canonical.startsWith(`/${mainLocale}`)) {
registerRouteMeta(canonical.slice(1), {
title: context.title,
description: context.description,
});
}

for (const locale of Object.keys(locales)) {
const localePath = canonical.replace(localesRegex, `/${locale}`);
Expand All @@ -37,6 +47,15 @@ export default defineConfig({
},
]);
}

head.push([
'link',
{
rel: 'alternate',
hreflang: 'x-default',
href: baseUrl + defaultLocalePath,
},
]);

head.push([
'link',
Expand Down
1 change: 1 addition & 0 deletions .vitepress/config/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const shared = defineConfig({
head: [
['link', { rel: 'icon', href: '/favicon.ico' }],
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/icons/apple-touch-icon.png' }],
['meta', { property: 'og:site_name', content: 'AiScript' }],
],

markdown: {
Expand Down
69 changes: 50 additions & 19 deletions .vitepress/scripts/gen-i18n-redirector.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
// @ts-expect-error Node
import fs from 'fs';
import { mainLocale, baseUrl } from '../config';
import type { SiteConfig } from 'vitepress';

type RouteMeta = {
title: string;
description?: string;
};

async function createFile(path: string, content: string) {
const dir = path.replace(/\/[^/]+$/, '');
await fs.promises.writeFile(path, content).catch((err) => {
Expand All @@ -11,36 +17,61 @@ async function createFile(path: string, content: string) {
});
}

export async function genI18nRedirector(siteConfig: SiteConfig) {
const routes = siteConfig.pages
.filter((page) => page.startsWith(`${mainLocale}/`))
.map((page) => page.replace(new RegExp(`^${mainLocale}\/`), '').replace(/\.md$/, '.html'));
export function createGenI18nRedirector() {
const routeMeta = new Map<string, RouteMeta>();

function registerRouteMeta(route: string, meta: RouteMeta) {
routeMeta.set(route, meta);
}

async function genI18nRedirector(siteConfig: SiteConfig) {
const genStartedAt = performance.now();

const routes = siteConfig.pages
.filter((page) => page.startsWith(`${mainLocale}/`));

const promises = routes.map(async (route) => {
const routePath = route.replace(new RegExp(`^${mainLocale}\/`), '');
const routePathForWrite = routePath.replace(/\.md$/, '.html');
const routePathForRender = routePath.replace(/index\.(md|html)$/, '').replace(/\.md$/, siteConfig.cleanUrls ? '' : '.html');

const promises = routes.map((route) => {
const localeNames = Object.keys(siteConfig.site.locales);
const routeForRender = route.replace(/index\.html$/, '');
const linkAlternate = localeNames.map((name) => `<link rel="alternate" hreflang="${siteConfig.site.locales[name].lang || name}" href="${baseUrl}/${name}/${routeForRender}">`).join('\n ');
const fallbackLinks = localeNames.map((name) => `<a href="${baseUrl}/${name}/${routeForRender}">${siteConfig.site.locales[name].label}</a>`).join(', ');
const content = `<!DOCTYPE html>
<html lang="${siteConfig.site.locales[mainLocale].lang || 'ja-JP'}">
let title = 'Redirecting...';
let description: string | null = null;
if (routeMeta.has(`${mainLocale}/${routePathForRender}`)) {
title = routeMeta.get(`${mainLocale}/${routePathForRender}`)?.title ?? title;
description = routeMeta.get(`${mainLocale}/${routePathForRender}`)?.description ?? null;
}

const localeNames = Object.keys(siteConfig.site.locales);
const linkAlternate = localeNames.map((name) => `<link rel="alternate" hreflang="${siteConfig.site.locales[name].lang || name}" href="${baseUrl}/${name}/${routePathForRender}">`).join('\n ');
const fallbackLinks = localeNames.map((name) => `<a href="${baseUrl}/${name}/${routePathForRender}">${siteConfig.site.locales[name].label}</a>`).join(', ');
const content = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redirecting...</title>
<title>${title}</title>${description ? `\n <meta name="description" content="${description}">\n` : ''}
${linkAlternate}
<link rel="alternate" hreflang="x-default" href="${baseUrl}/${mainLocale}/${routeForRender}">
<link rel="canonical" href="${baseUrl}/${mainLocale}/${routeForRender}">
<link rel="alternate" hreflang="x-default" href="${baseUrl}/${mainLocale}/${routePathForRender}">
<link rel="canonical" href="${baseUrl}/${mainLocale}/${routePathForRender}">
<script type="text/javascript">const s = ${JSON.stringify(localeNames)}; const d = localStorage.getItem('ais:locale'); if (d) { location.replace('/' + d + location.pathname + location.search + location.hash); } else if (s.includes(navigator.language.split("-")[0])) { location.replace('/' + navigator.language.split("-")[0] + location.pathname + location.search + location.hash); } else { location.replace('/ja' + location.pathname + location.search + location.hash); }</script>
</head>
<body>
<noscript>${fallbackLinks}</noscript>
</body>
</html>
`;
return createFile(`${siteConfig.outDir}/${route}`, content);
});

await Promise.allSettled(promises);
await createFile(`${siteConfig.outDir}/${routePathForWrite}`, content);
});

await Promise.allSettled(promises);

const genFinishedAt = performance.now();
console.log(`I18n redirector generated in ${Math.round((genFinishedAt - genStartedAt) / 10) / 100}s`);
}

console.log('I18n redirector generated');
return {
registerRouteMeta,
genI18nRedirector,
};
}

0 comments on commit e299cc3

Please sign in to comment.