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

Nuxt.js SSR如何提前读取localStorage设置主题避免渲染闪烁

解决方案

核心原理

SSR场景下服务端无法访问浏览器localStorage,所以返回的初始页面默认是浅色主题,客户端hydration完成后才切换到用户保存的主题,时间差导致闪烁。我们只需要在页面开始渲染前,用最早执行的同步脚本先设置好html标签的data-theme属性,就能彻底避免闪烁。

实现步骤

  1. 注入前置内联脚本

在nuxt.config.js中配置head,把读取localStorage设置主题的脚本放在所有资源最前面执行:

// nuxt.config.js
export default {
  head: {
    script: [
      {
        innerHTML: `
          (function() {
            // 优先读用户保存的主题,没有就默认light
            const savedTheme = localStorage.getItem('theme') || 'light';
            document.documentElement.setAttribute('data-theme', savedTheme);
          })();
        `,
        type: 'text/javascript'
      }
    ],
    // 必须加这个配置,避免脚本内容被转义
    __dangerouslyDisableSanitizers: ['script']
  }
}
  1. 调整布局初始值

修改默认布局的data初始化逻辑,直接读取前置脚本已经设置好的html属性作为初始主题值,避免二次修改:

// 默认布局的script部分
export default {
  data: function () {
    return {
      // 客户端侧读已设置的主题,服务端渲染时用默认值不影响
      theme: process.client ? document.documentElement.getAttribute('data-theme') : "light",
    };
  },
  // 剩下的head、methods、created等逻辑保持你原来的写法不变即可
  head() {
    return {
      htmlAttrs: {
        "data-theme": this.theme,
      },
    };
  },
  beforeMount() {
    // 这里原来的读取逻辑可以删掉了,前置脚本已经帮你做好了
  },
  methods: {
    setTheme(theme) {
      this.theme = theme;
      localStorage.setItem("theme", theme);
    },
  },
  created() {
    this.$nuxt.$on("changeTheme", (theme) => {
      this.setTheme(theme);
    });
  },
}

注意事项

这个方案完全不需要阻止页面渲染,内联脚本是浏览器解析HTML时最先执行的同步代码,此时页面还没有开始渲染任何内容,修改data-theme不会产生视觉上的切换,也就不会有闪烁问题。后续用户手动切换主题的逻辑完全不受影响,切换时保存的主题值下次打开页面时会被前置脚本直接读取生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:45:04