You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vite中如何根据请求Cookie为<html>标签添加dir属性

Vite 中根据Cookie设置页面文字方向的实现方案

根据项目渲染模式不同,分两种场景处理:

纯客户端渲染项目(普通SPA/静态站点)

这种场景不需要改Vite配置,直接在入口HTML中插入提前执行的内联脚本即可,核心是要在页面资源加载、DOM渲染前完成dir属性设置,避免布局闪烁。

  • 打开项目根目录的index.html,在<head>标签的最顶部(所有meta、资源引用、业务脚本之前)加入如下代码:
<script>
  // 按需补充你需要支持的RTL语言code
  const RTL_LANG_LIST = ['ar', 'fa', 'he', 'ur', 'ps', 'sd', 'ku', 'yi']
  // 读取指定Cookie值
  const getTargetCookie = (cookieKey) => {
    const regMatch = document.cookie.match(new RegExp('(^| )' + cookieKey + '=([^;]+)'))
    return regMatch ? decodeURIComponent(regMatch[2]) : null
  }
  // 替换成你项目中存储语言标识的Cookie键名
  const currentLang = getTargetCookie('your_site_lang_key')
  const isRTLMode = currentLang && RTL_LANG_LIST.includes(currentLang.split('-')[0])
  // 给html标签设置dir属性
  document.documentElement.dir = isRTLMode ? 'rtl' : 'ltr'
  // 可选:同步设置lang属性,符合无障碍访问要求
  if (currentLang) document.documentElement.lang = currentLang
</script>
  • 注意事项:这段脚本必须内联写在HTML头部最靠前的位置,不要抽成外部JS文件,也不要放到Vue/React等业务框架的挂载逻辑里执行,否则会出现页面先按默认LTR渲染、再跳转为RTL的布局闪动问题。

SSR/同构渲染项目

服务端渲染场景需要在服务端返回HTML时就注入正确的dir属性,避免客户端hydration时出现属性不匹配的报错,同时也能彻底避免闪屏。

  • 首先修改vite.config.js,让开发环境、生产预览环境的服务端逻辑都能根据请求Cookie自动注入dir属性:
import { defineConfig } from 'vite'

// 和客户端保持一致的RTL语言列表
const RTL_LANG_LIST = ['ar', 'fa', 'he', 'ur', 'ps', 'sd', 'ku', 'yi']
// 替换成你项目存储语言的Cookie键名
const LANG_COOKIE_KEY = 'your_site_lang_key'

export default defineConfig({
  server: {
    transformIndexHtml(html, ctx) {
      // 从请求头中解析Cookie
      const cookieHeader = ctx.server.req.headers.cookie || ''
      const langMatch = cookieHeader.match(new RegExp(`${LANG_COOKIE_KEY}=([^;]+)`))
      const currentLang = langMatch ? decodeURIComponent(langMatch[1]) : null
      const isRTLMode = currentLang && RTL_LANG_LIST.includes(currentLang.split('-')[0])
      const dirValue = isRTLMode ? 'rtl' : 'ltr'
      // 替换html标签,注入dir和lang属性
      return html.replace(
        '<html',
        `<html dir="${dirValue}"${currentLang ? ` lang="${currentLang}"` : ''}`
      )
    }
  },
  preview: {
    // 预览模式和开发环境保持一致的处理逻辑
    transformIndexHtml(html, ctx) {
      const cookieHeader = ctx.req.headers.cookie || ''
      const langMatch = cookieHeader.match(new RegExp(`${LANG_COOKIE_KEY}=([^;]+)`))
      const currentLang = langMatch ? decodeURIComponent(langMatch[1]) : null
      const isRTLMode = currentLang && RTL_LANG_LIST.includes(currentLang.split('-')[0])
      const dirValue = isRTLMode ? 'rtl' : 'ltr'
      return html.replace(
        '<html',
        `<html dir="${dirValue}"${currentLang ? ` lang="${currentLang}"` : ''}`
      )
    }
  }
})
  • 生产环境的SSR服务逻辑也要做相同处理:在收到请求时先从Cookie头解析语言,渲染HTML模板时直接把dir属性注入到<html>标签上,不要依赖客户端二次修改。Node服务端的处理示例:
// 生产SSR服务逻辑片段
import fs from 'node:fs'
const htmlTemplate = fs.readFileSync('./dist/index.html', 'utf-8')

app.get('*', (req, res) => {
  const cookieHeader = req.headers.cookie || ''
  const langMatch = cookieHeader.match(new RegExp(`${LANG_COOKIE_KEY}=([^;]+)`))
  const currentLang = langMatch ? decodeURIComponent(langMatch[1]) : null
  const isRTLMode = currentLang && RTL_LANG_LIST.includes(currentLang.split('-')[0])
  const dirValue = isRTLMode ? 'rtl' : 'ltr'
  // 注入dir属性后的最终模板
  const renderedTemplate = htmlTemplate.replace(
    '<html',
    `<html dir="${dirValue}"${currentLang ? ` lang="${currentLang}"` : ''}`
  )
  // 后续走正常的SSR内容渲染、HTML返回流程即可
  // ...
})

额外提示:如果项目引入了第三方UI组件库,记得同步开启组件库自带的RTL适配配置,避免组件样式方向和页面设置不匹配。

内容的提问来源于stack exchange,提问作者jumpo marketing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:21:33