Nuxt插件未在初始加载时添加Google Maps脚本标签问题
问题重现
我在使用Nuxt客户端插件googleMap.client.ts时遇到问题:插件本应在页面初始加载时添加Google Maps API脚本标签,但首次加载时完全不生效,只有刷新页面后脚本才会被正确添加,插件功能正常。原插件代码如下:
export default defineNuxtPlugin((nuxtApp) => { let config = useRuntimeConfig(); if (window.location.origin !== "<my-origin>") { config.googleMapKey = config.googleMapDevKey; } const script = document.createElement("script"); script.src = `maps.googleapis.com/maps/api/js?key=${config.googleMapKey}&libraries=places,drawing,geometry&callback=initMap`; script.async = true; script.defer = true; document.head.appendChild(script); });
我怀疑问题出在useRuntimeConfig的使用上,请问如何让插件在初始加载时就正常工作?
修复方案及原因分析
你的问题主要来自三个方面:直接修改useRuntimeConfig返回的响应式对象、手动操作DOM的时机问题,以及脚本URL缺少协议头。以下是修复后的代码:
export default defineNuxtPlugin(() => { const config = useRuntimeConfig(); // 单独存储最终使用的API Key,不修改原始config对象 const targetApiKey = window.location.origin !== "<my-origin>" ? config.googleMapDevKey : config.googleMapKey; // 使用Nuxt官方的useHead管理头部脚本,确保注入时机正确 useHead({ script: [ { src: `https://maps.googleapis.com/maps/api/js?key=${targetApiKey}&libraries=places,drawing,geometry&callback=initMap`, async: true, defer: true } ] }); });
关键修复点说明:
避免修改
useRuntimeConfig返回的对象useRuntimeConfig返回的是Nuxt的响应式配置对象,直接修改它可能会破坏配置的初始化流程,导致首次加载时无法正确读取到配置值。改用独立变量存储最终的API Key,能避免这个问题。使用
useHead替代手动DOM操作
Nuxt的客户端渲染有自己的生命周期,直接调用document.createElement和appendChild可能会在DOM尚未准备好的时机执行,导致脚本无法被正确注入。useHead是Nuxt官方提供的头部资源管理工具,会自动在合适的时机将脚本添加到页面中,适配SSR和客户端渲染场景。补全脚本URL的
https://协议头
原代码中的脚本URL缺少协议头,浏览器会将其当作相对路径处理,必然导致资源加载失败。补全协议头后,脚本才能被正确请求。
额外注意事项
确保initMap回调函数在全局作用域下可访问,否则Google Maps API加载完成后会找不到该函数,导致功能异常。你可以在客户端插件中或者全局脚本里定义这个函数:
// 例如在插件中添加全局回调 if (typeof window !== 'undefined') { window.initMap = () => { // 你的地图初始化逻辑 }; }
内容的提问来源于stack exchange,提问作者Ali Raza

