Skip to content

Commit 41ff746

Browse files
Copilothuangyiirene
andcommitted
Add root page with language detection and redirect
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent 619cf6b commit 41ff746

1 file changed

Lines changed: 63 additions & 0 deletions

File tree

packages/site/app/page.tsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { redirect } from 'next/navigation';
2+
import { headers } from 'next/headers';
3+
import { siteConfig } from '@/lib/site-config';
4+
5+
/**
6+
* Root page that redirects to the appropriate language version
7+
* Detects user's preferred language from Accept-Language header
8+
*/
9+
export default async function RootPage() {
10+
const headersList = await headers();
11+
const acceptLanguage = headersList.get('accept-language') || '';
12+
13+
// Get configured languages and default language from site config
14+
const availableLanguages = siteConfig.i18n.languages;
15+
const defaultLanguage = siteConfig.i18n.defaultLanguage;
16+
17+
// Parse Accept-Language header to find the best match
18+
const preferredLanguage = detectPreferredLanguage(acceptLanguage, availableLanguages);
19+
20+
// Redirect to the detected or default language
21+
const targetLanguage = preferredLanguage || defaultLanguage;
22+
redirect(`/${targetLanguage}/docs`);
23+
}
24+
25+
/**
26+
* Detect preferred language from Accept-Language header
27+
* Returns the first available language that matches user preferences
28+
*/
29+
function detectPreferredLanguage(
30+
acceptLanguage: string,
31+
availableLanguages: string[]
32+
): string | null {
33+
if (!acceptLanguage) {
34+
return null;
35+
}
36+
37+
// Parse Accept-Language header
38+
// Example: "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"
39+
const languages = acceptLanguage
40+
.split(',')
41+
.map(lang => {
42+
const [code, qValue] = lang.trim().split(';q=');
43+
const quality = qValue ? parseFloat(qValue) : 1.0;
44+
// Extract primary language code (e.g., "en" from "en-US")
45+
const primaryCode = code.split('-')[0].toLowerCase();
46+
return { code: primaryCode, quality };
47+
})
48+
.sort((a, b) => b.quality - a.quality); // Sort by quality (preference)
49+
50+
// Find first matching language that is available
51+
for (const { code } of languages) {
52+
// Check if the language code matches any available language
53+
if (availableLanguages.includes(code)) {
54+
return code;
55+
}
56+
// Special case: map 'zh' to 'cn'
57+
if (code === 'zh' && availableLanguages.includes('cn')) {
58+
return 'cn';
59+
}
60+
}
61+
62+
return null;
63+
}

0 commit comments

Comments
 (0)