@nuxt/scripts 1.0.0-rc.9 → 1.0.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 (106) hide show
  1. package/dist/devtools-client/200.html +1 -1
  2. package/dist/devtools-client/404.html +1 -1
  3. package/dist/devtools-client/_nuxt/{Cxq4HLPL.js → BjIIVRlr.js} +1 -1
  4. package/dist/devtools-client/_nuxt/{BBS9G2Kb.js → C3h_qg0j.js} +1 -1
  5. package/dist/devtools-client/_nuxt/{DCBsJT4N.js → CKrGhxlH.js} +1 -1
  6. package/dist/devtools-client/_nuxt/DD1eKorn.js +1 -0
  7. package/dist/devtools-client/_nuxt/{B4uHpJPz.js → DTVoxnk-.js} +1 -1
  8. package/dist/devtools-client/_nuxt/{DvZScWzI.js → TnW0ti1s.js} +1 -1
  9. package/dist/devtools-client/_nuxt/UTyLw2F_.js +188 -0
  10. package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
  11. package/dist/devtools-client/_nuxt/builds/meta/8eda1fb3-23bc-456f-8373-7e503f9580ec.json +1 -0
  12. package/dist/devtools-client/_nuxt/{entry.BwpOBArY.css → entry.BKkVrcJj.css} +1 -1
  13. package/dist/devtools-client/_nuxt/error-404.Rdq9GpXu.css +1 -0
  14. package/dist/devtools-client/_nuxt/error-500.BPHNCR4E.css +1 -0
  15. package/dist/devtools-client/_nuxt/index.DZD1lwyI.css +1 -0
  16. package/dist/devtools-client/docs/index.html +1 -1
  17. package/dist/devtools-client/first-party/index.html +1 -1
  18. package/dist/devtools-client/index.html +1 -1
  19. package/dist/devtools-client/registry/index.html +1 -1
  20. package/dist/module.d.mts +18 -2
  21. package/dist/module.d.ts +18 -2
  22. package/dist/module.json +1 -1
  23. package/dist/module.mjs +81 -9
  24. package/dist/registry.mjs +10 -6
  25. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +1 -2
  26. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +3 -0
  27. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue +6 -2
  28. package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +0 -1
  29. package/dist/runtime/components/ScriptBlueskyEmbed.vue +12 -10
  30. package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +0 -1
  31. package/dist/runtime/components/ScriptInstagramEmbed.vue +3 -1
  32. package/dist/runtime/components/ScriptXEmbed.d.vue.ts +0 -1
  33. package/dist/runtime/components/ScriptXEmbed.vue +11 -9
  34. package/dist/runtime/components/ScriptXEmbed.vue.d.ts +0 -1
  35. package/dist/runtime/composables/useScript.js +17 -6
  36. package/dist/runtime/composables/useScriptProxyToken.d.ts +12 -0
  37. package/dist/runtime/composables/useScriptProxyToken.js +4 -0
  38. package/dist/runtime/composables/useScriptProxyUrl.d.ts +12 -0
  39. package/dist/runtime/composables/useScriptProxyUrl.js +27 -0
  40. package/dist/runtime/plugins/proxy-token.server.d.ts +10 -0
  41. package/dist/runtime/plugins/proxy-token.server.js +17 -0
  42. package/dist/runtime/registry/bing-uet.d.ts +6 -2
  43. package/dist/runtime/registry/bing-uet.js +13 -1
  44. package/dist/runtime/registry/bluesky-embed.d.ts +0 -4
  45. package/dist/runtime/registry/bluesky-embed.js +0 -4
  46. package/dist/runtime/registry/clarity.d.ts +6 -2
  47. package/dist/runtime/registry/clarity.js +12 -1
  48. package/dist/runtime/registry/google-analytics.d.ts +6 -2
  49. package/dist/runtime/registry/google-analytics.js +12 -1
  50. package/dist/runtime/registry/google-tag-manager.d.ts +6 -2
  51. package/dist/runtime/registry/google-tag-manager.js +10 -1
  52. package/dist/runtime/registry/gravatar.js +10 -13
  53. package/dist/runtime/registry/matomo-analytics.d.ts +9 -3
  54. package/dist/runtime/registry/matomo-analytics.js +28 -1
  55. package/dist/runtime/registry/meta-pixel.d.ts +8 -2
  56. package/dist/runtime/registry/meta-pixel.js +10 -1
  57. package/dist/runtime/registry/mixpanel-analytics.d.ts +12 -2
  58. package/dist/runtime/registry/mixpanel-analytics.js +16 -4
  59. package/dist/runtime/registry/posthog.d.ts +8 -2
  60. package/dist/runtime/registry/posthog.js +15 -4
  61. package/dist/runtime/registry/schemas.d.ts +65 -0
  62. package/dist/runtime/registry/schemas.js +75 -8
  63. package/dist/runtime/registry/tiktok-pixel.d.ts +16 -2
  64. package/dist/runtime/registry/tiktok-pixel.js +22 -1
  65. package/dist/runtime/registry/x-embed.d.ts +0 -4
  66. package/dist/runtime/registry/x-embed.js +0 -4
  67. package/dist/runtime/server/bluesky-embed-image.d.ts +1 -1
  68. package/dist/runtime/server/bluesky-embed.d.ts +1 -15
  69. package/dist/runtime/server/bluesky-embed.js +22 -4
  70. package/dist/runtime/server/google-maps-geocode-proxy.js +8 -5
  71. package/dist/runtime/server/google-static-maps-proxy.d.ts +1 -1
  72. package/dist/runtime/server/google-static-maps-proxy.js +13 -8
  73. package/dist/runtime/server/gravatar-proxy.d.ts +1 -1
  74. package/dist/runtime/server/gravatar-proxy.js +6 -7
  75. package/dist/runtime/server/instagram-embed-asset.d.ts +1 -1
  76. package/dist/runtime/server/instagram-embed-image.d.ts +1 -1
  77. package/dist/runtime/server/instagram-embed.js +22 -10
  78. package/dist/runtime/server/utils/cached-upstream.d.ts +55 -0
  79. package/dist/runtime/server/utils/cached-upstream.js +65 -0
  80. package/dist/runtime/server/utils/embed-rewriters.d.ts +19 -0
  81. package/dist/runtime/server/utils/embed-rewriters.js +41 -0
  82. package/dist/runtime/server/utils/image-proxy.d.ts +3 -1
  83. package/dist/runtime/server/utils/image-proxy.js +8 -6
  84. package/dist/runtime/server/utils/instagram-embed.d.ts +4 -4
  85. package/dist/runtime/server/utils/instagram-embed.js +10 -9
  86. package/dist/runtime/server/utils/proxy-url.d.ts +9 -0
  87. package/dist/runtime/server/utils/proxy-url.js +21 -0
  88. package/dist/runtime/server/utils/sign-constants.d.ts +16 -0
  89. package/dist/runtime/server/utils/sign-constants.js +5 -0
  90. package/dist/runtime/server/utils/sign.d.ts +2 -10
  91. package/dist/runtime/server/utils/sign.js +8 -5
  92. package/dist/runtime/server/utils/withSigning.js +3 -2
  93. package/dist/runtime/server/vercel-insights-sink.d.ts +2 -0
  94. package/dist/runtime/server/vercel-insights-sink.js +5 -0
  95. package/dist/runtime/server/x-embed-image.d.ts +1 -1
  96. package/dist/runtime/server/x-embed.js +20 -2
  97. package/dist/runtime/types.d.ts +28 -1
  98. package/dist/types-source.mjs +104 -11
  99. package/dist/types.d.mts +1 -1
  100. package/package.json +3 -3
  101. package/dist/devtools-client/_nuxt/CQR4zIAm.js +0 -1
  102. package/dist/devtools-client/_nuxt/DTxy5P8N.js +0 -188
  103. package/dist/devtools-client/_nuxt/builds/meta/bd58b869-1eb5-4c50-871c-707f9b71e8f9.json +0 -1
  104. package/dist/devtools-client/_nuxt/error-404.d44aGwWI.css +0 -1
  105. package/dist/devtools-client/_nuxt/error-500.NthMfIEt.css +0 -1
  106. package/dist/devtools-client/_nuxt/index.CA-OpSj0.css +0 -1
@@ -0,0 +1 @@
1
+ .grid[data-v-6699daa6]{display:grid}.mb-2[data-v-6699daa6]{margin-bottom:.5rem}.mb-4[data-v-6699daa6]{margin-bottom:1rem}.max-w-520px[data-v-6699daa6]{max-width:520px}.min-h-screen[data-v-6699daa6]{min-height:100vh}.w-full[data-v-6699daa6]{width:100%}.flex[data-v-6699daa6]{display:flex}.place-content-center[data-v-6699daa6]{place-content:center}.items-center[data-v-6699daa6]{align-items:center}.justify-center[data-v-6699daa6]{justify-content:center}.overflow-hidden[data-v-6699daa6]{overflow:hidden}.bg-white[data-v-6699daa6]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2[data-v-6699daa6]{padding-left:.5rem;padding-right:.5rem}.text-center[data-v-6699daa6]{text-align:center}.text-\[80px\][data-v-6699daa6]{font-size:80px}.text-2xl[data-v-6699daa6]{font-size:1.5rem;line-height:2rem}.text-sm[data-v-6699daa6]{font-size:.875rem;line-height:1.25rem}.text-\[\#020420\][data-v-6699daa6]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\[\#64748B\][data-v-6699daa6]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.hover\:text-\[\#00DC82\][data-v-6699daa6]:hover{--un-text-opacity:1;color:rgb(0 220 130/var(--un-text-opacity))}.font-medium[data-v-6699daa6]{font-weight:500}.font-semibold[data-v-6699daa6]{font-weight:600}.leading-none[data-v-6699daa6]{line-height:1}.tracking-wide[data-v-6699daa6]{letter-spacing:.025em}.font-sans[data-v-6699daa6]{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-6699daa6]{--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-6699daa6]{text-decoration-line:underline}.underline-offset-3[data-v-6699daa6]{text-underline-offset:3px}.antialiased[data-v-6699daa6]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\:bg-\[\#020420\][data-v-6699daa6]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\:text-white[data-v-6699daa6]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\:text-\[110px\][data-v-6699daa6]{font-size:110px}.sm\:text-3xl[data-v-6699daa6]{font-size:1.875rem;line-height:2.25rem}}
@@ -0,0 +1 @@
1
+ .grid[data-v-a7ff0736]{display:grid}.mb-2[data-v-a7ff0736]{margin-bottom:.5rem}.mb-4[data-v-a7ff0736]{margin-bottom:1rem}.max-w-520px[data-v-a7ff0736]{max-width:520px}.min-h-screen[data-v-a7ff0736]{min-height:100vh}.place-content-center[data-v-a7ff0736]{place-content:center}.overflow-hidden[data-v-a7ff0736]{overflow:hidden}.bg-white[data-v-a7ff0736]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2[data-v-a7ff0736]{padding-left:.5rem;padding-right:.5rem}.text-center[data-v-a7ff0736]{text-align:center}.text-\[80px\][data-v-a7ff0736]{font-size:80px}.text-2xl[data-v-a7ff0736]{font-size:1.5rem;line-height:2rem}.text-\[\#020420\][data-v-a7ff0736]{--un-text-opacity:1;color:rgb(2 4 32/var(--un-text-opacity))}.text-\[\#64748B\][data-v-a7ff0736]{--un-text-opacity:1;color:rgb(100 116 139/var(--un-text-opacity))}.font-semibold[data-v-a7ff0736]{font-weight:600}.leading-none[data-v-a7ff0736]{line-height:1}.tracking-wide[data-v-a7ff0736]{letter-spacing:.025em}.font-sans[data-v-a7ff0736]{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-a7ff0736]{--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-a7ff0736]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(prefers-color-scheme:dark){.dark\:bg-\[\#020420\][data-v-a7ff0736]{--un-bg-opacity:1;background-color:rgb(2 4 32/var(--un-bg-opacity))}.dark\:text-white[data-v-a7ff0736]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media(min-width:640px){.sm\:text-\[110px\][data-v-a7ff0736]{font-size:110px}.sm\:text-3xl[data-v-a7ff0736]{font-size:1.875rem;line-height:2.25rem}}
@@ -0,0 +1 @@
1
+ .script-status[data-v-5cf865ba]{align-items:center;border-radius:9999px;display:inline-flex;font-size:.6875rem;font-weight:600;gap:.375rem;letter-spacing:.01em;line-height:1.4;padding:.125rem .5rem}.script-status-dot[data-v-5cf865ba]{border-radius:50%;flex-shrink:0;height:6px;width:6px}.status-loaded[data-v-5cf865ba]{background:#6bc6701f;color:#006818;color:oklch(45% .15 145)}.status-loaded .script-status-dot[data-v-5cf865ba]{background:#11ad32;box-shadow:0 0 6px #11ad3280}.dark .status-loaded[data-v-5cf865ba]{background:#10782326;color:#75d079}.status-loading[data-v-5cf865ba]{background:#70b3f71a;color:#0065b0;color:oklch(50% .15 250)}.status-loading .script-status-dot[data-v-5cf865ba]{animation:pulse-dot-5cf865ba 1.5s ease-in-out infinite;background:#0083e0;background:oklch(60% .18 250)}.dark .status-loading[data-v-5cf865ba]{background:#23588a26;color:#70b3f7}.status-awaiting[data-v-5cf865ba]{background:#d9b9821a;color:#946900;color:oklch(55% .12 80)}.status-awaiting .script-status-dot[data-v-5cf865ba]{background:#cd9200;background:oklch(70% .15 80)}.dark .status-awaiting[data-v-5cf865ba]{background:#67522d26;color:#cfa761}.status-error[data-v-5cf865ba]{background:#ce70691a;color:#a83634}.status-error .script-status-dot[data-v-5cf865ba]{background:#de3b3d}.dark .status-error[data-v-5cf865ba]{background:#843c3826;color:#e6857e}.status-validation[data-v-5cf865ba]{background:#a890d41a;color:#6e519d}.status-validation .script-status-dot[data-v-5cf865ba]{background:#8f68cb}.dark .status-validation[data-v-5cf865ba]{background:#4e3d6c26;color:#b7a0e4}.status-unknown[data-v-5cf865ba]{background:var(--color-surface-sunken);color:var(--color-text-muted)}.status-unknown .script-status-dot[data-v-5cf865ba]{background:var(--color-neutral-400)}@keyframes pulse-dot-5cf865ba{0%,to{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.85)}}.script-metric[data-v-b147450b]{align-items:center;background:var(--color-surface-sunken);border:1px solid var(--color-border-subtle);border-radius:9999px;color:var(--color-text-muted);display:inline-flex;font-family:var(--font-mono);font-size:.6875rem;font-weight:500;gap:.25rem;letter-spacing:-.01em;padding:.125rem .5rem}.script-metric[data-v-c6837c50]{align-items:center;background:#6bc67014;border:1px solid oklch(65% .15 145/.12);border-radius:9999px;color:#2f7434;display:inline-flex;font-family:var(--font-mono);font-size:.6875rem;font-weight:500;gap:.25rem;letter-spacing:-.01em;padding:.125rem .5rem}.dark .script-metric[data-v-c6837c50]{background:#2c63301f;border-color:#49814c26;color:#85cc87}.ui-tooltip-panel[data-v-16948115]{background:var(--color-surface-elevated);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:0 4px 12px #0000001a;color:var(--color-text);font-size:.75rem;font-weight:400;line-height:1.4;padding:.5rem .75rem;pointer-events:none;white-space:normal}.dark .ui-tooltip-panel[data-v-16948115]{box-shadow:0 4px 12px #0000004d}.waterfall-container[data-v-d16c88db]{display:flex;flex-direction:column;gap:.5rem;padding:.75rem}.waterfall-stats[data-v-d16c88db]{align-items:center;display:flex;font-size:.6875rem;gap:.5rem}.waterfall-stat[data-v-d16c88db]{align-items:baseline;display:inline-flex;font-variant-numeric:tabular-nums;gap:.25rem}.waterfall-stat-value[data-v-d16c88db]{color:var(--color-text);font-weight:700}.waterfall-stat-label[data-v-d16c88db]{color:var(--color-text-subtle)}.waterfall-sep[data-v-d16c88db]{background:var(--color-text-subtle);border-radius:50%;height:3px;opacity:.3;width:3px}.waterfall-proxied-badge[data-v-d16c88db]{align-items:center;color:#107823;display:inline-flex;gap:.25rem}.dark .waterfall-proxied-badge[data-v-d16c88db]{color:#85cc87}.domain-pill[data-v-d16c88db]{align-items:center;background:var(--color-surface-sunken);border:1px solid var(--color-border-subtle);border-radius:9999px;color:var(--color-text-subtle);display:inline-flex;font-family:var(--font-mono);font-size:.625rem;gap:.125rem;padding:.0625rem .375rem}.domain-pill-proxied[data-v-d16c88db]{background:#6bc67014;border-color:#4aa6511f;color:#2f7434}.dark .domain-pill-proxied[data-v-d16c88db]{background:#2f74341a;color:#8fc990}.waterfall-table[data-v-d16c88db]{background:var(--color-surface-elevated);border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);overflow:hidden}.waterfall-legend[data-v-d16c88db]{align-items:center;background:var(--color-surface-sunken);border-bottom:1px solid var(--color-border-subtle);display:flex;gap:.75rem;padding:.25rem .5rem}.waterfall-legend-item[data-v-d16c88db]{align-items:center;color:var(--color-text-subtle);display:flex;font-size:.5625rem;font-weight:600;gap:.25rem;letter-spacing:.04em;text-transform:uppercase}.waterfall-legend-dot[data-v-d16c88db]{border-radius:2px;height:5px;width:5px}.waterfall-row[data-v-d16c88db]{align-items:center;cursor:default;display:flex;font-size:.6875rem;gap:.375rem;padding:.1875rem .5rem;transition:background .1s}.waterfall-row[data-v-d16c88db]:hover{background:var(--color-surface-sunken)}.waterfall-row-proxied[data-v-d16c88db]{background:#6bc67008}.waterfall-row-proxied[data-v-d16c88db]:hover{background:#6bc6700f}.waterfall-status[data-v-d16c88db]{border-radius:3px;flex-shrink:0;font-family:var(--font-mono);font-size:.625rem;font-weight:600;line-height:1;padding:.125rem 0;text-align:center;width:1.5rem}.waterfall-status-200[data-v-d16c88db]{background:#6bc6701a;color:#107823}.dark .waterfall-status-200[data-v-d16c88db]{background:#2f74341f;color:#85cc87}.waterfall-status-304[data-v-d16c88db]{background:#d9b9821a;color:#946900;color:oklch(55% .12 80)}.dark .waterfall-status-304[data-v-d16c88db]{background:#75603b1f;color:#cfa761}.waterfall-row-icon[data-v-d16c88db]{color:var(--color-text-subtle);flex-shrink:0;font-size:.625rem;opacity:.4}.waterfall-row-icon-proxied[data-v-d16c88db]{color:#278733;opacity:1}.dark .waterfall-row-icon-proxied[data-v-d16c88db]{color:#85cc87}.waterfall-url[data-v-d16c88db]{color:var(--color-text-muted);flex-shrink:0;font-family:var(--font-mono);font-size:.625rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:15rem}.waterfall-bar-track[data-v-d16c88db]{background:var(--color-surface-sunken);border-radius:3px;flex:1;height:.875rem;overflow:hidden;position:relative}.waterfall-bar[data-v-d16c88db]{border-radius:3px;display:flex;height:100%;overflow:hidden;position:absolute}.waterfall-duration[data-v-d16c88db]{color:var(--color-text-subtle);flex-shrink:0;font-family:var(--font-mono);font-size:.625rem;font-variant-numeric:tabular-nums;text-align:right;width:2.5rem}.devtools-snippet[data-v-265ccc31]{margin:.5rem .75rem}.devtools-snippet-header[data-v-265ccc31]{align-items:center;display:flex;justify-content:space-between;margin-bottom:.375rem}.devtools-snippet-label[data-v-265ccc31]{color:var(--color-text-muted);font-family:var(--font-mono);font-size:.6875rem;font-weight:500;letter-spacing:-.01em}.devtools-snippet-block[data-v-265ccc31]{border-radius:var(--radius-sm);font-size:.6875rem;line-height:1.6;max-height:300px;overflow-y:auto;padding:.5rem .625rem!important}.filter-bar[data-v-1d33b8c9]{align-items:center;display:flex;gap:.25rem;margin-bottom:.75rem;padding:0 .25rem}.filter-chip[data-v-1d33b8c9]{align-items:center;background:transparent;border:1px solid var(--color-border-subtle);border-radius:9999px;color:var(--color-text-subtle);cursor:pointer;display:inline-flex;font-size:.6875rem;font-weight:500;gap:.375rem;padding:.25rem .625rem;transition:all .15s}.filter-chip[data-v-1d33b8c9]:hover{border-color:var(--color-border);color:var(--color-text-muted)}.filter-chip-active[data-v-1d33b8c9]{background:var(--color-surface-sunken);border-color:var(--color-border);color:var(--color-text)}.filter-chip-count[data-v-1d33b8c9]{background:var(--color-surface-sunken);border-radius:9999px;color:var(--color-text-subtle);font-size:.625rem;font-variant-numeric:tabular-nums;min-width:1.25rem;padding:0 .25rem;text-align:center}.filter-chip-active .filter-chip-count[data-v-1d33b8c9]{background:var(--color-surface-elevated)}.sub-tab[data-v-1d33b8c9]{align-items:center;border-bottom:2px solid transparent;color:var(--color-text-subtle);cursor:pointer;display:flex;font-size:.75rem;font-weight:500;gap:.375rem;margin-bottom:-1px;padding:.5rem .75rem;transition:color .15s,border-color .15s}.sub-tab[data-v-1d33b8c9]:hover{color:var(--color-text-muted)}.sub-tab-active[data-v-1d33b8c9]{border-bottom-color:var(--seo-green);color:var(--color-text)}.event-timeline[data-v-1d33b8c9]{display:flex;flex-direction:column;gap:.125rem}.event-row[data-v-1d33b8c9]{align-items:center;border-radius:var(--radius-sm);display:flex;font-size:.6875rem;gap:.625rem;padding:.25rem .375rem;transition:background .1s}.event-row[data-v-1d33b8c9]:hover{background:var(--color-surface-sunken)}.event-time[data-v-1d33b8c9]{color:var(--color-text-subtle);font-family:var(--font-mono);font-size:.625rem;font-variant-numeric:tabular-nums;min-width:5.5rem;white-space:nowrap}.event-badge[data-v-1d33b8c9]{border-radius:9999px;display:inline-flex;font-size:.625rem;font-weight:600;letter-spacing:.01em;padding:.0625rem .375rem;white-space:nowrap}.event-fn[data-v-1d33b8c9]{background:var(--color-surface-sunken);border:1px solid var(--color-border-subtle);border-radius:var(--radius-sm);color:var(--color-text-muted);font-family:var(--font-mono);font-size:.6875rem;max-width:100%;overflow:hidden;padding:.0625rem .5rem;text-overflow:ellipsis;white-space:nowrap}.status-badge-loaded[data-v-1d33b8c9]{background:#6bc6701f;color:#006818;color:oklch(45% .15 145)}.dark .status-badge-loaded[data-v-1d33b8c9]{background:#10782326;color:#75d079}.status-badge-loading[data-v-1d33b8c9]{background:#d9b9821f;color:#946900;color:oklch(55% .12 80)}.dark .status-badge-loading[data-v-1d33b8c9]{background:#67522d26;color:#cfa761}.status-badge-awaiting[data-v-1d33b8c9]{background:var(--color-surface-sunken);color:var(--color-text-muted)}.status-badge-error[data-v-1d33b8c9]{background:#ce70691a;color:#a83634}.dark .status-badge-error[data-v-1d33b8c9]{background:#843c3826;color:#e6857e}.status-badge-validation[data-v-1d33b8c9]{background:#a890d41a;color:#6e519d}.dark .status-badge-validation[data-v-1d33b8c9]{background:#4e3d6c26;color:#b7a0e4}.status-badge-default[data-v-1d33b8c9]{background:var(--color-surface-sunken);color:var(--color-text-subtle)}
@@ -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.BwpOBArY.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DTxy5P8N.js"><script type="module" src="/__nuxt-scripts/_nuxt/DTxy5P8N.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"bd58b869-1eb5-4c50-871c-707f9b71e8f9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776170341853,false]</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.BKkVrcJj.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/UTyLw2F_.js"><script type="module" src="/__nuxt-scripts/_nuxt/UTyLw2F_.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"8eda1fb3-23bc-456f-8373-7e503f9580ec",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776392828828,false]</script></body></html>
@@ -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.BwpOBArY.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DTxy5P8N.js"><script type="module" src="/__nuxt-scripts/_nuxt/DTxy5P8N.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"bd58b869-1eb5-4c50-871c-707f9b71e8f9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776170341854,false]</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.BKkVrcJj.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/UTyLw2F_.js"><script type="module" src="/__nuxt-scripts/_nuxt/UTyLw2F_.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"8eda1fb3-23bc-456f-8373-7e503f9580ec",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776392828829,false]</script></body></html>
@@ -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.BwpOBArY.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DTxy5P8N.js"><script type="module" src="/__nuxt-scripts/_nuxt/DTxy5P8N.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"bd58b869-1eb5-4c50-871c-707f9b71e8f9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776170341855,false]</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.BKkVrcJj.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/UTyLw2F_.js"><script type="module" src="/__nuxt-scripts/_nuxt/UTyLw2F_.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"8eda1fb3-23bc-456f-8373-7e503f9580ec",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776392828830,false]</script></body></html>
@@ -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.BwpOBArY.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/DTxy5P8N.js"><script type="module" src="/__nuxt-scripts/_nuxt/DTxy5P8N.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"bd58b869-1eb5-4c50-871c-707f9b71e8f9",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776170341855,false]</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.BKkVrcJj.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__nuxt-scripts/_nuxt/UTyLw2F_.js"><script type="module" src="/__nuxt-scripts/_nuxt/UTyLw2F_.js" crossorigin></script><script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-scripts",buildId:"8eda1fb3-23bc-456f-8373-7e503f9580ec",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1776392828829,false]</script></body></html>
package/dist/module.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { FetchOptions } from 'ofetch';
3
- import { RegistryScripts, FirstPartyPrivacy, NuxtConfigScriptRegistry, NuxtUseScriptOptionsSerializable, NuxtUseScriptInput, ResolvedProxyAutoInject } from '../dist/runtime/types.js';
3
+ import { RegistryScripts, FirstPartyPrivacy, NuxtConfigScriptRegistry, NuxtUseScriptOptionsSerializable, NuxtUseScriptInput, ResolvedProxyAutoInject, ProxyConfig } from '../dist/runtime/types.js';
4
4
  export { FirstPartyPrivacy } from '../dist/runtime/types.js';
5
5
 
6
6
  interface ResolvedProxySecret {
@@ -22,6 +22,7 @@ interface ResolvedProxySecret {
22
22
  declare function resolveProxySecret(rootDir: string, isDev: boolean, configSecret?: string, autoGenerate?: boolean): ResolvedProxySecret | undefined;
23
23
  declare function isProxyDisabled(registryKey: string, registry?: NuxtConfigScriptRegistry, runtimeConfig?: Record<string, any>): boolean;
24
24
  declare function applyAutoInject(registry: NuxtConfigScriptRegistry, runtimeConfig: Record<string, any>, proxyPrefix: string, registryKey: string, autoInject: ResolvedProxyAutoInject): void;
25
+ declare function resolveConfiguredProxyDomains(config: Record<string, any> | undefined, proxyConfig?: Pick<ProxyConfig, 'autoInject' | 'configDomainFields'>): string[];
25
26
  interface ModuleOptions {
26
27
  /**
27
28
  * Base path prefix for all script endpoints (proxy and bundled assets).
@@ -120,6 +121,21 @@ interface ModuleOptions {
120
121
  * @default true
121
122
  */
122
123
  autoGenerateSecret?: boolean;
124
+ /**
125
+ * How long (in seconds) a page token issued during SSR remains valid on the
126
+ * client. Client-driven proxy requests (dynamic fetches, runtime image
127
+ * helpers) attach this token so `withSigning` accepts them without each URL
128
+ * being HMAC-signed up front.
129
+ *
130
+ * The default of 1 hour is safe for SSR; for SSG or prerendered routes,
131
+ * deployed HTML carries the build-time token, so bump this (e.g. `2592000`
132
+ * for 30 days) to keep client-side proxy calls working after the build.
133
+ * Longer TTLs widen the replay window if a token is scraped, so prefer the
134
+ * shortest value that covers your cache horizon.
135
+ *
136
+ * @default 3600
137
+ */
138
+ pageTokenMaxAge?: number;
123
139
  };
124
140
  /**
125
141
  * Google Static Maps proxy configuration.
@@ -166,5 +182,5 @@ interface ModuleHooks {
166
182
  }
167
183
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
168
184
 
169
- export { applyAutoInject, _default as default, isProxyDisabled, resolveProxySecret };
185
+ export { applyAutoInject, _default as default, isProxyDisabled, resolveConfiguredProxyDomains, resolveProxySecret };
170
186
  export type { ModuleHooks, ModuleOptions, ResolvedProxySecret };
package/dist/module.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { FetchOptions } from 'ofetch';
3
- import { RegistryScripts, FirstPartyPrivacy, NuxtConfigScriptRegistry, NuxtUseScriptOptionsSerializable, NuxtUseScriptInput, ResolvedProxyAutoInject } from '../dist/runtime/types.js';
3
+ import { RegistryScripts, FirstPartyPrivacy, NuxtConfigScriptRegistry, NuxtUseScriptOptionsSerializable, NuxtUseScriptInput, ResolvedProxyAutoInject, ProxyConfig } from '../dist/runtime/types.js';
4
4
  export { FirstPartyPrivacy } from '../dist/runtime/types.js';
5
5
 
6
6
  interface ResolvedProxySecret {
@@ -22,6 +22,7 @@ interface ResolvedProxySecret {
22
22
  declare function resolveProxySecret(rootDir: string, isDev: boolean, configSecret?: string, autoGenerate?: boolean): ResolvedProxySecret | undefined;
23
23
  declare function isProxyDisabled(registryKey: string, registry?: NuxtConfigScriptRegistry, runtimeConfig?: Record<string, any>): boolean;
24
24
  declare function applyAutoInject(registry: NuxtConfigScriptRegistry, runtimeConfig: Record<string, any>, proxyPrefix: string, registryKey: string, autoInject: ResolvedProxyAutoInject): void;
25
+ declare function resolveConfiguredProxyDomains(config: Record<string, any> | undefined, proxyConfig?: Pick<ProxyConfig, 'autoInject' | 'configDomainFields'>): string[];
25
26
  interface ModuleOptions {
26
27
  /**
27
28
  * Base path prefix for all script endpoints (proxy and bundled assets).
@@ -120,6 +121,21 @@ interface ModuleOptions {
120
121
  * @default true
121
122
  */
122
123
  autoGenerateSecret?: boolean;
124
+ /**
125
+ * How long (in seconds) a page token issued during SSR remains valid on the
126
+ * client. Client-driven proxy requests (dynamic fetches, runtime image
127
+ * helpers) attach this token so `withSigning` accepts them without each URL
128
+ * being HMAC-signed up front.
129
+ *
130
+ * The default of 1 hour is safe for SSR; for SSG or prerendered routes,
131
+ * deployed HTML carries the build-time token, so bump this (e.g. `2592000`
132
+ * for 30 days) to keep client-side proxy calls working after the build.
133
+ * Longer TTLs widen the replay window if a token is scraped, so prefer the
134
+ * shortest value that covers your cache horizon.
135
+ *
136
+ * @default 3600
137
+ */
138
+ pageTokenMaxAge?: number;
123
139
  };
124
140
  /**
125
141
  * Google Static Maps proxy configuration.
@@ -166,5 +182,5 @@ interface ModuleHooks {
166
182
  }
167
183
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
168
184
 
169
- export { applyAutoInject, _default as default, isProxyDisabled, resolveProxySecret };
185
+ export { applyAutoInject, _default as default, isProxyDisabled, resolveConfiguredProxyDomains, resolveProxySecret };
170
186
  export type { ModuleHooks, ModuleOptions, ResolvedProxySecret };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16"
6
6
  },
7
- "version": "1.0.0-rc.9",
7
+ "version": "1.0.1",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createHash, randomBytes } from 'node:crypto';
2
2
  import { existsSync, readFileSync, appendFileSync, writeFileSync, readdirSync } from 'node:fs';
3
- import { useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, createResolver, extendViteConfig, logger as logger$1, useLogger, addTypeTemplate, defineNuxtModule, addPluginTemplate, addServerHandler, addImports, addComponentsDir, addTemplate, hasNuxtModule, addBuildPlugin } from '@nuxt/kit';
3
+ import { useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, createResolver, extendViteConfig, logger as logger$1, useLogger, addTypeTemplate, defineNuxtModule, addPluginTemplate, addServerHandler, addImports, addComponentsDir, addTemplate, hasNuxtModule, addBuildPlugin, addPlugin } from '@nuxt/kit';
4
4
  import { defu } from 'defu';
5
5
  import { join, resolve } from 'pathe';
6
6
  import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
@@ -288,7 +288,7 @@ function migrateDeprecatedRegistryKeys(registry, warn) {
288
288
  }
289
289
  }
290
290
  }
291
- function normalizeRegistryConfig(registry, warn) {
291
+ function normalizeRegistryConfig(registry, warn, componentOnlyKeys) {
292
292
  for (const key of Object.keys(registry)) {
293
293
  const entry = registry[key];
294
294
  if (!entry) {
@@ -296,6 +296,10 @@ function normalizeRegistryConfig(registry, warn) {
296
296
  continue;
297
297
  }
298
298
  if (entry === true) {
299
+ if (componentOnlyKeys?.has(key)) {
300
+ registry[key] = [{}];
301
+ continue;
302
+ }
299
303
  warn?.(`[nuxt-scripts] registry.${key}: \`true\` shorthand is deprecated. Use \`{ trigger: 'onNuxtReady' }\` instead.`);
300
304
  registry[key] = [{}, { trigger: "onNuxtReady" }];
301
305
  continue;
@@ -1438,6 +1442,37 @@ function applyAutoInject(registry2, runtimeConfig, proxyPrefix, registryKey, aut
1438
1442
  if (rtEntry && typeof rtEntry === "object" && rtEntry !== input)
1439
1443
  rtEntry[autoInject.configField] = value;
1440
1444
  }
1445
+ const ABSOLUTE_URL_RE = /^[a-z][a-z\d+.-]*:\/\//i;
1446
+ function resolveConfiguredProxyDomain(value) {
1447
+ if (typeof value !== "string")
1448
+ return;
1449
+ const trimmed = value.trim();
1450
+ if (!trimmed || !ABSOLUTE_URL_RE.test(trimmed) && !trimmed.startsWith("//"))
1451
+ return;
1452
+ try {
1453
+ return new URL(trimmed, "https://nuxt-scripts.local").hostname || void 0;
1454
+ } catch {
1455
+ }
1456
+ }
1457
+ function resolveConfiguredProxyDomains(config, proxyConfig) {
1458
+ if (!config || typeof config !== "object")
1459
+ return [];
1460
+ const domains = /* @__PURE__ */ new Set();
1461
+ const scriptSrc = resolveConfiguredProxyDomain(config.scriptInput?.src);
1462
+ if (scriptSrc)
1463
+ domains.add(scriptSrc);
1464
+ if (proxyConfig?.autoInject?.configField) {
1465
+ const endpointDomain = resolveConfiguredProxyDomain(config[proxyConfig.autoInject.configField]);
1466
+ if (endpointDomain)
1467
+ domains.add(endpointDomain);
1468
+ }
1469
+ for (const field of proxyConfig?.configDomainFields || []) {
1470
+ const domain = resolveConfiguredProxyDomain(config[field]);
1471
+ if (domain)
1472
+ domains.add(domain);
1473
+ }
1474
+ return [...domains].sort();
1475
+ }
1441
1476
  const module$1 = defineNuxtModule({
1442
1477
  meta: {
1443
1478
  name: "@nuxt/scripts",
@@ -1496,8 +1531,9 @@ const module$1 = defineNuxtModule({
1496
1531
  }
1497
1532
  const scripts = await registry(resolvePath);
1498
1533
  if (config.registry) {
1534
+ const componentOnlyKeys = new Set(scripts.filter((s) => !s.import).map((s) => s.registryKey));
1499
1535
  migrateDeprecatedRegistryKeys(config.registry, (msg) => logger.warn(msg));
1500
- normalizeRegistryConfig(config.registry, (msg) => logger.warn(msg));
1536
+ normalizeRegistryConfig(config.registry, (msg) => logger.warn(msg), componentOnlyKeys);
1501
1537
  nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
1502
1538
  const registryWithDefaults = {};
1503
1539
  for (const [key, entry] of Object.entries(config.registry)) {
@@ -1547,9 +1583,17 @@ const module$1 = defineNuxtModule({
1547
1583
  const proxyConfigs = {};
1548
1584
  const proxyHandlerPath = await resolvePath("./runtime/server/proxy-handler");
1549
1585
  addServerHandler({ route: `${proxyPrefix}/**`, handler: proxyHandlerPath });
1586
+ if (nuxt.options.dev && config.registry?.vercelAnalytics) {
1587
+ addServerHandler({
1588
+ route: "/_vercel/insights/**",
1589
+ handler: await resolvePath("./runtime/server/vercel-insights-sink")
1590
+ });
1591
+ }
1550
1592
  const composables = [
1551
1593
  "useScript",
1552
1594
  "useScriptEventPage",
1595
+ "useScriptProxyToken",
1596
+ "useScriptProxyUrl",
1553
1597
  "useScriptTriggerConsent",
1554
1598
  "useScriptTriggerElement",
1555
1599
  "useScriptTriggerIdleTimeout",
@@ -1592,10 +1636,23 @@ const module$1 = defineNuxtModule({
1592
1636
  const script = scripts.find((s) => s.registryKey === key);
1593
1637
  if (!script?.schema)
1594
1638
  continue;
1595
- const requiredFields = extractRequiredFields(script.schema);
1596
- const missing = requiredFields.filter((f) => !input[f]);
1597
- if (missing.length) {
1598
- logger.warn(`[nuxt-scripts] registry.${key}: missing required field${missing.length > 1 ? "s" : ""} ${missing.map((f) => `'${f}'`).join(", ")}. The script infrastructure is registered but will not function without ${missing.length > 1 ? "them" : "it"}.`);
1639
+ const isComponentOnly = !script.import;
1640
+ if (isComponentOnly) {
1641
+ if (scriptOptions && "trigger" in scriptOptions && scriptOptions.trigger !== false) {
1642
+ const pascal = key.charAt(0).toUpperCase() + key.slice(1);
1643
+ logger.warn(
1644
+ `[nuxt-scripts] registry.${key}: \`trigger\` has no effect on component-only scripts. Render <Script${pascal}> in your template to load the embed.`
1645
+ );
1646
+ }
1647
+ continue;
1648
+ }
1649
+ const willAutoLoad = scriptOptions && "trigger" in scriptOptions && scriptOptions.trigger !== false;
1650
+ if (willAutoLoad) {
1651
+ const requiredFields = extractRequiredFields(script.schema);
1652
+ const missing = requiredFields.filter((f) => !input[f]);
1653
+ if (missing.length) {
1654
+ logger.warn(`[nuxt-scripts] registry.${key}: missing required field${missing.length > 1 ? "s" : ""} ${missing.map((f) => `'${f}'`).join(", ")}. The script infrastructure is registered but will not function without ${missing.length > 1 ? "them" : "it"}.`);
1655
+ }
1599
1656
  }
1600
1657
  const envDefaultKeys = new Set(Object.keys(script.envDefaults || {}));
1601
1658
  const userProvidedFields = Object.keys(input).filter((f) => !envDefaultKeys.has(f));
@@ -1666,6 +1723,7 @@ const module$1 = defineNuxtModule({
1666
1723
  const unmatchedScripts = [];
1667
1724
  let totalDomains = 0;
1668
1725
  const devtoolsScripts = [];
1726
+ const publicScripts = nuxt.options.runtimeConfig.public?.scripts;
1669
1727
  for (const key of registryKeys) {
1670
1728
  const script = scriptByKey.get(key);
1671
1729
  if (!script) {
@@ -1684,10 +1742,17 @@ const module$1 = defineNuxtModule({
1684
1742
  }
1685
1743
  const entry = config.registry?.[key];
1686
1744
  const inputPrivacy = entry?.[0]?.privacy;
1745
+ const runtimeEntry = publicScripts?.[key] && typeof publicScripts[key] === "object" ? publicScripts[key] : void 0;
1687
1746
  for (const domain of proxyConfig.domains) {
1688
1747
  domainPrivacy[domain] = inputPrivacy ?? proxyConfig.privacy;
1689
1748
  totalDomains++;
1690
1749
  }
1750
+ for (const source of [entry?.[0], runtimeEntry]) {
1751
+ for (const domain of resolveConfiguredProxyDomains(source, proxyConfig)) {
1752
+ domainPrivacy[domain] = inputPrivacy ?? proxyConfig.privacy;
1753
+ totalDomains++;
1754
+ }
1755
+ }
1691
1756
  if (proxyConfig.autoInject && config.registry)
1692
1757
  applyAutoInject(config.registry, nuxt.options.runtimeConfig, proxyPrefix, key, proxyConfig.autoInject);
1693
1758
  if (nuxt.options.dev)
@@ -1830,7 +1895,14 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
1830
1895
  else if (proxySecretResolved?.source === "memory-generated")
1831
1896
  logger.warn(`[security] Generated an in-memory ${PROXY_SECRET_ENV_KEY} (could not write .env). Signed URLs will break across restarts.`);
1832
1897
  if (proxySecretResolved?.secret) {
1833
- nuxt.options.runtimeConfig["nuxt-scripts"].proxySecret = proxySecretResolved.secret;
1898
+ const scriptsRuntime = nuxt.options.runtimeConfig["nuxt-scripts"];
1899
+ scriptsRuntime.proxySecret = proxySecretResolved.secret;
1900
+ if (config.security?.pageTokenMaxAge !== void 0)
1901
+ scriptsRuntime.pageTokenMaxAge = config.security.pageTokenMaxAge;
1902
+ addPlugin({
1903
+ src: await resolvePath("./runtime/plugins/proxy-token.server"),
1904
+ mode: "server"
1905
+ });
1834
1906
  } else if (!nuxt.options.dev) {
1835
1907
  logger.warn(
1836
1908
  `[security] ${PROXY_SECRET_ENV_KEY} is not set. Proxy endpoints will pass requests through without signature verification.
@@ -1842,4 +1914,4 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
1842
1914
  }
1843
1915
  });
1844
1916
 
1845
- export { applyAutoInject, module$1 as default, isProxyDisabled, resolveProxySecret };
1917
+ export { applyAutoInject, module$1 as default, isProxyDisabled, resolveConfiguredProxyDomains, resolveProxySecret };
package/dist/registry.mjs CHANGED
@@ -240,7 +240,8 @@ async function registry(resolve) {
240
240
  bundle: true,
241
241
  proxy: {
242
242
  domains: ["va.vercel-scripts.com", "vitals.vercel-insights.com"],
243
- privacy: PRIVACY_IP_ONLY
243
+ privacy: PRIVACY_IP_ONLY,
244
+ configDomainFields: ["endpoint"]
244
245
  }
245
246
  }),
246
247
  def("posthog", {
@@ -284,7 +285,8 @@ async function registry(resolve) {
284
285
  envDefaults: { matomoUrl: "" },
285
286
  proxy: {
286
287
  domains: ["cdn.matomo.cloud"],
287
- privacy: PRIVACY_IP_ONLY
288
+ privacy: PRIVACY_IP_ONLY,
289
+ configDomainFields: ["matomoUrl", "trackerUrl"]
288
290
  },
289
291
  partytown: { forwards: ["_paq.push"] }
290
292
  }),
@@ -319,7 +321,8 @@ async function registry(resolve) {
319
321
  proxy: {
320
322
  domains: ["cdn.databuddy.cc", "basket.databuddy.cc"],
321
323
  privacy: PRIVACY_IP_ONLY,
322
- autoInject: { field: "apiUrl", target: "basket.databuddy.cc" }
324
+ autoInject: { field: "apiUrl", target: "basket.databuddy.cc" },
325
+ configDomainFields: ["scriptUrl"]
323
326
  }
324
327
  }),
325
328
  def("segment", {
@@ -346,7 +349,7 @@ async function registry(resolve) {
346
349
  return "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
347
350
  }
348
351
  },
349
- partytown: { forwards: ["mixpanel", "mixpanel.init", "mixpanel.track", "mixpanel.identify", "mixpanel.people.set", "mixpanel.reset", "mixpanel.register"] }
352
+ partytown: { forwards: ["mixpanel", "mixpanel.init", "mixpanel.track", "mixpanel.identify", "mixpanel.people.set", "mixpanel.reset", "mixpanel.register", "mixpanel.opt_in_tracking", "mixpanel.opt_out_tracking"] }
350
353
  }),
351
354
  // ad
352
355
  def("bingUet", {
@@ -401,7 +404,7 @@ async function registry(resolve) {
401
404
  domains: ["analytics.tiktok.com", "mon.tiktok.com", "mcs.tiktok.com"],
402
405
  privacy: PRIVACY_FULL
403
406
  },
404
- partytown: { forwards: ["ttq.track", "ttq.page", "ttq.identify"] }
407
+ partytown: { forwards: ["ttq.track", "ttq.page", "ttq.identify", "ttq.grantConsent", "ttq.revokeConsent", "ttq.holdConsent"] }
405
408
  }),
406
409
  def("snapchatPixel", {
407
410
  schema: SnapTrPixelOptions,
@@ -503,7 +506,7 @@ async function registry(resolve) {
503
506
  domains: ["www.clarity.ms", "scripts.clarity.ms", "d.clarity.ms", "e.clarity.ms", "k.clarity.ms", "c.clarity.ms", "a.clarity.ms", "b.clarity.ms"],
504
507
  privacy: PRIVACY_HEATMAP
505
508
  },
506
- partytown: { forwards: [] }
509
+ partytown: { forwards: ["clarity"] }
507
510
  }),
508
511
  // payments
509
512
  def("stripe", {
@@ -746,6 +749,7 @@ function buildProxyConfigsFromRegistry(scripts, scriptByKey) {
746
749
  domains: proxyDef.domains.map((d) => typeof d === "string" ? d : d.domain),
747
750
  privacy: proxyDef.privacy || { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
748
751
  autoInject: proxyDef.autoInject ? resolveAutoInject(proxyDef.autoInject) : void 0,
752
+ configDomainFields: proxyDef.configDomainFields,
749
753
  sdkPatches: proxyDef.sdkPatches
750
754
  };
751
755
  }
@@ -74,7 +74,7 @@ const { load, status, onLoaded } = useScriptGoogleMaps({
74
74
  v: props.version
75
75
  });
76
76
  const options = computed(() => {
77
- const mapId = props.mapOptions?.styles ? void 0 : currentMapId.value || "map";
77
+ const mapId = props.mapOptions?.styles ? void 0 : currentMapId.value || "DEMO_MAP_ID";
78
78
  return defu(
79
79
  { center: centerOverride.value, mapId },
80
80
  props.mapOptions,
@@ -280,7 +280,6 @@ const rootAttrs = computed(() => {
280
280
  onBeforeUnmount(() => {
281
281
  map.value?.unbindAll();
282
282
  map.value = void 0;
283
- mapEl.value?.firstChild?.remove();
284
283
  libraries.clear();
285
284
  queryToLatLngCache.clear();
286
285
  });
@@ -20,6 +20,9 @@ let gmpClickHandler;
20
20
  const advancedMarkerElement = useGoogleMapsResource({
21
21
  ready: () => !slots.content || !!markerContent.value,
22
22
  async create({ mapsApi, map }) {
23
+ if (import.meta.dev && !map.get("mapId")) {
24
+ console.warn("[nuxt-scripts] <ScriptGoogleMapsMarker> requires the parent <ScriptGoogleMaps> to have a `mapId` set, but none was found. This usually happens when `mapOptions.styles` (JSON styles) is set, since Google Maps treats `styles` and `mapId` as mutually exclusive. Use cloud-based map styling instead: https://scripts.nuxt.com/scripts/google-maps/guides/map-styling");
25
+ }
23
26
  await mapsApi.importLibrary("marker");
24
27
  const marker = new mapsApi.marker.AdvancedMarkerElement({
25
28
  ...props.options,
@@ -4,6 +4,7 @@ import { defu } from "defu";
4
4
  import { useHead, useRuntimeConfig } from "nuxt/app";
5
5
  import { withQuery } from "ufo";
6
6
  import { computed, onMounted, ref } from "vue";
7
+ import { useScriptProxyUrl } from "../../composables/useScriptProxyUrl";
7
8
  </script>
8
9
 
9
10
  <script setup>
@@ -34,6 +35,7 @@ const runtimeConfig = useRuntimeConfig();
34
35
  const proxyConfig = runtimeConfig.public["nuxt-scripts"]?.googleStaticMapsProxy;
35
36
  const apiKey = props.apiKey || scriptRuntimeConfig("googleMaps")?.apiKey;
36
37
  const useProxy = !props.apiKey && proxyConfig?.enabled;
38
+ const proxyUrl = useScriptProxyUrl();
37
39
  if (import.meta.dev) {
38
40
  if (!apiKey && !useProxy)
39
41
  console.warn("[nuxt-scripts] ScriptGoogleMapsStaticMap requires a Google Maps API key with Static Maps API access. Set NUXT_PUBLIC_SCRIPTS_GOOGLE_MAPS_API_KEY in your .env, or enable the proxy via `scripts.registry.googleMaps`.");
@@ -122,8 +124,10 @@ const src = computed(() => {
122
124
  if (query[key] === void 0)
123
125
  delete query[key];
124
126
  }
125
- const baseUrl = useProxy ? "/_scripts/proxy/google-static-maps" : "https://maps.googleapis.com/maps/api/staticmap";
126
- return withQuery(baseUrl, query);
127
+ if (useProxy) {
128
+ return proxyUrl("/_scripts/proxy/google-static-maps", query);
129
+ }
130
+ return withQuery("https://maps.googleapis.com/maps/api/staticmap", query);
127
131
  });
128
132
  const imgAttributes = computed(() => {
129
133
  return defu(props.imgAttrs, {
@@ -32,7 +32,6 @@ declare const slotProps: import("vue").ComputedRef<{
32
32
  displayName: string;
33
33
  handle: string;
34
34
  avatar: string;
35
- avatarOriginal: string;
36
35
  isVerified: boolean;
37
36
  text: string;
38
37
  richText: string;
@@ -1,7 +1,8 @@
1
1
  <script setup>
2
2
  import { useAsyncData } from "nuxt/app";
3
3
  import { computed } from "vue";
4
- import { extractBlueskyPostId, facetsToHtml, formatBlueskyDate, formatCount, proxyBlueskyImageUrl } from "../registry/bluesky-embed";
4
+ import { useScriptProxyUrl } from "../composables/useScriptProxyUrl";
5
+ import { extractBlueskyPostId, facetsToHtml, formatBlueskyDate, formatCount } from "../registry/bluesky-embed";
5
6
  import { requireRegistryEndpoint, scriptsPrefix } from "../utils";
6
7
  const props = defineProps({
7
8
  postUrl: { type: String, required: true },
@@ -15,11 +16,12 @@ const resolvedApiEndpoint = computed(() => props.apiEndpoint || `${prefix}/embed
15
16
  const resolvedImageProxyEndpoint = computed(() => props.imageProxyEndpoint || `${prefix}/embed/bluesky-image`);
16
17
  if (!props.apiEndpoint)
17
18
  requireRegistryEndpoint("ScriptBlueskyEmbed", "blueskyEmbed");
19
+ const proxyUrl = useScriptProxyUrl();
18
20
  const postId = computed(() => extractBlueskyPostId(props.postUrl));
19
21
  const cacheKey = computed(() => `bluesky-embed-${postId.value?.actor}-${postId.value?.rkey}`);
20
22
  const { data: post, status, error } = useAsyncData(
21
23
  cacheKey,
22
- () => $fetch(`${resolvedApiEndpoint.value}?url=${encodeURIComponent(props.postUrl)}`)
24
+ () => $fetch(proxyUrl(resolvedApiEndpoint.value, { url: props.postUrl }))
23
25
  );
24
26
  const slotProps = computed(() => {
25
27
  if (!post.value)
@@ -31,8 +33,7 @@ const slotProps = computed(() => {
31
33
  // Author info
32
34
  displayName: p.author.displayName,
33
35
  handle: p.author.handle,
34
- avatar: proxyBlueskyImageUrl(p.author.avatar, resolvedImageProxyEndpoint.value),
35
- avatarOriginal: p.author.avatar,
36
+ avatar: p.author.avatar,
36
37
  isVerified: p.author.verification?.verifiedStatus === "valid",
37
38
  // Post content
38
39
  text: p.record.text,
@@ -49,10 +50,10 @@ const slotProps = computed(() => {
49
50
  repliesFormatted: formatCount(p.replyCount),
50
51
  quotes: p.quoteCount,
51
52
  quotesFormatted: formatCount(p.quoteCount),
52
- // Media
53
+ // Media (already proxied)
53
54
  images: p.embed?.images?.map((img) => ({
54
- thumb: proxyBlueskyImageUrl(img.thumb, resolvedImageProxyEndpoint.value),
55
- fullsize: proxyBlueskyImageUrl(img.fullsize, resolvedImageProxyEndpoint.value),
55
+ thumb: img.thumb,
56
+ fullsize: img.fullsize,
56
57
  alt: img.alt,
57
58
  aspectRatio: img.aspectRatio
58
59
  })),
@@ -60,13 +61,14 @@ const slotProps = computed(() => {
60
61
  uri: p.embed.external.uri,
61
62
  title: p.embed.external.title,
62
63
  description: p.embed.external.description,
63
- thumb: p.embed.external.thumb ? proxyBlueskyImageUrl(p.embed.external.thumb, resolvedImageProxyEndpoint.value) : void 0
64
+ thumb: p.embed.external.thumb
64
65
  } : void 0,
65
66
  // Links
66
67
  postUrl: props.postUrl,
67
68
  authorUrl: `https://bsky.app/profile/${p.author.handle}`,
68
- // Helpers
69
- proxyImage: (url) => proxyBlueskyImageUrl(url, resolvedImageProxyEndpoint.value)
69
+ // Helpers — proxy an arbitrary URL through the image endpoint at runtime.
70
+ // Uses the page token emitted during SSR so client-generated URLs validate.
71
+ proxyImage: (url) => proxyUrl(resolvedImageProxyEndpoint.value, { url })
70
72
  };
71
73
  });
72
74
  defineExpose({
@@ -32,7 +32,6 @@ declare const slotProps: import("vue").ComputedRef<{
32
32
  displayName: string;
33
33
  handle: string;
34
34
  avatar: string;
35
- avatarOriginal: string;
36
35
  isVerified: boolean;
37
36
  text: string;
38
37
  richText: string;
@@ -1,6 +1,7 @@
1
1
  <script setup>
2
2
  import { useAsyncData } from "nuxt/app";
3
3
  import { computed } from "vue";
4
+ import { useScriptProxyUrl } from "../composables/useScriptProxyUrl";
4
5
  import { extractInstagramShortcode } from "../registry/instagram-embed";
5
6
  import { requireRegistryEndpoint, scriptsPrefix } from "../utils";
6
7
  const props = defineProps({
@@ -14,10 +15,11 @@ const prefix = scriptsPrefix();
14
15
  const apiEndpoint = computed(() => props.apiEndpoint || `${prefix}/embed/instagram`);
15
16
  if (!props.apiEndpoint)
16
17
  requireRegistryEndpoint("ScriptInstagramEmbed", "instagramEmbed");
18
+ const proxyUrl = useScriptProxyUrl();
17
19
  const shortcode = computed(() => extractInstagramShortcode(props.postUrl));
18
20
  const { data: html, status, error } = useAsyncData(
19
21
  `instagram-embed-${props.postUrl}`,
20
- () => $fetch(`${apiEndpoint.value}?url=${encodeURIComponent(props.postUrl)}&captions=${props.captions}`),
22
+ () => $fetch(proxyUrl(apiEndpoint.value, { url: props.postUrl, captions: props.captions })),
21
23
  { watch: [() => props.postUrl, () => props.captions] }
22
24
  );
23
25
  defineExpose({
@@ -31,7 +31,6 @@ declare const slotProps: import("vue").ComputedRef<{
31
31
  userName: string;
32
32
  userHandle: string;
33
33
  userAvatar: string;
34
- userAvatarOriginal: string;
35
34
  isVerified: boolean | undefined;
36
35
  text: string;
37
36
  datetime: string;