@nuxt/scripts 0.13.2 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +9 -0
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/{iNmKC7TZ.js → Bdf7Qtwg.js} +1 -1
  5. package/dist/client/_nuxt/CoyZWCgl.js +162 -0
  6. package/dist/client/_nuxt/{Bje-0OHL.js → DTDyDxvR.js} +1 -1
  7. package/dist/client/_nuxt/{rttsH3SL.js → Ds1k3yKJ.js} +1 -1
  8. package/dist/client/_nuxt/builds/latest.json +1 -1
  9. package/dist/client/_nuxt/builds/meta/62574f80-71d4-4f9e-8b96-145c85230d99.json +1 -0
  10. package/dist/client/_nuxt/error-404.D45Vtjcx.css +1 -0
  11. package/dist/client/_nuxt/error-500.BOm1rWQf.css +1 -0
  12. package/dist/client/index.html +1 -1
  13. package/dist/module.d.mts +26 -2
  14. package/dist/module.json +1 -1
  15. package/dist/module.mjs +98 -54
  16. package/dist/registry.mjs +53 -0
  17. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +29 -1
  18. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +35 -10
  19. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +29 -1
  20. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +20 -8
  21. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +2 -2
  22. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +20 -8
  23. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +7 -1
  24. package/dist/runtime/components/ScriptCrisp.d.vue.ts +1 -1
  25. package/dist/runtime/components/ScriptCrisp.vue.d.ts +1 -1
  26. package/dist/runtime/components/ScriptIntercom.d.vue.ts +1 -1
  27. package/dist/runtime/components/ScriptIntercom.vue.d.ts +1 -1
  28. package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +2 -2
  29. package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +2 -2
  30. package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +12 -1
  31. package/dist/runtime/components/ScriptYouTubePlayer.vue +41 -16
  32. package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +12 -1
  33. package/dist/runtime/composables/useScript.js +10 -0
  34. package/dist/runtime/npm-script-stub.d.ts +20 -0
  35. package/dist/runtime/npm-script-stub.js +73 -0
  36. package/dist/runtime/registry/google-recaptcha.d.ts +27 -0
  37. package/dist/runtime/registry/google-recaptcha.js +45 -0
  38. package/dist/runtime/registry/google-sign-in.d.ts +84 -0
  39. package/dist/runtime/registry/google-sign-in.js +50 -0
  40. package/dist/runtime/registry/google-tag-manager.d.ts +3 -1
  41. package/dist/runtime/registry/google-tag-manager.js +15 -5
  42. package/dist/runtime/registry/matomo-analytics.js +1 -1
  43. package/dist/runtime/registry/plausible-analytics.js +8 -6
  44. package/dist/runtime/registry/posthog.d.ts +26 -0
  45. package/dist/runtime/registry/posthog.js +92 -0
  46. package/dist/runtime/registry/rybbit-analytics.js +38 -8
  47. package/dist/runtime/registry/tiktok-pixel.d.ts +43 -0
  48. package/dist/runtime/registry/tiktok-pixel.js +43 -0
  49. package/dist/runtime/server/google-static-maps-proxy.d.ts +2 -0
  50. package/dist/runtime/server/google-static-maps-proxy.js +54 -0
  51. package/dist/runtime/types.d.ts +13 -1
  52. package/dist/runtime/utils.d.ts +2 -1
  53. package/dist/runtime/utils.js +9 -0
  54. package/package.json +25 -19
  55. package/dist/client/_nuxt/DMut0W-e.js +0 -162
  56. package/dist/client/_nuxt/builds/meta/5e0206fe-a683-423c-8d59-2596d0b16fee.json +0 -1
  57. package/dist/client/_nuxt/error-404.B0ZhSNwd.css +0 -1
  58. package/dist/client/_nuxt/error-500.D4MdgPaC.css +0 -1
@@ -1 +1 @@
1
- import{u as a,f as s,h as u,i as r,g as h}from"./DMut0W-e.js";function i(t){const e=t||s();return e.ssrContext?.head||e.runWithContext(()=>{if(u()){const n=r(h);if(!n)throw new Error("[nuxt] [unhead] Missing Unhead instance.");return n}})}function d(t,e={}){const n=e.head||i(e.nuxt);return a(t,{head:n,...e})}export{d as u};
1
+ import{u as a,f as s,h as u,i as r,g as h}from"./CoyZWCgl.js";function i(t){const e=t||s();return e.ssrContext?.head||e.runWithContext(()=>{if(u()){const n=r(h);if(!n)throw new Error("[nuxt] [unhead] Missing Unhead instance.");return n}})}function d(t,e={}){const n=e.head||i(e.nuxt);return a(t,{head:n,...e})}export{d as u};
@@ -1 +1 @@
1
- import{_ as o,c as s,o as a,a as t,t as r}from"./DMut0W-e.js";import{u as i}from"./Bje-0OHL.js";const u={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},c={class:"max-w-520px text-center"},l=["textContent"],d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Internal server error"},description:{type:String,default:"This page is temporarily unavailable."},refresh:{type:String,default:"Refresh this page"}},setup(e){const n=e;return i({title:`${n.statusCode} - ${n.statusMessage} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(g,h)=>(a(),s("div",u,[t("div",c,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:r(e.statusCode)},null,8,l),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:r(e.statusMessage)},null,8,d),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:r(e.description)},null,8,p)])]))}},x=o(f,[["__scopeId","data-v-db4fc13b"]]);export{x as default};
1
+ import{_ as o,c as s,o as a,a as t,t as r}from"./CoyZWCgl.js";import{u as i}from"./DTDyDxvR.js";const u={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},l={class:"max-w-520px text-center"},c=["textContent"],d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Internal server error"},description:{type:String,default:"This page is temporarily unavailable."},refresh:{type:String,default:"Refresh this page"}},setup(e){const n=e;return i({title:`${n.statusCode} - ${n.statusMessage} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(g,h)=>(a(),s("div",u,[t("div",l,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:r(e.statusCode)},null,8,c),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:r(e.statusMessage)},null,8,d),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:r(e.description)},null,8,p)])]))}},x=o(f,[["__scopeId","data-v-39d92261"]]);export{x as default};
@@ -1 +1 @@
1
- {"id":"5e0206fe-a683-423c-8d59-2596d0b16fee","timestamp":1766211441196}
1
+ {"id":"62574f80-71d4-4f9e-8b96-145c85230d99","timestamp":1769157046085}
@@ -0,0 +1 @@
1
+ {"id":"62574f80-71d4-4f9e-8b96-145c85230d99","timestamp":1769157046085,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -0,0 +1 @@
1
+ .grid[data-v-75dfa5e6]{display:grid}.mb-2[data-v-75dfa5e6]{margin-bottom:.5rem}.mb-4[data-v-75dfa5e6]{margin-bottom:1rem}.max-w-520px[data-v-75dfa5e6]{max-width:520px}.min-h-screen[data-v-75dfa5e6]{min-height:100vh}.w-full[data-v-75dfa5e6]{width:100%}.flex[data-v-75dfa5e6]{display:flex}.place-content-center[data-v-75dfa5e6]{place-content:center}.items-center[data-v-75dfa5e6]{align-items:center}.justify-center[data-v-75dfa5e6]{justify-content:center}.overflow-hidden[data-v-75dfa5e6]{overflow:hidden}.bg-white[data-v-75dfa5e6]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2[data-v-75dfa5e6]{padding-left:.5rem;padding-right:.5rem}.text-center[data-v-75dfa5e6]{text-align:center}.text-\[80px\][data-v-75dfa5e6]{font-size:80px}.text-2xl[data-v-75dfa5e6]{font-size:1.5rem;line-height:2rem}.text-sm[data-v-75dfa5e6]{font-size:.875rem;line-height:1.25rem}.text-\[\#020420\][data-v-75dfa5e6]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\[\#64748B\][data-v-75dfa5e6]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.hover\:text-\[\#00DC82\][data-v-75dfa5e6]:hover{--un-text-opacity:1;color:rgb(0 220 130/var(--un-text-opacity))}.font-medium[data-v-75dfa5e6]{font-weight:500}.font-semibold[data-v-75dfa5e6]{font-weight:600}.leading-none[data-v-75dfa5e6]{line-height:1}.tracking-wide[data-v-75dfa5e6]{letter-spacing:.025em}.font-sans[data-v-75dfa5e6]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.tabular-nums[data-v-75dfa5e6]{--un-numeric-spacing:tabular-nums;font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)}.underline[data-v-75dfa5e6]{text-decoration-line:underline}.underline-offset-3[data-v-75dfa5e6]{text-underline-offset:3px}.antialiased[data-v-75dfa5e6]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\:bg-\[\#020420\][data-v-75dfa5e6]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\:text-white[data-v-75dfa5e6]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\:text-\[110px\][data-v-75dfa5e6]{font-size:110px}.sm\:text-3xl[data-v-75dfa5e6]{font-size:1.875rem;line-height:2.25rem}}
@@ -0,0 +1 @@
1
+ .grid[data-v-39d92261]{display:grid}.mb-2[data-v-39d92261]{margin-bottom:.5rem}.mb-4[data-v-39d92261]{margin-bottom:1rem}.max-w-520px[data-v-39d92261]{max-width:520px}.min-h-screen[data-v-39d92261]{min-height:100vh}.place-content-center[data-v-39d92261]{place-content:center}.overflow-hidden[data-v-39d92261]{overflow:hidden}.bg-white[data-v-39d92261]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2[data-v-39d92261]{padding-left:.5rem;padding-right:.5rem}.text-center[data-v-39d92261]{text-align:center}.text-\[80px\][data-v-39d92261]{font-size:80px}.text-2xl[data-v-39d92261]{font-size:1.5rem;line-height:2rem}.text-\[\#020420\][data-v-39d92261]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\[\#64748B\][data-v-39d92261]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.font-semibold[data-v-39d92261]{font-weight:600}.leading-none[data-v-39d92261]{line-height:1}.tracking-wide[data-v-39d92261]{letter-spacing:.025em}.font-sans[data-v-39d92261]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.tabular-nums[data-v-39d92261]{--un-numeric-spacing:tabular-nums;font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)}.antialiased[data-v-39d92261]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\:bg-\[\#020420\][data-v-39d92261]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\:text-white[data-v-39d92261]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\:text-\[110px\][data-v-39d92261]{font-size:110px}.sm\:text-3xl[data-v-39d92261]{font-size:1.875rem;line-height:2.25rem}}
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.BjfcJo5q.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DMut0W-e.js"><script type="module" src="/__nuxt-scripts/_nuxt/DMut0W-e.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1766211445685,false]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"}}},app:{baseURL:"/__nuxt-scripts",buildId:"5e0206fe-a683-423c-8d59-2596d0b16fee",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__nuxt-scripts/_nuxt/entry.BjfcJo5q.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/CoyZWCgl.js"><script type="module" src="/__nuxt-scripts/_nuxt/CoyZWCgl.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{"nuxt-scripts":{version:"",defaultScriptOptions:{trigger:"onNuxtReady"},googleStaticMapsProxy:""}},app:{baseURL:"/__nuxt-scripts",buildId:"62574f80-71d4-4f9e-8b96-145c85230d99",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1769157050846,false]</script></body></html>
package/dist/module.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import * as nuxt_schema from 'nuxt/schema';
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { FetchOptions } from 'ofetch';
3
3
  import { NuxtConfigScriptRegistry, NuxtUseScriptOptionsSerializable, NuxtUseScriptInput, RegistryScripts } from '../dist/runtime/types.js';
4
4
 
@@ -44,6 +44,30 @@ interface ModuleOptions {
44
44
  * @default 604800000 (7 days)
45
45
  */
46
46
  cacheMaxAge?: number;
47
+ /**
48
+ * Enable automatic integrity hash generation for bundled scripts.
49
+ * When enabled, calculates SRI (Subresource Integrity) hash and injects
50
+ * integrity attribute along with crossorigin="anonymous".
51
+ *
52
+ * @default false
53
+ */
54
+ integrity?: boolean | 'sha256' | 'sha384' | 'sha512';
55
+ };
56
+ /**
57
+ * Google Static Maps proxy configuration.
58
+ * Proxies static map images through your server to fix CORS issues and enable caching.
59
+ */
60
+ googleStaticMapsProxy?: {
61
+ /**
62
+ * Enable proxying Google Static Maps through your own origin.
63
+ * @default false
64
+ */
65
+ enabled?: boolean;
66
+ /**
67
+ * Cache duration for static map images in seconds.
68
+ * @default 3600 (1 hour)
69
+ */
70
+ cacheMaxAge?: number;
47
71
  };
48
72
  /**
49
73
  * Whether the module is enabled.
@@ -61,7 +85,7 @@ interface ModuleOptions {
61
85
  interface ModuleHooks {
62
86
  'scripts:registry': (registry: RegistryScripts) => void | Promise<void>;
63
87
  }
64
- declare const _default: nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
88
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
65
89
 
66
90
  export { _default as default };
67
91
  export type { ModuleHooks, ModuleOptions };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16"
6
6
  },
7
- "version": "0.13.2",
7
+ "version": "1.0.0-beta.1",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,7 +1,8 @@
1
- import { useNuxt, extendViteConfig, useLogger, addDevServerHandler, tryUseNuxt, logger as logger$1, defineNuxtModule, createResolver, addImports, addComponentsDir, addTemplate, addTypeTemplate, addPluginTemplate, addBuildPlugin, hasNuxtModule } from '@nuxt/kit';
1
+ import { useNuxt, extendViteConfig, useLogger, addDevServerHandler, tryUseNuxt, logger as logger$1, addTypeTemplate, defineNuxtModule, createResolver, addImports, addComponentsDir, addTemplate, addPluginTemplate, addBuildPlugin, addServerHandler, hasNuxtModule } from '@nuxt/kit';
2
2
  import { defu } from 'defu';
3
3
  import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
4
4
  import { existsSync } from 'node:fs';
5
+ import { createHash } from 'node:crypto';
5
6
  import fsp from 'node:fs/promises';
6
7
  import { createUnplugin } from 'unplugin';
7
8
  import MagicString from 'magic-string';
@@ -149,6 +150,10 @@ function isJS(id) {
149
150
  }
150
151
 
151
152
  const SEVEN_DAYS_IN_MS = 7 * 24 * 60 * 60 * 1e3;
153
+ function calculateIntegrity(content, algorithm = "sha384") {
154
+ const hash = createHash(algorithm).update(content).digest("base64");
155
+ return `${algorithm}-${hash}`;
156
+ }
152
157
  async function isCacheExpired(storage, filename, cacheMaxAge = SEVEN_DAYS_IN_MS) {
153
158
  const metaKey = `bundle-meta:${filename}`;
154
159
  const meta = await storage.getItem(metaKey);
@@ -173,7 +178,7 @@ function normalizeScriptData(src, assetsBaseURL = "/_scripts") {
173
178
  return { url: src };
174
179
  }
175
180
  async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
176
- const { src, url, filename, forceDownload } = opts;
181
+ const { src, url, filename, forceDownload, integrity } = opts;
177
182
  if (src === url || !filename) {
178
183
  return;
179
184
  }
@@ -184,13 +189,15 @@ async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
184
189
  const cacheKey = `bundle:${filename}`;
185
190
  const shouldUseCache = !forceDownload && await storage.hasItem(cacheKey) && !await isCacheExpired(storage, filename, cacheMaxAge);
186
191
  if (shouldUseCache) {
187
- const res2 = await storage.getItemRaw(cacheKey);
192
+ const cachedContent = await storage.getItemRaw(cacheKey);
193
+ const meta = await storage.getItem(`bundle-meta:${filename}`);
188
194
  renderedScript.set(url, {
189
- content: res2,
190
- size: res2.length / 1024,
195
+ content: cachedContent,
196
+ size: cachedContent.length / 1024,
191
197
  encoding: "utf-8",
192
198
  src,
193
- filename
199
+ filename,
200
+ integrity: meta?.integrity
194
201
  });
195
202
  return;
196
203
  }
@@ -205,20 +212,23 @@ async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
205
212
  size = contentLength ? Number(contentLength) / 1024 : 0;
206
213
  return Buffer.from(r._data || await r.arrayBuffer());
207
214
  });
215
+ const integrityHash = integrity && res ? calculateIntegrity(res, integrity === true ? "sha384" : integrity) : void 0;
208
216
  await storage.setItemRaw(`bundle:${filename}`, res);
209
217
  await storage.setItem(`bundle-meta:${filename}`, {
210
218
  timestamp: Date.now(),
211
219
  src,
212
- filename
220
+ filename,
221
+ integrity: integrityHash
213
222
  });
214
223
  size = size || res.length / 1024;
215
- logger.info(`Downloading script ${colors.gray(`${src} \u2192 ${filename} (${size.toFixed(2)} kB ${encoding})`)}`);
224
+ logger.info(`Downloading script ${colors.gray(`${src} \u2192 ${filename} (${size.toFixed(2)} kB ${encoding})${integrityHash ? ` [${integrityHash.slice(0, 15)}...]` : ""}`)}`);
216
225
  renderedScript.set(url, {
217
226
  content: res,
218
227
  size,
219
228
  encoding,
220
229
  src,
221
- filename
230
+ filename,
231
+ integrity: integrityHash
222
232
  });
223
233
  }
224
234
  }
@@ -374,7 +384,7 @@ function NuxtScriptBundleTransformer(options = {
374
384
  const { url: _url, filename } = normalizeScriptData(src, options.assetsBaseURL);
375
385
  let url = _url;
376
386
  try {
377
- await downloadScript({ src, url, filename, forceDownload }, renderedScript, options.fetchOptions, options.cacheMaxAge);
387
+ await downloadScript({ src, url, filename, forceDownload, integrity: options.integrity }, renderedScript, options.fetchOptions, options.cacheMaxAge);
378
388
  } catch (e) {
379
389
  if (options.fallbackOnSrcOnBundleFail) {
380
390
  logger.warn(`[Nuxt Scripts: Bundle Transformer] Failed to bundle ${src}. Fallback to remote loading.`);
@@ -394,9 +404,20 @@ function NuxtScriptBundleTransformer(options = {
394
404
  else
395
405
  logger.warn(`[Nuxt Scripts: Bundle Transformer] Failed to bundle ${src}.`);
396
406
  }
407
+ const scriptMeta = renderedScript.get(url);
408
+ const integrityHash = scriptMeta instanceof Error ? void 0 : scriptMeta?.integrity;
397
409
  if (scriptSrcNode) {
398
- s.overwrite(scriptSrcNode.start, scriptSrcNode.end, `'${url}'`);
410
+ if (integrityHash && fnName === "useScript" && node.arguments[0]?.type === "Literal") {
411
+ s.overwrite(scriptSrcNode.start, scriptSrcNode.end, `{ src: '${url}', integrity: '${integrityHash}', crossorigin: 'anonymous' }`);
412
+ } else if (integrityHash && fnName === "useScript" && node.arguments[0]?.type === "ObjectExpression") {
413
+ s.overwrite(scriptSrcNode.start, scriptSrcNode.end, `'${url}'`);
414
+ const objArg = node.arguments[0];
415
+ s.appendLeft(objArg.end - 1, `, integrity: '${integrityHash}', crossorigin: 'anonymous'`);
416
+ } else {
417
+ s.overwrite(scriptSrcNode.start, scriptSrcNode.end, `'${url}'`);
418
+ }
399
419
  } else {
420
+ const integrityProps = integrityHash ? `, integrity: '${integrityHash}', crossorigin: 'anonymous'` : "";
400
421
  if (node.arguments[0]) {
401
422
  const optionsNode = node.arguments[0];
402
423
  const scriptInputProperty = optionsNode.properties.find(
@@ -408,16 +429,19 @@ function NuxtScriptBundleTransformer(options = {
408
429
  const srcProperty = scriptInput.properties.find(
409
430
  (p) => p.key?.name === "src" || p.key?.value === "src"
410
431
  );
411
- if (srcProperty)
432
+ if (srcProperty) {
412
433
  s.overwrite(srcProperty.value.start, srcProperty.value.end, `'${url}'`);
413
- else
414
- s.appendRight(scriptInput.end, `, src: '${url}'`);
434
+ if (integrityHash)
435
+ s.appendLeft(scriptInput.end - 1, integrityProps);
436
+ } else {
437
+ s.appendRight(scriptInput.end - 1, `, src: '${url}'${integrityProps}`);
438
+ }
415
439
  }
416
440
  } else {
417
- s.appendRight(node.arguments[0].start + 1, ` scriptInput: { src: '${url}' }, `);
441
+ s.appendRight(node.arguments[0].start + 1, ` scriptInput: { src: '${url}'${integrityProps} }, `);
418
442
  }
419
443
  } else {
420
- s.appendRight(node.callee.end, `({ scriptInput: { src: '${url}' } })`);
444
+ s.appendRight(node.callee.end, `({ scriptInput: { src: '${url}'${integrityProps} } })`);
421
445
  }
422
446
  }
423
447
  }
@@ -531,6 +555,44 @@ function NuxtScriptsCheckScripts() {
531
555
  });
532
556
  }
533
557
 
558
+ function registerTypeTemplates({ nuxt, config, newScripts }) {
559
+ addTypeTemplate({
560
+ filename: "types/nuxt-scripts-augments.d.ts",
561
+ getContents: () => {
562
+ const typesPath = relative(
563
+ resolve(nuxt.options.rootDir, nuxt.options.buildDir, "types"),
564
+ resolve("runtime/types")
565
+ );
566
+ let augments = `// Generated by @nuxt/scripts
567
+ declare module '#app' {
568
+ interface NuxtApp {
569
+ $scripts: Record<${[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`).concat(["string"]).join(" | ")}, import('#nuxt-scripts/types').UseScriptContext<any> | undefined>
570
+ _scripts: Record<string, import('#nuxt-scripts/types').NuxtDevToolsScriptInstance>
571
+ }
572
+ interface RuntimeNuxtHooks {
573
+ 'scripts:updated': (ctx: { scripts: Record<string, import('#nuxt-scripts/types').NuxtDevToolsScriptInstance> }) => void | Promise<void>
574
+ }
575
+ }
576
+ `;
577
+ if (newScripts.length) {
578
+ augments += `
579
+ declare module '#nuxt-scripts/types' {
580
+ type _NuxtScriptOptions = Omit<import('${typesPath}').NuxtUseScriptOptions, 'use' | 'beforeInit'>
581
+ interface ScriptRegistry {
582
+ ${newScripts.map((i) => {
583
+ const key = i.import.name.replace("useScript", "");
584
+ const keyLcFirst = key.substring(0, 1).toLowerCase() + key.substring(1);
585
+ return ` ${keyLcFirst}?: import('${i.import.from}').${key}Input | [import('${i.import.from}').${key}Input, _NuxtScriptOptions]`;
586
+ }).join("\n")}
587
+ }
588
+ }
589
+ `;
590
+ }
591
+ return `${augments}
592
+ export {}`;
593
+ }
594
+ }, { nuxt: true });
595
+ }
534
596
  function templateTriggerResolver(defaultScriptOptions) {
535
597
  const needsIdleTimeout = defaultScriptOptions?.trigger && typeof defaultScriptOptions.trigger === "object" && "idleTimeout" in defaultScriptOptions.trigger;
536
598
  const needsInteraction = defaultScriptOptions?.trigger && typeof defaultScriptOptions.trigger === "object" && "interaction" in defaultScriptOptions.trigger;
@@ -668,6 +730,10 @@ const module$1 = defineNuxtModule({
668
730
  // Configures the maximum time (in milliseconds) allowed for each fetch attempt.
669
731
  }
670
732
  },
733
+ googleStaticMapsProxy: {
734
+ enabled: false,
735
+ cacheMaxAge: 3600
736
+ },
671
737
  enabled: true,
672
738
  debug: false
673
739
  },
@@ -687,11 +753,17 @@ const module$1 = defineNuxtModule({
687
753
  if (unheadVersion?.startsWith("1")) {
688
754
  logger.error(`Nuxt Scripts requires Unhead >= 2, you are using v${unheadVersion}. Please run \`nuxi upgrade --clean\` to upgrade...`);
689
755
  }
690
- nuxt.options.runtimeConfig["nuxt-scripts"] = { version };
756
+ nuxt.options.runtimeConfig["nuxt-scripts"] = {
757
+ version,
758
+ // Private proxy config with API key (server-side only)
759
+ googleStaticMapsProxy: config.googleStaticMapsProxy?.enabled ? { apiKey: nuxt.options.runtimeConfig.public.scripts?.googleMaps?.apiKey } : void 0
760
+ };
691
761
  nuxt.options.runtimeConfig.public["nuxt-scripts"] = {
692
762
  // expose for devtools
693
763
  version: nuxt.options.dev ? version : void 0,
694
- defaultScriptOptions: config.defaultScriptOptions
764
+ defaultScriptOptions: config.defaultScriptOptions,
765
+ // Only expose enabled and cacheMaxAge to client, not apiKey
766
+ googleStaticMapsProxy: config.googleStaticMapsProxy?.enabled ? { enabled: true, cacheMaxAge: config.googleStaticMapsProxy.cacheMaxAge } : void 0
695
767
  };
696
768
  if (config.registry) {
697
769
  nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
@@ -743,42 +815,7 @@ const module$1 = defineNuxtModule({
743
815
  }
744
816
  const registryScriptsWithImport = registryScripts.filter((i) => !!i.import?.name);
745
817
  const newScripts = registryScriptsWithImport.filter((i) => !scripts.some((r) => r.import?.name === i.import.name));
746
- addTypeTemplate({
747
- filename: "module/nuxt-scripts.d.ts",
748
- getContents: (data) => {
749
- const typesPath = relative(resolve(data.nuxt.options.rootDir, data.nuxt.options.buildDir, "module"), resolve("runtime/types"));
750
- let types = `
751
- declare module '#app' {
752
- interface NuxtApp {
753
- $scripts: Record<${[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`).concat(["string"]).join(" | ")}, (import('#nuxt-scripts/types').UseScriptContext<any>)>
754
- _scripts: Record<string, (import('#nuxt-scripts/types').UseScriptContext<any>)>
755
- }
756
- interface RuntimeNuxtHooks {
757
- 'scripts:updated': (ctx: { scripts: Record<string, (import('#nuxt-scripts/types').UseScriptContext<any>)> }) => void | Promise<void>
758
- }
759
- }
760
- `;
761
- if (newScripts.length) {
762
- types = `${types}
763
- declare module '#nuxt-scripts/types' {
764
- type NuxtUseScriptOptions = Omit<import('${typesPath}').NuxtUseScriptOptions, 'use' | 'beforeInit'>
765
- interface ScriptRegistry {
766
- ${newScripts.map((i) => {
767
- const key = i.import?.name.replace("useScript", "");
768
- const keyLcFirst = key.substring(0, 1).toLowerCase() + key.substring(1);
769
- return ` ${keyLcFirst}?: import('${i.import?.from}').${key}Input | [import('${i.import?.from}').${key}Input, NuxtUseScriptOptions]`;
770
- }).join("\n")}
771
- }
772
- }`;
773
- return types;
774
- }
775
- return `${types}
776
- export {}`;
777
- }
778
- }, {
779
- nuxt: true,
780
- node: true
781
- });
818
+ registerTypeTemplates({ nuxt, config, newScripts });
782
819
  if (Object.keys(config.globals || {}).length || Object.keys(config.registry || {}).length) {
783
820
  addPluginTemplate({
784
821
  filename: `modules/${name.replace("/", "-")}/plugin.mjs`,
@@ -804,6 +841,7 @@ export {}`;
804
841
  fallbackOnSrcOnBundleFail: config.assets?.fallbackOnSrcOnBundleFail,
805
842
  fetchOptions: config.assets?.fetchOptions,
806
843
  cacheMaxAge: config.assets?.cacheMaxAge,
844
+ integrity: config.assets?.integrity,
807
845
  renderedScript
808
846
  }));
809
847
  nuxt.hooks.hook("build:done", async () => {
@@ -812,6 +850,12 @@ export {}`;
812
850
  await p?.();
813
851
  });
814
852
  });
853
+ if (config.googleStaticMapsProxy?.enabled) {
854
+ addServerHandler({
855
+ route: "/_scripts/google-static-maps-proxy",
856
+ handler: await resolvePath("./runtime/server/google-static-maps-proxy")
857
+ });
858
+ }
815
859
  if (nuxt.options.dev)
816
860
  setupDevToolsUI(config, resolvePath);
817
861
  }
package/dist/registry.mjs CHANGED
@@ -26,6 +26,17 @@ async function registry(resolve) {
26
26
  from: await resolve("./runtime/registry/cloudflare-web-analytics")
27
27
  }
28
28
  },
29
+ {
30
+ label: "PostHog",
31
+ src: false,
32
+ scriptBundling: false,
33
+ category: "analytics",
34
+ logo: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 128 128"><path fill="#1d4aff" d="M0 .52v32.15l31.79 31.78V32.3L0 .52zm32.3 32.15v32.15l31.78 31.78V64.45L32.3 32.67zM0 64.97v32.15l31.79 31.78V96.75L0 64.97zm64.6-32.3v32.15l31.78 31.78V64.45L64.6 32.67zm31.78 31.78v32.15l31.78 31.78V96.23l-31.78-31.78zm-64.08.52v32.15l31.78 31.78V96.75L32.3 64.97zM64.6 .52v32.15l31.78 31.78V32.3L64.6 .52zm0 64.45v32.15l31.78 31.78V96.75L64.6 64.97z"/></svg>`,
35
+ import: {
36
+ name: "useScriptPostHog",
37
+ from: await resolve("./runtime/registry/posthog")
38
+ }
39
+ },
29
40
  {
30
41
  label: "Fathom Analytics",
31
42
  scriptBundling: false,
@@ -101,6 +112,20 @@ async function registry(resolve) {
101
112
  from: await resolve("./runtime/registry/x-pixel")
102
113
  }
103
114
  },
115
+ {
116
+ label: "TikTok Pixel",
117
+ category: "tracking",
118
+ logo: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path d="M224 72a52.059 52.059 0 0 1-52-52a4 4 0 0 0-4-4h-40a4 4 0 0 0-4 4v132a28 28 0 1 1-40.567-25.019a4 4 0 0 0 2.567-3.734V80a4 4 0 0 0-4.652-3.949A84.032 84.032 0 1 0 156 152v-43.047a99.432 99.432 0 0 0 52 14.586a4 4 0 0 0 4-4V76a4 4 0 0 0-4-4z" fill="currentColor"/></svg>`,
119
+ import: {
120
+ name: "useScriptTikTokPixel",
121
+ from: await resolve("./runtime/registry/tiktok-pixel")
122
+ },
123
+ scriptBundling(options) {
124
+ if (!options?.id)
125
+ return false;
126
+ return withQuery("https://analytics.tiktok.com/i18n/pixel/events.js", { sdkid: options.id, lib: "ttq" });
127
+ }
128
+ },
104
129
  {
105
130
  label: "Snapchat Pixel",
106
131
  src: "https://sc-static.net/scevent.min.js",
@@ -281,6 +306,34 @@ async function registry(resolve) {
281
306
  from: await resolve("./runtime/registry/npm")
282
307
  }
283
308
  },
309
+ {
310
+ label: "Google reCAPTCHA",
311
+ category: "utility",
312
+ logo: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#1c3aa9" d="M64 32a32 32 0 1 1-64 0 32 32 0 0 1 64 0"/><path fill="#4285f4" d="m32 14-2 18 2 2 18-2V14z"/><path fill="#efefef" d="M14 32v18h18l2-2-2-16-16-2z"/><path fill="#f1f1f1" d="M32 32h18v18H32z"/><path fill="#e1e1e1" d="M14 14h18v18H14z"/><path fill="#1c3aa9" d="M32 14v18H14V14z"/><path fill="#4285f4" d="M32 32v18h18V32z"/><path d="M14 32h18v18H14z" fill="#f1f1f1"/><path d="M32 14h18v18H32z" fill="#fff"/></svg>`,
313
+ import: {
314
+ name: "useScriptGoogleRecaptcha",
315
+ from: await resolve("./runtime/registry/google-recaptcha")
316
+ },
317
+ scriptBundling(options) {
318
+ if (!options?.siteKey) {
319
+ return false;
320
+ }
321
+ const baseUrl = options?.recaptchaNet ? "https://www.recaptcha.net/recaptcha" : "https://www.google.com/recaptcha";
322
+ return `${baseUrl}/${options?.enterprise ? "enterprise.js" : "api.js"}`;
323
+ }
324
+ },
325
+ {
326
+ label: "Google Sign-In",
327
+ src: "https://accounts.google.com/gsi/client",
328
+ scriptBundling: false,
329
+ // CORS prevents bundling
330
+ category: "utility",
331
+ logo: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 262"><path fill="#4285F4" d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622l38.755 30.023l2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"/><path fill="#34A853" d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055c-34.523 0-63.824-22.773-74.269-54.25l-1.531.13l-40.298 31.187l-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"/><path fill="#FBBC05" d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82c0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602z"/><path fill="#EB4335" d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0C79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"/></svg>`,
332
+ import: {
333
+ name: "useScriptGoogleSignIn",
334
+ from: await resolve("./runtime/registry/google-sign-in")
335
+ }
336
+ },
284
337
  {
285
338
  label: "Google Tag Manager",
286
339
  category: "tracking",
@@ -89,6 +89,20 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
89
89
  * Extra Markers to add to the map.
90
90
  */
91
91
  markers?: (`${string},${string}` | google.maps.marker.AdvancedMarkerElementOptions)[];
92
+ /**
93
+ * Map IDs for light and dark color modes.
94
+ * When provided, the map will automatically switch styles based on color mode.
95
+ * Requires @nuxtjs/color-mode or manual colorMode prop.
96
+ */
97
+ mapIds?: {
98
+ light?: string;
99
+ dark?: string;
100
+ };
101
+ /**
102
+ * Manual color mode control. When provided, overrides auto-detection from @nuxtjs/color-mode.
103
+ * Accepts 'light', 'dark', or a reactive ref.
104
+ */
105
+ colorMode?: "light" | "dark";
92
106
  }, {
93
107
  readonly googleMaps: Ref<typeof google.maps | undefined, typeof google.maps | undefined>;
94
108
  readonly map: ShallowRef<google.maps.Map | undefined>;
@@ -182,6 +196,20 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
182
196
  * Extra Markers to add to the map.
183
197
  */
184
198
  markers?: (`${string},${string}` | google.maps.marker.AdvancedMarkerElementOptions)[];
199
+ /**
200
+ * Map IDs for light and dark color modes.
201
+ * When provided, the map will automatically switch styles based on color mode.
202
+ * Requires @nuxtjs/color-mode or manual colorMode prop.
203
+ */
204
+ mapIds?: {
205
+ light?: string;
206
+ dark?: string;
207
+ };
208
+ /**
209
+ * Manual color mode control. When provided, overrides auto-detection from @nuxtjs/color-mode.
210
+ * Accepts 'light', 'dark', or a reactive ref.
211
+ */
212
+ colorMode?: "light" | "dark";
185
213
  }> & Readonly<{
186
214
  onError?: (() => any) | undefined;
187
215
  onReady?: ((e: {
@@ -205,7 +233,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
205
233
  height: number | string;
206
234
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
207
235
  placeholder?: (props: {
208
- placeholder: any;
236
+ placeholder: string;
209
237
  }) => any;
210
238
  } & {
211
239
  loading?: (props: {}) => any;
@@ -3,7 +3,7 @@ import { computed, onBeforeUnmount, onMounted, ref, watch, toRaw, provide, shall
3
3
  import { withQuery } from "ufo";
4
4
  import { defu } from "defu";
5
5
  import { hash } from "ohash";
6
- import { useHead } from "nuxt/app";
6
+ import { tryUseNuxtApp, useHead, useRuntimeConfig } from "nuxt/app";
7
7
  import { scriptRuntimeConfig } from "#nuxt-scripts/utils";
8
8
  import { useScriptTriggerElement } from "#nuxt-scripts/composables/useScriptTriggerElement";
9
9
  import { useScriptGoogleMaps } from "#nuxt-scripts/registry/google-maps";
@@ -27,10 +27,28 @@ const props = defineProps({
27
27
  placeholderOptions: { type: Object, required: false },
28
28
  placeholderAttrs: { type: Object, required: false },
29
29
  rootAttrs: { type: Object, required: false },
30
- markers: { type: Array, required: false }
30
+ markers: { type: Array, required: false },
31
+ mapIds: { type: Object, required: false },
32
+ colorMode: { type: String, required: false }
31
33
  });
32
34
  const emits = defineEmits(["ready", "error"]);
33
35
  const apiKey = props.apiKey || scriptRuntimeConfig("googleMaps")?.apiKey;
36
+ const runtimeConfig = useRuntimeConfig();
37
+ const proxyConfig = runtimeConfig.public["nuxt-scripts"]?.googleStaticMapsProxy;
38
+ const nuxtApp = tryUseNuxtApp();
39
+ const nuxtColorMode = nuxtApp?.$colorMode;
40
+ const currentColorMode = computed(() => {
41
+ if (props.colorMode)
42
+ return props.colorMode;
43
+ if (nuxtColorMode?.value)
44
+ return nuxtColorMode.value === "dark" ? "dark" : "light";
45
+ return "light";
46
+ });
47
+ const currentMapId = computed(() => {
48
+ if (!props.mapIds)
49
+ return props.mapOptions?.mapId;
50
+ return props.mapIds[currentColorMode.value] || props.mapIds.light || props.mapOptions?.mapId;
51
+ });
34
52
  const mapsApi = ref();
35
53
  if (import.meta.dev && !apiKey)
36
54
  throw new Error("GoogleMaps requires an API key. Please provide `apiKey` on the <ScriptGoogleMaps> or globally via `runtimeConfig.public.scripts.googleMaps.apiKey`.");
@@ -48,10 +66,10 @@ const { load, status, onLoaded } = useScriptGoogleMaps({
48
66
  v: props.version
49
67
  });
50
68
  const options = computed(() => {
51
- return defu({ center: centerOverride.value }, props.mapOptions, {
69
+ const mapId = props.mapOptions?.styles ? void 0 : currentMapId.value || "map";
70
+ return defu({ center: centerOverride.value, mapId }, props.mapOptions, {
52
71
  center: props.center,
53
- zoom: 15,
54
- mapId: props.mapOptions?.styles ? void 0 : "map"
72
+ zoom: 15
55
73
  });
56
74
  });
57
75
  const ready = ref(false);
@@ -146,8 +164,12 @@ function importLibrary(key) {
146
164
  }
147
165
  }, { immediate: true });
148
166
  });
149
- libraries.set(key, p);
150
- return p;
167
+ const cached = Promise.resolve(p).catch((err) => {
168
+ libraries.delete(key);
169
+ throw err;
170
+ });
171
+ libraries.set(key, cached);
172
+ return cached;
151
173
  }
152
174
  const googleMaps = {
153
175
  googleMaps: mapsApi,
@@ -244,7 +266,7 @@ onMounted(() => {
244
266
  ready.value = true;
245
267
  });
246
268
  });
247
- if (import.meta.server) {
269
+ if (import.meta.server && !proxyConfig?.enabled) {
248
270
  useHead({
249
271
  link: [
250
272
  {
@@ -280,10 +302,12 @@ const placeholder = computed(() => {
280
302
  center
281
303
  }, {
282
304
  size: `${props.width}x${props.height}`,
283
- key: apiKey,
305
+ // Only include API key if not using proxy (proxy injects it server-side)
306
+ key: proxyConfig?.enabled ? void 0 : apiKey,
284
307
  scale: 2,
285
308
  // we assume a high DPI to avoid hydration issues
286
309
  style: props.mapOptions?.styles ? transformMapStyles(props.mapOptions.styles) : void 0,
310
+ map_id: currentMapId.value,
287
311
  markers: [
288
312
  ...props.markers || [],
289
313
  props.centerMarker && center
@@ -297,7 +321,8 @@ const placeholder = computed(() => {
297
321
  return m;
298
322
  }).join("|")
299
323
  });
300
- return withQuery("https://maps.googleapis.com/maps/api/staticmap", placeholderOptions);
324
+ const baseUrl = proxyConfig?.enabled ? "/_scripts/google-static-maps-proxy" : "https://maps.googleapis.com/maps/api/staticmap";
325
+ return withQuery(baseUrl, placeholderOptions);
301
326
  });
302
327
  const placeholderAttrs = computed(() => {
303
328
  return defu(props.placeholderAttrs, {