v1.0.0
Nuxt Scripts v1 is the project's first stable release. It adds a first-party proxy, per-script Partytown support, server-rendered social embeds, consent APIs, and new registry integrations.
Highlights
First-Party Mode
Loading a third-party script gives its provider browser data that it can use for fingerprinting.
The amount of data varies by provider. The Nuxt Scripts audit snapshot records 5 X Pixel cookies and requests to 3 domains, plus browser signals such as battery status, CPU count, screen data, timezone, language, platform, and touch capability. It records Clarity traffic across 3 domains.
First-party mode bundles supported scripts at build time and serves them from your domain. Its reverse proxy forwards supported runtime requests through your server and anonymizes fields such as IP addresses (180.233.124.74 → 180.233.124.0) and browser versions (Mozilla/5.0 (compatible; Chrome/120.0)). Registry scripts use these capabilities by default when they declare support for them.
Serving bundled scripts from your origin avoids DNS and connection setup for the original script host. Same-origin proxy URLs are also less likely to match host-based blocking rules, although other blocking rules can still identify them. First-party mode does not remove consent requirements or the need for a consent banner where the law requires one.
See the First-Party Mode Guide and PR #577 for details.
Partytown Web Worker Support
Set partytown: true to run a supported registry script in a Partytown web worker. Its first-party bundling and proxy capabilities still apply. See PR #576.
The current Partytown quick path renders the script into the initial HTML and returns a loaded stub. It bypasses trigger resolution, use() proxies, load(), and reload(). In the configuration below, trigger enables generation of each global registry instance, but onNuxtReady does not delay the Partytown script.
Nuxt Scripts configures forwarding for googleAnalytics, plausibleAnalytics, cloudflareWebAnalytics, umamiAnalytics, matomoAnalytics, segment, mixpanelAnalytics, clarity, bingUet, metaPixel, xPixel, tiktokPixel, snapchatPixel, redditPixel, linkedinInsight, and calendly.
Do not assume that forwarding alone makes every registry integration usable on the current quick path. For example, Plausible and Umami need attributes that this path drops, while Clarity depends on a client initialization callback that never runs.
The Partytown tracker has an open report of dropped GA4 sessions when Google Tag Manager runs in a worker. Nuxt Scripts does not declare Partytown support for GTM. Test analytics delivery before moving GA4 to Partytown.
Server-Rendered Social Embeds
Twitter widgets, Instagram embeds, and Bluesky posts normally load vendor scripts in the browser. Following the Cloudflare Zaraz approach, Nuxt Scripts can fetch the embed data on the server and rewrite supported media URLs through your domain. See PR #590.
<ScriptXEmbed tweet-id="1754336034228171055">
<template #default="{ userName, text, likesFormatted, photos }">
<!-- Render the post with your own markup -->
</template>
</ScriptXEmbed>
<ScriptInstagramEmbed post-url="https://instagram.com/p/ABC123/">
<template #default="{ html, shortcode }">
<div v-html="html" />
</template>
</ScriptInstagramEmbed>
<ScriptBlueskyEmbed post-url="https://bsky.app/profile/...">
<template #default="{ displayName, text, images }">
<article>
<strong>{{ displayName }}</strong>
<p>{{ text }}</p>
<img v-for="image in images" :key="image.fullsize" :src="image.thumb" :alt="image.alt">
</article>
</template>
</ScriptBlueskyEmbed>
Consent Controls
v1 adds two layers of consent control. See the Consent Guide, PR #544, PR #631, and PR #712.
Consent trigger: useScriptTriggerConsent() prevents a script from loading until consent is granted. Its reactive state records later revocation, although revoking consent does not unload a script:
const trigger = useScriptTriggerConsent()
useScriptGoogleTagManager({ id: 'GTM-XXX', scriptOptions: { trigger } })
trigger.accept() // Grant → script loads
trigger.revoke() // Set consented to false; does not unload an already-loaded script
trigger.consented // Ref<boolean>
Vendor controls: consent-aware registry scripts expose a consent object and a typed defaultConsent option that runs before the first tracking call. This covers Google Analytics, Google Tag Manager, Bing UET, Meta Pixel, TikTok Pixel, Matomo, Mixpanel, PostHog, and Clarity. The types preserve each vendor's vocabulary, including GCMv2 for Google and Bing, grant/revoke for Meta, and 'opt-in'/'opt-out' defaults for Mixpanel and PostHog. Import the GCMv2 ConsentState from #nuxt-scripts/types.
const gtm = useScriptGoogleTagManager({
id: 'GTM-XXX',
defaultConsent: { ad_storage: 'denied', analytics_storage: 'denied' },
})
// Later, after the user accepts
gtm.consent.update({ ad_storage: 'granted', analytics_storage: 'granted' })
const ttq = useScriptTikTokPixel({ id: '...', defaultConsent: 'hold' })
ttq.consent.grant() // or .revoke() / .hold()
const meta = useScriptMetaPixel({ id: '...', defaultConsent: 'denied' })
meta.consent.grant()
DevTools
The Nuxt DevTools panel now covers the v1 privacy and capability model (implementation commit):
- First-party panel: proxy routes, active anonymization flags, and upstream domains.
- Registry panel: support and activation status for
bundle,proxy, andpartytown. - Script inspection: status, load timing, network waterfall, bundle size, and inline documentation.
- Standalone view: a separate DevTools tab connected to the Nuxt development server.
New Registry Scripts
- PostHog Analytics (#568): Product analytics with feature flags
- Google reCAPTCHA v3 (#567): Invisible bot protection
- TikTok Pixel (#569): Conversion tracking
- Google Sign-In (#573): One-tap authentication
- Rybbit Analytics (#453): Privacy-focused open source analytics
- Databuddy Analytics (#495): Lightweight analytics
- Bing UET (#650): Microsoft Advertising conversion tracking
- Mixpanel Analytics (#648): Product analytics and user tracking
- Vercel Analytics (#605): Vercel Web Analytics integration
- Gravatar (#606): Avatar service with privacy-preserving proxy
Other Changes
Script Reload API
Scripts now expose a .reload() method for re-executing DOM-scanning scripts after SPA navigation. See commit 77f853b.
const script = useScript('/third-party.js')
await script.reload()
Subresource Integrity Hashes
Set assets.integrity to generate Subresource Integrity hashes for bundled scripts. See PR #575.
export default defineNuxtConfig({
scripts: {
assets: {
integrity: 'sha384'
}
}
})
Script Stats Export
The new @nuxt/scripts/stats subpath exports script privacy and performance data for audits; the source lists its measured fields and rating inputs.
import { getScriptStats } from '@nuxt/scripts/stats'
const stats = await getScriptStats()
// Privacy ratings (A+ to F), performance ratings, CWV estimates,
// cookie analysis, network behavior, tracked data types
YouTube Player
- Isolated player instances (#586): Multiple players no longer share state
- Aspect ratio control: New
ratioprop - Unmount cleanup: Player instances are destroyed on unmount
Vimeo Player
- Aspect ratio control (#624): New
ratioprop, matching YouTube Player API
Google Maps
The Google Maps integration now exposes Vue components for markers, shapes, overlays, clustering, static maps, and GeoJSON.
Declarative components (#510): 11 components use Vue injection for parent-child communication and clean up on unmount.
Custom marker content (#658): The #content slot on ScriptGoogleMapsMarker replaces the default pin with HTML or a Vue template.
<ScriptGoogleMapsMarker :position="{ lat: -34.397, lng: 150.644 }">
<template #content>
<div class="price-tag">$420k</div>
</template>
</ScriptGoogleMapsMarker>
Custom overlay view (#658): ScriptGoogleMapsOverlayView renders Vue content at a map position. Inside a marker, it inherits the position and follows the marker while dragging. Use v-model:open to toggle it without remounting.
<ScriptGoogleMapsMarker :position="pos" @click="open = !open">
<ScriptGoogleMapsOverlayView v-model:open="open" anchor="bottom-center" :offset="{ x: 0, y: -50 }">
<MyCustomPopup @close="open = false" />
</ScriptGoogleMapsOverlayView>
</ScriptGoogleMapsMarker>
Direct :position prop: Marker components accept :position without an options object.
Additional components:
ScriptGoogleMapsStaticMap(#673): The static placeholder is now a standalone component. By default, images are routed through your server, which injects the API key into the upstream request. Google's current terms restrict storing and serving Static Maps images from an application server; the billing guide explains how to bypass this proxy with an explicitapi-key.ScriptGoogleMapsGeoJson(#656): Declarative wrapper aroundgoogle.maps.Datafor loading and styling GeoJSON with full event bindings.
Infrastructure:
- Color mode support (#587): Auto light/dark map switching with
mapIdsprop - Geocode proxy: Server-side geocoding hides API keys and caches results. Review the current caching restriction in the billing guide before using it.
- Resource cleanup (#651):
useGoogleMapsResourcecleans up subcomponents on unmount, including across async boundaries - Marker clustering (#517, #653): Batch operations use
noDrawto avoid repeated renders
Deprecation: v1 consolidates the legacy ScriptGoogleMapsMarker (wrapping google.maps.Marker) and ScriptGoogleMapsAdvancedMarkerElement names into ScriptGoogleMapsMarker (wrapping google.maps.marker.AdvancedMarkerElement). v1 removes ScriptGoogleMapsPinElement; a slot-passthrough compatibility shim remains, but custom marker markup belongs in the #content slot on ScriptGoogleMapsMarker.
Environment-Variable Config
The module now auto-populates runtimeConfig.public.scripts for fields that each registry integration declares as environment-backed. IDs, keys, and domains covered by those declarations resolve from NUXT_PUBLIC_SCRIPTS_* env vars without matching runtimeConfig boilerplate. See PR #634.
# .env
NUXT_PUBLIC_SCRIPTS_GOOGLE_ANALYTICS_ID=G-XXXXXX
NUXT_PUBLIC_SCRIPTS_POSTHOG_API_KEY=phc_xxx
Breaking Changes and Migration
Upgrading from v0? See the v0 to v1 migration guide for the summary table and before/after diffs for every breaking change and deprecation.
Bug Fixes
cdfb697fix(rybbit): queue custom events before script loads (#585)f8ce5a1fix(gtm): invoke onBeforeGtmStart callback when ID is in config (#584)a8d20b0fix: addestree-walkeras a dependency (#583)4c79486fix(plausible): use consistent window reference in clientInit stub (#574)78367b1fix(matomo): respect user-provided URL protocol (#572)c685f43fix: broken type augmentinge2050a2fix: align templates with existing augments (#589)da3a8ccchore: include.nuxttypes (#588)039380efix: prevent memory leaks in all Google Maps sub-components (#651)7e139b3fix: avoid mutating runtimeConfig scriptOptions (#638)01b1af4fix: expand self-closing<Script*>tags to prevent SFC extraction issues (#613)c3a6098fix: preserve compressed/binary request bodies in proxy handler (#619)96db067fix: missing Bing UET types (#710)fdaf089fix(types): prevent registry entry types from collapsing tonever(#701)698a585fix: inherit registry scriptOptions in composable instances (#691)506dfd8fix(google-maps): guard pan-on-open for closed/unpositioned overlay (#698)6fdd533fix(google-maps): prevent center reset on re-render and export clusterer types (#686)0e4ae9efix(google-maps): prevent zoom/pan reset when overlay toggles (#685)33ebf61fix(google-maps): close races inresolveQueryToLatLng(#693)4df13edfix: adddefineSlotsto all components for proper slot type inference (#684)afbb6bdfix(types): broken IDE display of registry types (#683)63d4da5fix: add v0 migration warnings and docs for breaking config changes (#679)3007458fix(google-analytics): addwww.google.comandwww.googletagmanager.comto proxy domains (#678)1c47e72fix: add missing proxy domains across registry scriptse6ecffffix(google-maps): bind$attrsto overlay view (#672)c2f8a8bfix(google-maps): remove redundant slot props from OverlayView (#666)b65e5dbfix(google-maps): OverlayView, InfoWindow, and AdvancedMarkerElement DX issues (#660)a597de9fix: prevent memory leak inScriptGoogleMapsAdvancedMarkerElement(#649)32ff4fafix: improve registry script DX and type safety (#647)569eeebfix(first-party): inject proxy endpoints for boolean/mock registry entries (#640)00fbaaefix: allow custom script keys inScriptRegistrytype (#632)3b93696fix(plausible): broken firstParty mode1c31a71fix(gravatar): broken proxy