Skip to content

Commit 7778187

Browse files
authored
feat: i18n with sitemap (#2708)
1 parent 2be6858 commit 7778187

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

docs/.vitepress/config.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ export default defineConfig({
1313
cleanUrls: true,
1414

1515
sitemap: {
16-
hostname: 'https://vitepress.dev'
16+
hostname: 'https://vitepress.dev',
17+
transformItems(items) {
18+
return items.filter((item) => !item.url.includes('migration'))
19+
}
1720
},
1821

1922
head: [

src/node/build/generateSitemap.ts

+46-10
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,55 @@ import { task } from '../utils/task'
1414
export async function generateSitemap(siteConfig: SiteConfig) {
1515
if (!siteConfig.sitemap?.hostname) return
1616

17+
const getLastmod = async (url: string) => {
18+
if (!siteConfig.lastUpdated) return undefined
19+
20+
let path = url.replace(/(^|\/)$/, '$1index')
21+
path = path.replace(/(\.html)?$/, '.md')
22+
path = siteConfig.rewrites.inv[path] || path
23+
24+
return (await getGitTimestamp(path)) || undefined
25+
}
26+
1727
await task('generating sitemap', async () => {
18-
let items: SitemapItem[] = await Promise.all(
19-
siteConfig.pages.map(async (page) => {
20-
//
21-
let url = siteConfig.rewrites.map[page] || page
22-
url = url.replace(/(^|\/)index\.md$/, '$1')
23-
url = url.replace(/\.md$/, siteConfig.cleanUrls ? '' : '.html')
24-
25-
const lastmod = siteConfig.lastUpdated && (await getGitTimestamp(page))
26-
return lastmod ? { url, lastmod } : { url }
28+
const locales = siteConfig.userConfig.locales || {}
29+
const filteredLocales = Object.keys(locales).filter(
30+
(locale) => locales[locale].lang && locale !== 'root'
31+
)
32+
const defaultLang =
33+
locales?.root?.lang || siteConfig.userConfig.lang || 'en-US'
34+
35+
const pages = siteConfig.pages.map(
36+
(page) => siteConfig.rewrites.map[page] || page
37+
)
38+
39+
const groupedPages: Record<string, { lang: string; url: string }[]> = {}
40+
pages.forEach((page) => {
41+
const locale = page.split('/')[0]
42+
const lang = locales[locale]?.lang || defaultLang
43+
44+
let url = page.replace(/(^|\/)index\.md$/, '$1')
45+
url = url.replace(/\.md$/, siteConfig.cleanUrls ? '' : '.html')
46+
if (filteredLocales.includes(locale)) page = page.slice(locale.length + 1)
47+
48+
if (!groupedPages[page]) groupedPages[page] = []
49+
groupedPages[page].push({ url, lang })
50+
})
51+
52+
const _items = await Promise.all(
53+
Object.values(groupedPages).map(async (pages) => {
54+
if (pages.length < 2)
55+
return { url: pages[0].url, lastmod: await getLastmod(pages[0].url) }
56+
57+
return await Promise.all(
58+
pages.map(async ({ url }) => {
59+
return { url, lastmod: await getLastmod(url), links: pages }
60+
})
61+
)
2762
})
2863
)
29-
items = items.sort((a, b) => a.url.localeCompare(b.url))
64+
65+
let items: SitemapItem[] = _items.flat()
3066
items = (await siteConfig.sitemap?.transformItems?.(items)) || items
3167

3268
const sitemapStream = new SitemapStream(siteConfig.sitemap)

src/node/utils/getGitTimestamp.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { spawn } from 'cross-spawn'
2+
import fs from 'fs-extra'
23
import { basename, dirname } from 'path'
34

45
const cache = new Map<string, number>()
@@ -9,6 +10,7 @@ export function getGitTimestamp(file: string) {
910

1011
return new Promise<number>((resolve, reject) => {
1112
const cwd = dirname(file)
13+
if (!fs.existsSync(cwd)) return resolve(0)
1214
const fileName = basename(file)
1315
const child = spawn('git', ['log', '-1', '--pretty="%ai"', fileName], {
1416
cwd

0 commit comments

Comments
 (0)