
在 Nuxt 3 中,若插件仅通过 defineNuxtPlugin 在服务端注册(如 headTags.server.js),则 $setTags 等 $ 方法不会在客户端可用;直接调用将导致 TypeError。解决方案是显式检查 process.server,确保仅在服务端执行。
在 nuxt 3 中,若插件仅通过 `definenuxtplugin` 在服务端注册(如 `headtags.server.js`),则 `$settags` 等 `$` 方法不会在客户端可用;直接调用将导致 `typeerror`。解决方案是显式检查 `process.server`,确保仅在服务端执行。
Nuxt 3 的插件具有明确的服务端/客户端作用域区分。当你命名插件文件为 headTags.server.js 时,Nuxt 会仅在服务端环境加载并执行该插件,这意味着:
- nuxtApp.provide("setTags", ...) 只在 Node.js 进程中运行;
- $setTags 仅存在于服务端上下文(SSR 渲染阶段),不会被序列化或注入到客户端 Vue 实例中;
- 在 <script setup> 中无条件调用 $setTags(data.value),会导致客户端 hydration 阶段尝试访问未定义的 $setTags,从而抛出 TypeError: $setTags is not a function。</script>
✅ 正确做法:始终用 process.server 守卫调用
<script setup>
const { $setTags } = useNuxtApp()
const { find } = useStrapi4()
const { data } = await useAsyncData(
"posts",
async () => {
const response = await find("posts", { filters: { slug: "hello-world" } })
return response.data?.[0]?.attributes || null
}
)
// ✅ 安全调用:仅在服务端执行
if (process.server) {
$setTags(data.value)
}
</script>
⚠️ 注意事项:
- 不要将 $setTags() 移入 useAsyncData 的回调内部(如 return data; $setTags(...)),因为该回调在服务端和客户端均会执行(取决于数据缓存状态),且 data 在客户端可能为 ref(null) 或未响应式;
- 若需在客户端动态更新 SEO(如 SPA 导航后),应改用 useHead 或 useSeoMeta 组合式 API,而非依赖服务端插件;
- 插件命名规则很重要:.server. 后缀是 Nuxt 自动分流的关键,误写为 .client. 或无后缀会导致行为不符合预期。
? 总结:Nuxt 3 的服务端插件不是“全局函数”,而是 SSR 上下文专属能力。拥抱 process.server 是保障服务端逻辑不泄漏到客户端的最简单、最可靠方式。










