← 返回日志

Astro 中实现基于浏览器首选语言的自动重定向.

在 Astro 中实现基于浏览器首选语言的自动重定向,主要有以下 4 种主流方案。根据部署架构(SSG 纯静态 vs SSR/Edge 边缘计算)的不同,它们的性能、SEO 影响及维护成本有显著差异。

维度方案一:Astro SSR 中间件 (Middleware)方案二:边缘计算重定向 (Cloudflare Workers / Vercel Edge)方案三:客户端 JS 拦截 (Root index.astro)方案四:HTML <meta> 标签静态重定向
执行位置Node/Edge 运行时(SotA)Edge 节点(CDN 网络最外层)浏览器端(Client Side)浏览器端(Client Side)
适配模式SSR / HybridSSG(纯静态构建)SSG(纯静态构建)SSG(纯静态构建)
用户体验极佳(无白屏/无闪烁)极佳(延迟极低,无白屏)一般(存在毫秒级白屏或闪烁)较差(响应极慢,存在延迟)
SEO 友好度高(支持 302/307 语义与 Vary: Accept-Language)高(支持 302/307 语义)中(搜索引擎可能会忽略 JS 跳转)低(搜索引擎不推荐 meta refresh)
部署成本需启用 Astro SSR 适配器需配置 CDN / Vercel 重定向规则零配置(纯 HTML/JS 输出)零配置(纯 HTML/JS 输出)

核心选型逻辑

  1. 如果你的站点采用 SSG 纯静态导出(部署在 Vercel / Netlify / Cloudflare Pages):
    • 最佳实践:采用 方案二(边缘/平台重定向规则),既保住了纯静态 HTML 的部署成本和极速响应,又能实现 0 闪烁的服务端级重定向。
    • 次优备选:采用 方案三(客户端 JS 降级),实现最简单,适合纯前端轻量处理。
  2. 如果你的 Astro 开启了 SSR 模式(Node.js / Cloudflare SSR):
    • 最佳实践:首选 方案一(Astro 原生 Middleware)。

落地实现细节

落地方案一:Astro Middleware 方式(SSR 架构)

在 src/middleware.ts 中拦截根路径访问:

import { defineMiddleware } from "astro:middleware";

const DEFAULT_LANG = "en";
const SUPPORTED_LANGS = ["zh", "en"];

export const onRequest = defineMiddleware(async ({ request, redirect, url }, next) => {
  // 仅针对根路径 "/" 进行重定向处理
  if (url.pathname === "/" || url.pathname === "") {
    const acceptLanguage = request.headers.get("accept-language") || "";
    
    // 解析 Accept-Language Header(例如: "zh-CN,zh;q=0.9,en;q=0.8")
    let targetLang = DEFAULT_LANG;
    if (acceptLanguage.includes("zh")) {
      targetLang = "zh";
    } else if (acceptLanguage.includes("en")) {
      targetLang = "en";
    }

    // 302/307 重定向至对应语言根路径
    return redirect(`/${targetLang}/`, 307);
  }

  return next();
});

落地方案二:Vercel / Cloudflare Edge 托管层配置(SSG 纯静态架构)

如果你将 Astro 以纯静态方式部署在 Vercel,直接在项目根目录的 vercel.json 中配置原生重定向逻辑,完全不需要改动任何代码:

{
  "redirects": [
    {
      "source": "/",
      "has": [
        {
          "type": "header",
          "key": "accept-language",
          "value": "(?i).*zh.*"
        }
      ],
      "destination": "/zh/",
      "permanent": false
    },
    {
      "source": "/",
      "destination": "/en/",
      "permanent": false
    }
  ]
}

落地方案三:客户端 JS 降级重定向(SSG 纯静态架构)

在 src/pages/index.astro 页面中注入内联 Script,在 DOM 渲染前立即完成跳转:

---
// src/pages/index.astro (作为重定向中转页)
---
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Redirecting...</title>
  <script is:inline>
    (function () {
      // 优先读取用户之前手动选择过的语言 Cookie/LocalStorage,没有则读取浏览器首选语言
      const savedLang = localStorage.getItem("preferred_lang");
      const browserLang = navigator.language || navigator.userLanguage || "";
      
      let targetLang = "en";
      
      if (savedLang && ["zh", "en"].includes(savedLang)) {
        targetLang = savedLang;
      } else if (browserLang.toLowerCase().startsWith("zh")) {
        targetLang = "zh";
      }

      window.location.replace("/" + targetLang + "/");
    })();
  </script>
</head>
<body class="bg-tihubb-900 text-white flex items-center justify-center min-h-screen font-mono text-xs">
  <p>Redirecting to your preferred language...</p>
</body>
</html>

相关文章 / 延续阅读 →