Next.js 14静态导出时如何实现默认语言无URL前缀?
Next.js 14 静态导出下默认语言无URL前缀的多语言实现方案
核心思路
- 同时维护根目录页面和带语言前缀的
[language]目录页面,通过复用核心组件避免代码冗余 - 根目录页面直接渲染默认语言内容,不做任何重定向操作
- 通过
generateStaticParams确保静态导出时生成所有所需的静态文件(根路径+各语言前缀路径)
具体实现步骤
1. 调整目录结构
保留原[language]目录,同时在根目录添加对应的布局和页面文件,最终结构如下:
- layout.tsx # 根目录布局,对应默认语言(如en) - page.tsx # 根目录首页,对应默认语言 - example -- page.tsx # 根目录示例页,对应默认语言 - [language] -- layout.tsx # 带语言前缀的布局 -- page.tsx # 带语言前缀的首页 -- example -- page.tsx # 带语言前缀的示例页 - components -- CoreLayout.tsx # 共享的通用布局组件 -- HomeContent.tsx # 共享的首页内容组件 -- ExampleContent.tsx # 共享的示例页内容组件
2. 复用核心组件
把页面的核心渲染逻辑抽离到共享组件中,根目录和[language]目录的页面仅需传入对应语言参数即可,避免重复代码。
示例:共享内容组件
// components/HomeContent.tsx type Props = { lang: string; }; // 模拟根据语言获取内容的函数,实际可替换为i18n库或本地JSON文件 const getContentByLang = (lang: string) => { return lang === 'en' ? { home: 'Welcome to the homepage' } : { home: 'Willkommen auf der Startseite' }; }; export default function HomeContent({ lang }: Props) { const content = getContentByLang(lang); return <h1>{content.home}</h1>; }
根目录首页(默认语言)
// app/page.tsx import HomeContent from '@/components/HomeContent'; export default function HomePage() { // 直接传入默认语言标识 return <HomeContent lang="en" />; }
带语言前缀的首页
// app/[language]/page.tsx import HomeContent from '@/components/HomeContent'; type Props = { params: { language: string; }; }; export default function LanguageHomePage({ params }: Props) { return <HomeContent lang={params.language} />; } // 生成所有支持的语言参数,确保静态导出时生成对应文件 export async function generateStaticParams() { return [ { language: 'en' }, { language: 'de' }, // 可添加其他支持的语言 ]; }
3. 处理布局逻辑
同样将通用布局抽离为共享组件,根目录和带语言前缀的布局分别传入对应语言参数:
共享布局组件
// components/CoreLayout.tsx type Props = { lang: string; children: React.ReactNode; }; export default function CoreLayout({ lang, children }: Props) { return ( <div> <nav> {/* 语言切换器:默认语言链接到根路径,其他语言链接到对应前缀 */} <a href="/" className={lang === 'en' ? 'active' : ''}>English</a> <a href="/de" className={lang === 'de' ? 'active' : ''}>Deutsch</a> </nav> <main>{children}</main> </div> ); }
根目录布局
// app/layout.tsx import CoreLayout from '@/components/CoreLayout'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> <CoreLayout lang="en">{children}</CoreLayout> </body> </html> ); }
带语言前缀的布局
// app/[language]/layout.tsx import CoreLayout from '@/components/CoreLayout'; type Props = { params: { language: string; }; children: React.ReactNode; }; export default function LanguageLayout({ params, children }: Props) { const lang = params.language; return ( <html lang={lang}> <body> <CoreLayout lang={lang}>{children}</CoreLayout> </body> </html> ); } export async function generateStaticParams() { return [ { language: 'en' }, { language: 'de' }, // 可添加其他支持的语言 ]; }
4. 配置静态导出
在next.config.js中开启静态导出配置:
/** @type {import('next').NextConfig} */ const nextConfig = { output: 'export', // 可选:自定义导出目录,默认是out // distDir: 'out', }; module.exports = nextConfig;
执行npm run build后,out目录会生成所有静态文件:
- 根路径文件(对应默认语言):
index.html、example/index.html - 带语言前缀的文件:
en/index.html、en/example/index.html、de/index.html、de/example/index.html
部署到Cloudflare Pages后,即可实现:
- 访问
/或/example直接加载默认语言内容 - 访问
/de或/de/example加载德语内容 - 无任何重定向操作,完全符合SEO需求
注意事项
- 确保所有页面的
<html>标签lang属性正确设置,根目录页面设为默认语言,带前缀页面设为对应语言 - 语言切换器的链接需严格对应:默认语言指向根路径,其他语言指向对应前缀路径
generateStaticParams需覆盖所有支持的语言,确保静态导出时生成所有所需文件
内容的提问来源于stack exchange,提问作者Lars Flieger
相关产品推荐
相关产品推荐

