背景
提到Next.js,就不得不提及SSR、SSG等相关的前端技术。
SSR(Server-Side Rendering,服务器端渲染),是指在服务器端将组件呈现为HTML字符串,然后在浏览器中进行客户端渲染。这可以提高页面的加载速度和SEO性能,并提供更好的用户体验。
SSG(Static Site Generation,静态站点生成),是指在构建时生成静态HTML文件,并将它们存储在服务器上,以便在用户请求页面时立即提供响应。这可以大大减少网络请求时间并提高页面加载速度。
另外,如果网站还需要支持国际化,即多语言切换,那又该如何实现呢?
探索
最初,在Next.js官网文档中欣喜地发现,从“v10.0.0”开始,Next.js内置了国际化(i18n)支持。于是,马上整起来......可是,跟着文档一步一步往下走着走着,一碰冷水泼了过来——这个国际化路由不支持SSG,就像Next.js的中间件(middleware)一样。
于是,要么放弃SSG,要么另寻出路实现多语言的支持。经过对项目规模、部署成本等方面的考虑,决定坚持SSG,放弃Next.js内置的 i18n。通过引入Nginx对“accept-language”的处理,配合Next.js,同时实现SSG与国际化。
实现
1)Next.js页面
定义动态路由的静态页面,例如 pages/[lang]/index.tsx。
export async function getStaticPaths() {
return {
paths: [
{ params: { lang: 'zh-CN' } },
{ params: { lang: 'en-US' } },
]
}
}
export async function getStaticProps() {
return { props: {} }
}
export default function Index() {
const { query: { lang } } = useRouter()
return (
<>
{/* ... */}
</>
)
}
使用“next build && next export”编译并生成静态页面文件。建议在 next.config.js 里加上如下配置。
trailingSlash: true
这样,路由为“/zh-CN”和“/en-US”的静态页面就生成好了,可是访问根路由“/”咋办呢?
2)Nginx处理“accept-language”
既然,既不能利用Next.js内置的 i18n 来实现语言识别与重定向,又不能像CSR(浏览器端渲染)项目可以轻松获取浏览器的语言信息,那就利用Nginx来实现。检测请求中携带的消息头“accept-language”,如果开头是“zh”,则将“/”重定向到“/zh-CN”,否则“/en-US”。
server {
listen 80;
server_name xxx.xxx;
location / {
root /home/html/;
index index.html index.htm;
autoindex off;
if ($http_accept_language ~* ^zh) {
rewrite ^/$ /zh-CN permanent;
}
if ($http_accept_language !~* ^zh) {
rewrite ^/$ /en-US permanent;
}
}
}
结束语
对于需要支持国际化的SSR网站,究竟是采用本文介绍的SSG+Nginx,还是非SSG(比如使用“next start”部署)+i18n,主要是看部署方式。SSG+Nginx 更适合于不希望独立部署的小型项目。