WP Manifestindependent plugin directory
manifest / performance / dc-script-worker-prefetcher

DC Script Worker Proxy

Offload third-party scripts (GTM, Pixel, HubSpot…) to a Web Worker via Partytown + consent-aware loading + viewport/pagination prefetching for WooCommerce. Fully vendored — no npm required.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/dc-plugins/dc-script-worker-prefetcher/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Offload third-party scripts to a Web Worker via Partytown + consent-aware loading.

Offload third-party scripts (GTM, Pixel, HubSpot…) to a Web Worker via Partytown + consent-aware loading. Fully vendored — no npm required.


What it does

  1. Partytown Web Worker execution — Partytown moves third-party scripts into a Web Worker, off the main thread. Unlike async/defer (which still block the main thread), Partytown executes scripts entirely off-thread. No layout jank, no TBT impact. Tested with: Google Tag Manager, Facebook Pixel, HubSpot, Intercom, Klaviyo, TikTok Pixel, Mixpanel (full list).

Note: Partytown is in beta. Review the trade-offs before using in production.

  1. Google Consent Mode v2 (GCM v2) — GCM v2-aware services (GTM, GA, Hotjar, Clarity, LinkedIn, TikTok) always run in the worker and self-restrict based on consent state. Meta Pixel uses its own Limited Data Use (LDU) toggle. Other services are blocked until consent is granted via the WP Consent API.

The plugin uses a per-service consent gate so that each script class is handled by the most appropriate mechanism:

Script class Condition Output type
GCM v2-aware service GCM v2 enabled text/partytown (always — service self-restricts)
Meta Pixel Meta LDU enabled text/partytown (always — fbq LDU stub injected)
Any other service Consent Gate ON + wp_has_consent($category) true text/partytown
Any other service Consent Gate ON + no consent text/plain (browser blocked)
Any other service Consent Gate OFF (default) text/partytown (unconditional)

GCM v2-aware services

These services implement the Google Consent Mode v2 API and adjust their own data collection when consent is denied. The plugin always loads them into the Partytown worker and lets them handle consent internally:

googletagmanager.com · google-analytics.com · static.hotjar.com · script.hotjar.com · clarity.ms · snap.licdn.com (LinkedIn) · analytics.tiktok.com

Developers can extend this list via the dc_swp_gcm_v2_aware_services filter.

Consent Gate — WP Consent API

The optional Consent Gate delegates consent decisions to the WP Consent API standard. When enabled:

  • Scripts are output as type="text/plain" with a data-wp-consent-category attribute until the visitor grants consent for that category.
  • A consent-change listener (consent-gate.js) dynamically unblocks scripts when consent is granted, swapping text/plain to text/partytown.
  • Each inline script block has its own configurable consent category (marketing, statistics, statistics-anonymous, functional, preferences).
  • The Script List default category is configurable in the admin settings.
  • Any CMP that integrates with the WP Consent API is automatically supported — no per-CMP cookie reading code is required.

Known limitations

Full-page caching + Meta Pixel consent The fbq("consent","revoke"/"grant") and LDU stubs are injected by PHP at request time. If a full-page cache plugin (WP Rocket, Nginx FastCGI, static HTML) serves a cached page without invoking PHP, the stub is baked in with the consent state of whoever filled the cache — not the current visitor's. Use per-visitor cache keys, fragment caching, or disable full-page caching for logged-out visitors.

Meta Pixel with Gate OFF and LDU OFF If both the Meta LDU toggle and the Consent Gate are disabled, Meta Pixel fires with no fbq("consent",...) call. Meta receives data without any explicit consent declaration from this plugin. Enable Meta LDU, the Consent Gate, or both to emit meaningful consent signals.


How Partytown works

  1. Scripts matching your configured patterns are output with type="text/partytown" — this tells the browser not to execute them on the main thread.
  2. A Web Worker receives and executes those scripts entirely off the main thread.
  3. JavaScript Proxies replicate main-thread APIs (DOM reads/writes) synchronously inside the worker — third-party scripts run exactly as coded, without modification.
  4. Communication between the web worker and main thread uses one of two bridges:
    • Atomics bridge (crossOriginIsolated active) — worker writes a request into a SharedArrayBuffer slot and calls Atomics.wait() to block; main thread reads the slot, writes the response, and calls Atomics.notify() to wake the worker. No service worker involved. Roughly 10× faster round-trips. Enabled via the COI Headers setting.
    • Service Worker bridge (fallback when COI is unavailable) — worker makes a synchronous XHR to a synthetic URL; a registered service worker intercepts it, relays the message to the main thread, and returns the response as the XHR body.

Architecture

Page request (PHP)
  └─ dc_swp_partytown_script_attrs()  ← per-service consent gate
       ├─ GCM v2-aware service + GCM v2 enabled  → type="text/partytown" (service self-restricts)
       ├─ Meta Pixel + Meta LDU enabled           → type="text/partytown" (fbq LDU stub active)
       ├─ Other service + marketing consent       → type="text/partytown"
       └─ Other service + no consent              → type="text/plain"  (browser blocked)

Key features

  • No npm / no build step — Partytown lib files are vendored in assets/partytown/
  • Auto-detect — one-click scan in admin discovers external scripts on your homepage
  • Pattern-based — enter one URL pattern per line; full URLs and partial patterns both work
  • Consent Gate (WP Consent API) — optional toggle blocks scripts as text/plain until the visitor grants consent via any CMP that integrates with the WP Consent API; per-script consent category support
  • GCM v2 per-service gate — GCM v2-aware services always run in the worker and self-restrict; Meta Pixel uses LDU
  • Consent Architecture panel — collapsible admin panel shows GCM v2-aware services and Meta LDU badges (shields.io SVGs + offline CSS fallback)
  • Bot-safe — bots receive no Partytown JS (clean HTML for crawlers)
  • Cart/checkout safe — Partytown uses the Service Worker bridge on cart, checkout, and account pages (Atomics bridge auto-disabled); analytics scripts still fire without breaking payment gateways
  • Bilingual admin — English default, Danish auto-detected from WP locale
  • Weekly auto-updates — GitHub Actions workflow opens a PR when a new Partytown release is detected

Installation

  1. Upload the dc-script-worker-prefetcher folder to /wp-content/plugins/.
  2. Activate from the Plugins screen.
  3. Go to SW Prefetch in the admin menu.
  4. Add URL patterns for any third-party scripts you want to offload (e.g. analytics.ahrefs.com or the full GTM URL). Use the Auto-Detect button to scan your homepage.
  5. Save.

The window.partytown.forward array is pre-configured for all officially tested services: dataLayer.push (GTM), fbq (Facebook Pixel), _hsq.push (HubSpot), Intercom, _learnq.push (Klaviyo), ttq.track/ttq.page/ttq.load (TikTok Pixel), mixpanel.track (Mixpanel), FS.identify/FS.event (FullStory). See partytown.qwik.dev/common-services for details.


Updating the vendored Partytown library

Automatic: the update-partytown.yml workflow runs every Monday at 08:00 UTC.

Manual:

# Latest release
bash scripts/update-partytown.sh

# Pin a specific version
bash scripts/update-partytown.sh 0.11.2

Then commit assets/partytown/ and package.json.


Repository structure

dc-script-worker-prefetcher.php   — Main plugin file
admin.php                         — Admin settings page (EN/DA)
uninstall.php                     — Cleanup on deletion
assets/partytown/                 — Vendored Partytown lib (do NOT hand-edit)
scripts/                          — update-partytown.sh
.github/workflows/                — deploy.yml, update-partytown.yml
package.json                      — Tracks vendored Partytown version
languages/                        — .pot translation template

External Services

This plugin runs third-party scripts off the main thread using the vendored Partytown library. It only connects to services you explicitly configure.

Partytown library

The Partytown JavaScript library is fully vendored inside the plugin (assets/partytown/). No files are downloaded from any CDN at runtime; the library is loaded from your own server.

CORS proxy (server-side script relay)

Some third-party CDNs do not send CORS headers, which prevents Partytown's sandbox from fetching their scripts directly from the browser. The plugin provides a /~partytown-proxy endpoint: WordPress makes a server-side HTTP GET request to the CDN and re-serves the script to the browser.

  • What is sent: the script file request only — no visitor personal data.
  • When: only when Partytown cannot fetch a script directly, and only for hostnames the administrator has added to the Partytown Script List.
  • Allowlist-only: the proxy strictly rejects any hostname not configured by the administrator.

Third-party analytics and marketing scripts (administrator-configured)

When the administrator adds a service's URL pattern to the Partytown Script List, that service's script loads inside a Web Worker (via Partytown) for visitors who have granted marketing consent. The visitor's browser (or the CORS proxy) contacts the service's CDN, and the service may receive visitor data per its own terms.

Scripts are only loaded when:

  1. The administrator has added the service's URL pattern to the Partytown Script List or Inline Script Blocks.
  2. If the Consent Gate is enabled, the visitor has granted consent for the script's category via the WP Consent API. Without consent, scripts are blocked (type="text/plain"). If the Consent Gate is disabled (default), scripts load unconditionally.

The plugin ships pre-configured forwarding for these officially tested services:

Service Provider Data sent Privacy Terms
Google Tag Manager / GA4 Google LLC Page URL, visitor interactions Privacy Terms
Meta (Facebook) Pixel Meta Platforms, Inc. Page URL, events, hashed identifiers Privacy Terms
HubSpot Analytics HubSpot, Inc. Page views, form interactions Privacy Terms
Intercom Intercom R&D Unlimited Company Visitor identity, page views, events Privacy Terms
Klaviyo Klaviyo, Inc. Page views, cart/checkout events, email Privacy Terms
TikTok Pixel TikTok Inc. / ByteDance Ltd. Page views, events, hashed identifiers Privacy Terms
Mixpanel Mixpanel, Inc. Page views, events, anonymous visitor ID Privacy Terms
FullStory FullStory, Inc. Session replay, events, visitor identity Privacy Terms

The administrator may configure additional services via the Partytown Script List. Refer to each service's own privacy policy and terms of service for details on collected data.


Changelog

3.1.0

  • Fix: Inline Script Blocks rebuilt as Script Center — JS is sanitised with sanitize_text_field() at save time and always rendered as type="text/plain" (consent-gated); no arbitrary script execution path remains.
  • Fix: Removed PayPal 1×1 tracking pixel and paypalobjects.com donate image; replaced with a plain text button.
  • Fix: Removed all img.shields.io requests from admin UI; Consent Architecture panel now uses pure-CSS badges.
  • Fix: Added FullStory to readme.txt External Services section.
  • Fix: All external `