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

Nuxt 3 SSR模式下能否实现首页初始站点加载器?

在Nuxt 3 SSR模式下实现首页首次访问专属加载器

核心结论

完全可以实现,不需要切换到CSR,也不会因为hydration过程无法完成这个需求。

实现逻辑

首次访问首页时,Nuxt会通过SSR直接输出完整HTML到客户端。我们可以把加载器直接嵌入这份初始HTML中,等客户端完成Vue应用的hydration(挂载)后,再隐藏并移除加载器即可。路由间导航是客户端内部跳转,不会重新加载整个页面,所以加载器只会在首次访问首页时出现,天然符合需求。

具体实现步骤

1. 定制Nuxt初始HTML模板

在项目根目录创建app.html(如果没有的话),在<body>中先插入加载器的结构和样式,再放置Nuxt渲染的应用内容:

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
    <style>
      #initial-loader {
        position: fixed;
        inset: 0;
        background-color: #ffffff;
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 9999;
        transition: opacity 0.3s ease;
      }
      .spinner {
        width: 48px;
        height: 48px;
        border: 4px solid #e0e0e0;
        border-top-color: #2563eb;
        border-radius: 50%;
        animation: spin 1.2s linear infinite;
      }
      @keyframes spin {
        to { transform: rotate(360deg); }
      }
    </style>
  </head>
  <body {{ BODY_ATTRS }}>
    <!-- 仅在首页添加加载器 -->
    <% if (route.path === '/') { %>
      <div id="initial-loader">
        <div class="spinner"></div>
      </div>
    <% } %>
    {{ APP }}
  </body>
</html>

2. 在客户端挂载完成后移除加载器

创建一个Nuxt插件,监听应用挂载完成的事件,移除加载器:
在plugins/initial-loader.ts中写入:

export default defineNuxtPlugin(() => {
  if (process.client) {
    onMounted(() => {
      const loader = document.getElementById('initial-loader')
      if (loader) {
        // 添加淡出动画后移除
        loader.style.opacity = '0'
        setTimeout(() => loader.remove(), 300)
      }
    })
  }
})

3. 额外校验(可选)

如果需要确保仅首次访问触发(比如用户刷新其他页面时不显示),可以结合localStorage做标记:
修改插件代码:

export default defineNuxtPlugin(() => {
  if (process.client) {
    onMounted(() => {
      const loader = document.getElementById('initial-loader')
      const hasVisited = localStorage.getItem('has-visited-home')
      
      if (loader && !hasVisited) {
        loader.style.opacity = '0'
        setTimeout(() => loader.remove(), 300)
        localStorage.setItem('has-visited-home', 'true')
      } else if (loader) {
        loader.remove()
      }
    })
  }
})

为什么这个方案可行?

加载器是SSR直接输出到初始HTML的,客户端打开页面时会立即显示,不需要等待JS加载或hydration完成。当Vue完成hydration并挂载应用后,再通过客户端代码移除加载器,完全绕开了hydration对加载器显示的限制,同时严格遵循SSR模式,不需要切换到CSR。

内容的提问来源于stack exchange,提问作者Thomas James Thorstensson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:53:22