---
title: "v1.0.0"
description: "Nuxt Scripts v1 adds a first-party proxy, Partytown workers, server-rendered social embeds, SRI hashes, and registry scripts."
canonical_url: "https://scripts.nuxt.com/docs/releases/v1"
last_updated: "2026-09-01T04:51:49.027Z"
---

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](https://developer.mozilla.org/en-US/docs/Glossary/Fingerprinting).

The amount of data varies by provider. The [Nuxt Scripts audit snapshot](https://github.com/nuxt/scripts/blob/main/packages/script/src/script-sizes.json) 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)`{lang="ts"}). 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](/docs/guides/first-party) and [PR #577](https://github.com/nuxt/scripts/pull/577) for details.

### Partytown Web Worker Support

Set `partytown: true` to run a supported registry script in a [Partytown](https://partytown.qwik.dev/) web worker. Its first-party bundling and proxy capabilities still apply. See [PR #576](https://github.com/nuxt/scripts/pull/576).

The [current Partytown quick path](https://github.com/nuxt/scripts/blob/main/packages/script/src/runtime/composables/useScript.ts) renders the script into the initial HTML and returns a loaded stub. It bypasses trigger resolution, `use()`{lang="ts"} proxies, `load()`{lang="ts"}, and `reload()`{lang="ts"}. 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.

::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
The Partytown tracker has an [open report of dropped GA4 sessions](https://github.com/QwikDev/partytown/issues/583) 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](https://blog.cloudflare.com/zaraz-supports-server-side-rendering-of-embeds/), Nuxt Scripts can fetch the embed data on the server and rewrite supported media URLs through your domain. See [PR #590](https://github.com/nuxt/scripts/pull/590).

```vue
<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](/docs/guides/consent), [PR #544](https://github.com/nuxt/scripts/pull/544), [PR #631](https://github.com/nuxt/scripts/pull/631), and [PR #712](https://github.com/nuxt/scripts/pull/712).

**Consent trigger:** [`useScriptTriggerConsent()`{lang="ts"}](/docs/api/use-script-trigger-consent) prevents a script from loading until consent is granted. Its reactive state records later revocation, although revoking consent does not unload a script:

```ts
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`{lang="ts"}.

```ts
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](https://github.com/nuxt/scripts/commit/1c2855fa)):

- **First-party panel:** proxy routes, active anonymization flags, and upstream domains.
- **Registry panel:** support and activation status for `bundle`, `proxy`, and `partytown`.
- **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](https://github.com/nuxt/scripts/pull/568)): Product analytics with feature flags
- **Google reCAPTCHA v3** ([#567](https://github.com/nuxt/scripts/pull/567)): Invisible bot protection
- **TikTok Pixel** ([#569](https://github.com/nuxt/scripts/pull/569)): Conversion tracking
- **Google Sign-In** ([#573](https://github.com/nuxt/scripts/pull/573)): One-tap authentication
- **Rybbit Analytics** ([#453](https://github.com/nuxt/scripts/pull/453)): Privacy-focused open source analytics
- **Databuddy Analytics** ([#495](https://github.com/nuxt/scripts/pull/495)): Lightweight analytics
- **Bing UET** ([#650](https://github.com/nuxt/scripts/pull/650)): Microsoft Advertising conversion tracking
- **Mixpanel Analytics** ([#648](https://github.com/nuxt/scripts/pull/648)): Product analytics and user tracking
- **Vercel Analytics** ([#605](https://github.com/nuxt/scripts/pull/605)): Vercel Web Analytics integration
- **Gravatar** ([#606](https://github.com/nuxt/scripts/pull/606)): Avatar service with privacy-preserving proxy

## Other Changes

### Script Reload API

Scripts now expose a [`.reload()`{lang="ts"}](/docs/api/use-script) method for re-executing DOM-scanning scripts after SPA navigation. See [commit 77f853b](https://github.com/nuxt/scripts/commit/77f853b).

```ts
const script = useScript('/third-party.js')
await script.reload()
```

### Subresource Integrity Hashes

Set `assets.integrity` to generate [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Subresource_Integrity) hashes for bundled scripts. See [PR #575](https://github.com/nuxt/scripts/pull/575).

```ts
export default defineNuxtConfig({
  scripts: {
    assets: {
      integrity: 'sha384'
    }
  }
})
```

### Script Stats Export

The new `@nuxt/scripts/stats`{lang="ts"} subpath exports script privacy and performance data for audits; the [source lists its measured fields and rating inputs](https://github.com/nuxt/scripts/blob/main/packages/script/src/stats.ts).

```ts
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](https://github.com/nuxt/scripts/pull/586)): Multiple players no longer share state
- **Aspect ratio control**: New `ratio` prop
- **Unmount cleanup**: Player instances are destroyed on unmount

### Vimeo Player

- **Aspect ratio control** ([#624](https://github.com/nuxt/scripts/pull/624)): New `ratio` prop, 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](https://github.com/nuxt/scripts/pull/510)): 11 components use Vue injection for parent-child communication and clean up on unmount.

**Custom marker content** ([#658](https://github.com/nuxt/scripts/pull/658)): The `#content` slot on `ScriptGoogleMapsMarker` replaces the default pin with HTML or a Vue template.

```vue
<ScriptGoogleMapsMarker :position="{ lat: -34.397, lng: 150.644 }">
  <template #content>
    <div class="price-tag">$420k</div>
  </template>
</ScriptGoogleMapsMarker>
```

**Custom overlay view** ([#658](https://github.com/nuxt/scripts/pull/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.

```vue
<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`**](/scripts/google-maps/api/static-map) ([#673](https://github.com/nuxt/scripts/pull/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](/scripts/google-maps/guides/billing) explains how to bypass this proxy with an explicit `api-key`.
- [**`ScriptGoogleMapsGeoJson`**](/scripts/google-maps/api/geojson) ([#656](https://github.com/nuxt/scripts/pull/656)): Declarative wrapper around `google.maps.Data` for loading and styling GeoJSON with full event bindings.

**Infrastructure:**

- **Color mode support** ([#587](https://github.com/nuxt/scripts/pull/587)): Auto light/dark map switching with `mapIds` prop
- **Geocode proxy**: Server-side geocoding hides API keys and caches results. Review the current caching restriction in the [billing guide](/scripts/google-maps/guides/billing) before using it.
- **Resource cleanup** ([#651](https://github.com/nuxt/scripts/pull/651)): `useGoogleMapsResource` cleans up subcomponents on unmount, including across async boundaries
- **Marker clustering** ([#517](https://github.com/nuxt/scripts/pull/517), [#653](https://github.com/nuxt/scripts/pull/653)): Batch operations use `noDraw` to 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](https://github.com/nuxt/scripts/pull/634).

```bash
# .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](/docs/migration-guide/v0-to-v1) for the summary table and before/after diffs for every breaking change and deprecation.

## Bug Fixes

- `cdfb697` fix(rybbit): queue custom events before script loads ([#585](https://github.com/nuxt/scripts/pull/585))
- `f8ce5a1` fix(gtm): invoke onBeforeGtmStart callback when ID is in config ([#584](https://github.com/nuxt/scripts/pull/584))
- `a8d20b0` fix: add `estree-walker` as a dependency ([#583](https://github.com/nuxt/scripts/pull/583))
- `4c79486` fix(plausible): use consistent window reference in clientInit stub ([#574](https://github.com/nuxt/scripts/pull/574))
- `78367b1` fix(matomo): respect user-provided URL protocol ([#572](https://github.com/nuxt/scripts/pull/572))
- [`c685f43`](https://github.com/nuxt/scripts/commit/c685f43) fix: broken type augmenting
- `e2050a2` fix: align templates with existing augments ([#589](https://github.com/nuxt/scripts/pull/589))
- `da3a8cc` chore: include `.nuxt` types ([#588](https://github.com/nuxt/scripts/pull/588))
- `039380e` fix: prevent memory leaks in all Google Maps sub-components ([#651](https://github.com/nuxt/scripts/pull/651))
- `7e139b3` fix: avoid mutating runtimeConfig scriptOptions ([#638](https://github.com/nuxt/scripts/pull/638))
- `01b1af4` fix: expand self-closing `<Script*>`{lang="html"} tags to prevent SFC extraction issues ([#613](https://github.com/nuxt/scripts/issues/613))
- `c3a6098` fix: preserve compressed/binary request bodies in proxy handler ([#619](https://github.com/nuxt/scripts/pull/619))
- `96db067` fix: missing Bing UET types ([#710](https://github.com/nuxt/scripts/pull/710))
- `fdaf089` fix(types): prevent registry entry types from collapsing to `never`{lang="ts"} ([#701](https://github.com/nuxt/scripts/pull/701))
- `698a585` fix: inherit registry scriptOptions in composable instances ([#691](https://github.com/nuxt/scripts/pull/691))
- `506dfd8` fix(google-maps): guard pan-on-open for closed/unpositioned overlay ([#698](https://github.com/nuxt/scripts/pull/698))
- `6fdd533` fix(google-maps): prevent center reset on re-render and export clusterer types ([#686](https://github.com/nuxt/scripts/pull/686))
- `0e4ae9e` fix(google-maps): prevent zoom/pan reset when overlay toggles ([#685](https://github.com/nuxt/scripts/pull/685))
- `33ebf61` fix(google-maps): close races in `resolveQueryToLatLng`{lang="ts"} ([#693](https://github.com/nuxt/scripts/pull/693))
- `4df13ed` fix: add `defineSlots`{lang="ts"} to all components for proper slot type inference ([#684](https://github.com/nuxt/scripts/pull/684))
- `afbb6bd` fix(types): broken IDE display of registry types ([#683](https://github.com/nuxt/scripts/pull/683))
- `63d4da5` fix: add v0 migration warnings and docs for breaking config changes ([#679](https://github.com/nuxt/scripts/pull/679))
- `3007458` fix(google-analytics): add `www.google.com`{lang="html"} and `www.googletagmanager.com`{lang="html"} to proxy domains ([#678](https://github.com/nuxt/scripts/pull/678))
- [`1c47e72`](https://github.com/nuxt/scripts/commit/1c47e72) fix: add missing proxy domains across registry scripts
- `e6ecfff` fix(google-maps): bind `$attrs`{lang="ts"} to overlay view ([#672](https://github.com/nuxt/scripts/pull/672))
- `c2f8a8b` fix(google-maps): remove redundant slot props from OverlayView ([#666](https://github.com/nuxt/scripts/pull/666))
- `b65e5db` fix(google-maps): OverlayView, InfoWindow, and AdvancedMarkerElement DX issues ([#660](https://github.com/nuxt/scripts/pull/660))
- `a597de9` fix: prevent memory leak in `ScriptGoogleMapsAdvancedMarkerElement`{lang="html"} ([#649](https://github.com/nuxt/scripts/pull/649))
- `32ff4fa` fix: improve registry script DX and type safety ([#647](https://github.com/nuxt/scripts/pull/647))
- `569eeeb` fix(first-party): inject proxy endpoints for boolean/mock registry entries ([#640](https://github.com/nuxt/scripts/pull/640))
- `00fbaae` fix: allow custom script keys in `ScriptRegistry`{lang="ts"} type ([#632](https://github.com/nuxt/scripts/pull/632))
- [`3b93696`](https://github.com/nuxt/scripts/commit/3b93696) fix(plausible): broken firstParty mode
- [`1c31a71`](https://github.com/nuxt/scripts/commit/1c31a71) fix(gravatar): broken proxy