Skip to content

Commit

Permalink
enhance(i18n): i18nRedirectorを改良
Browse files Browse the repository at this point in the history
  • Loading branch information
kakkokari-gtyih committed Dec 5, 2024
1 parent 5aea98f commit 435e1ac
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 41 deletions.
12 changes: 9 additions & 3 deletions .vitepress/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { defineConfig } from 'vitepress';
import type { LocaleConfig, DefaultTheme, HeadConfig } from 'vitepress';

import { shared } from './shared';
import { ja } from './ja';
import { en } from './en';

const locales: LocaleConfig<DefaultTheme.Config> = {
import { genI18nRedirector } from '../scripts/gen-i18n-redirector';

const locales = {
ja: { label: '日本語', ...ja },
en: { label: 'English', ...en },
};
} as const satisfies LocaleConfig<DefaultTheme.Config>;

export const mainLocale = 'ja' as const satisfies keyof typeof locales;

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

export default defineConfig({
...shared,
Expand Down Expand Up @@ -44,4 +49,5 @@ export default defineConfig({

return head;
},
buildEnd: genI18nRedirector,
});
47 changes: 47 additions & 0 deletions .vitepress/scripts/gen-i18n-redirector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//@ts-expect-error Node
import fs from 'fs';
import { mainLocale, baseUrl } from '../config';
import type { SiteConfig } from 'vitepress';

async function createFile(path: string, content: string) {
const dir = path.replace(/\/[^/]+$/, '');
await fs.promises.writeFile(path, content).catch((err) => {
if (err.code === 'ENOENT') {
fs.promises.mkdir(dir, { recursive: true }).then(() => createFile(path, content));
}
});
}

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'));

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'}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redirecting...</title>
${linkAlternate}
<link rel="alternate" hreflang="x-default" href="${baseUrl}/${mainLocale}/${routeForRender}">
<link rel="canonical" href="${baseUrl}/${mainLocale}/${routeForRender}">
<script type="text/javascript">const s = ${JSON.stringify(localeNames)}; const d = localStorage.getItem('ais:locale'); if (d) { location.replace('/' + d + location.pathname + location.search); } else if (s.includes(navigator.language.split("-")[0])) { location.replace('/' + navigator.language.split("-")[0] + location.pathname + location.search); } else { location.replace('/ja' + location.pathname + location.search); }</script>
</head>
<body>
<noscript>${fallbackLinks}</noscript>
</body>
</html>
`;
return createFile(`${siteConfig.outDir}/${route}`, content);
});

await Promise.allSettled(promises);

console.log('I18n redirector generated');
}
41 changes: 3 additions & 38 deletions .vitepress/theme/Layout.vue
Original file line number Diff line number Diff line change
@@ -1,52 +1,17 @@
<template>
<div>
<DefaultTheme.Layout />
<div v-if="!loaded" :class="$style.w"></div>
</div>
<DefaultTheme.Layout />
</template>

<script setup lang="ts">
import { watch, ref } from 'vue';
import { useData, useRoute, inBrowser } from 'vitepress';
import { watch } from 'vue';
import { useData, inBrowser } from 'vitepress';
import DefaultTheme from 'vitepress/theme';
const data = useData();
const route = useRoute();
const loaded = ref(false);
const locales = Object.keys(data.site.value.locales) as string[];
const localesRegex = new RegExp(`^/(${locales.join('|')})`);
const savedLocale = inBrowser ? localStorage.getItem('ais:locale') : null;
if (inBrowser) {
if (!localesRegex.test(route.path)) {
if (savedLocale != null && locales.includes(savedLocale)) {
location.replace('/' + savedLocale + location.pathname + location.search);
} else if (locales.includes(navigator.language.split('-')[0])) {
location.replace('/' + navigator.language.split('-')[0] + location.pathname + location.search);
} else {
location.replace('/ja' + location.pathname + location.search);
}
} else {
loaded.value = true;
}
}
watch(data.lang, (lang) => {
if (inBrowser) {
localStorage.setItem('ais:locale', lang.split('-')[0]);
}
}, { immediate: true });
</script>

<style module>
.w {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: var(--vp-c-bg);
z-index: 9999;
}
</style>

0 comments on commit 435e1ac

Please sign in to comment.