### Install Composer Merge Plugin Source: https://partytown.qwik.dev/drupal Install the wikimedia composer-merge-plugin if it is not already present. ```bash composer require wikimedia/composer-merge-plugin ``` -------------------------------- ### Install Partytown with npm, yarn, or pnpm Source: https://partytown.qwik.dev/gatsby Install the @qwik.dev/partytown package using your preferred package manager. Choose one command based on your environment. ```bash npm install @qwik.dev/partytown ``` ```bash yarn add @qwik.dev/partytown ``` ```bash pnpm install @qwik.dev/partytown ``` -------------------------------- ### Install PartyTown JS library via Composer Source: https://partytown.qwik.dev/drupal Install the PartyTown JS library using Composer. ```bash composer require quikdev/partytown ``` -------------------------------- ### Install @nuxtjs/partytown Source: https://partytown.qwik.dev/nuxt Install the @nuxtjs/partytown module as a development dependency using npm, yarn, or pnpm. ```bash npm install --save-dev @nuxtjs/partytown yarn add --dev @nuxtjs/partytown pnpm install --save-dev @nuxtjs/partytown ``` -------------------------------- ### Install Partytown with astro add Source: https://partytown.qwik.dev/astro Commands to automatically install and configure the Partytown integration for Astro. Choose the command matching your package manager (npm, yarn, or pnpm). ```bash npx astro add partytown ``` ```bash yarn astro add partytown ``` ```bash pnpx astro add partytown ``` -------------------------------- ### Vanilla Config resolveUrl Example Source: https://partytown.qwik.dev/proxying-requests Configures Partytown to intercept and proxy specific script URLs. ```javascript partytown = { resolveUrl: function (url, location, type) { if (type === "script") { var proxyUrl = new URL("https://my-reverse-proxy.com/"); proxyUrl.searchParams.append("url", url.href); return proxyUrl; } return url; }, }; ``` -------------------------------- ### Vanilla Partytown Configuration Example Source: https://partytown.qwik.dev/configuration Demonstrates setting the debug configuration option in a vanilla environment. The configuration script must be placed before the Partytown snippet script and should not use the type="text/partytown" attribute. ```html Vanilla Config Example ... ``` -------------------------------- ### Install Drupal PartyTown module via Composer Source: https://partytown.qwik.dev/drupal Use Composer to download the PartyTown module for Drupal. ```bash composer require drupal/partytown ``` -------------------------------- ### Third-party service global variable initialization Source: https://partytown.qwik.dev/forwarding-events Example of how services like Google Tag Manager and Facebook Pixel initialize global variables on the window object. ```javascript // Google Tag Manager window.dataLayer = []; // Facebook Events window.fbq = function(){...}; ``` -------------------------------- ### Minimal Partytown setup with static HTML Source: https://partytown.qwik.dev/html Set up a minimal static page with Partytown: download the library files into a ~partytown directory, serve the folder with Python's HTTP server, and include the partytown.js script plus a text/partytown script that logs a message from a web worker. The /~partytown/ directory must be served from your own origin. ```bash mkdir -p demo/~partytown && cd demo/~partytown curl -O -L https://unpkg.com/@qwik.dev/partytown@latest/lib/partytown.js curl -O -L https://unpkg.com/@qwik.dev/partytown@latest/lib/partytown-sw.js cd .. && python3 -m http.server 8080 ``` ```html ``` -------------------------------- ### Install Partytown NPM package Source: https://partytown.qwik.dev/getting-started Use this command to add the Partytown package to your project dependencies. ```bash npm install @qwik.dev/partytown ``` -------------------------------- ### Synchronous DOM Access Example Source: https://partytown.qwik.dev/how-does-partytown-work Demonstrates how code within a web worker can access DOM properties synchronously without using async/await or callbacks. ```javascript const rect = element.getBoundingClientRect(); console.log(rect.x, rect.y); ``` -------------------------------- ### Copy library files to static/~partytown using onPreBuild Source: https://partytown.qwik.dev/gatsby Example of using Gatsby's onPreBuild extension point in gatsby-node.js to copy Partytown library files to the static directory. Note that onPreBuild is only called during build; use onPreBootstrap for development. ```javascript const path = require("path"); const { copyLibFiles } = require("@qwik.dev/partytown/utils"); exports.onPreBuild = async () => { await copyLibFiles(path.join(__dirname, "static", "~partytown")); }; ``` -------------------------------- ### Install perspective/magento2-partytown via Composer Source: https://partytown.qwik.dev/magento2 Install the Magento 2 Partytown integration module. Requires PHP 8.1+, Magento 2.4.4+, and Node.js v16+. After running these commands, clear all caches. ```bash composer config repositories.perspective-magento2-partytown git git@github.com:rostilos/perspective-partytown.git composer require perspective/magento2-partytown dev-master php bin/magento setup:upgrade bin/magento setup:di:compile php bin/magento setup:static-content:deploy ``` -------------------------------- ### npm scripts for copying Partytown lib before Next.js build Source: https://partytown.qwik.dev/copy-library-files Example npm scripts that run the partytown copylib command before a Next.js build. The build script runs the partytown script first, then next build. ```json { "scripts": { "build": "npm run partytown && next build", "partytown": "partytown copylib 'public/~partytown'" } } ``` -------------------------------- ### Add Partytown NPM script Source: https://partytown.qwik.dev/nextjs Example of adding a partytown script to package.json to copy library files to the public directory before building. ```json "scripts": { "build": "npm run partytown && next build", "partytown": "partytown copylib public/~partytown" } ``` -------------------------------- ### Configure Partytown with forward for GTM Source: https://partytown.qwik.dev/html Configure Partytown by setting the partytown global object on window before the inlined snippet. This example forwards dataLayer.push for Google Tag Manager. ```html ``` -------------------------------- ### Laravel Mix copy for Partytown lib Source: https://partytown.qwik.dev/copy-library-files Laravel Mix configuration using Mix's copy() to copy the Partytown lib directory to the public/~partytown/ directory. Uses partytown.libDirPath() to get the source directory. ```javascript // webpack.mix.js const mix = require("laravel-mix"); const partytown = require("@qwik.dev/partytown/utils"); mix.copy(partytown.libDirPath(), "public/~partytown"); ``` -------------------------------- ### Configure Partytown component in root Source: https://partytown.qwik.dev/remix Example of including the Partytown component in the Remix app root component's head section, configured for Google Tag Manager. ```jsx import { Partytown } from "@qwik.dev/partytown/react"; import { Links, Meta, Outlet } from "@remix-run/react"; export default function App() { return ( ... ); } ``` -------------------------------- ### Configure Partytown in Next.js Head Source: https://partytown.qwik.dev/nextjs Example of including the Partytown component within the Next.js Head and marking an analytics script with type="text/partytown". ```jsx import Head from "next/head"; import { Partytown } from "@qwik.dev/partytown/react"; const Home = () => { return ( <> My App {@html ''} ``` -------------------------------- ### Copy Partytown lib files with copyLibFiles API Source: https://partytown.qwik.dev/copy-library-files Imports the copyLibFiles API from @qwik.dev/partytown/utils and copies the lib files to the given directory. Both ESM and CommonJS imports are shown. The function is async and should be awaited. ```javascript import { copyLibFiles } from "@qwik.dev/partytown/utils"; // ESM // const { copyLibFiles } = require('@qwik.dev/partytown/utils'); // CommonJS async function myBuildTask() { await copyLibFiles("path/to/public/~partytown"); } ``` -------------------------------- ### Get Partytown snippet string Source: https://partytown.qwik.dev/distribution Use the partytownSnippet function to retrieve the code string for inlining into the document head. ```javascript import { partytownSnippet } from "@qwik.dev/partytown/integration"; const snippetText = partytownSnippet(); ``` -------------------------------- ### Set up Partytown scripts in index.html Source: https://partytown.qwik.dev/angular Set up Partytown in your index.html file. The first script tag holds the Partytown configuration, the second references the Partytown JS file, and the third loads third-party scripts on the web worker. ```html /* Partytown config properties */ /* Inlined Partytown Snippet */ ``` -------------------------------- ### Vite config with partytownVite plugin Source: https://partytown.qwik.dev/copy-library-files Vite configuration using the partytownVite plugin to copy the Partytown lib directory to the given destination. The destination must be an absolute file path. The copying happens at the writeBundle() hook, and in dev mode the lib files are served by the Vite Dev Server. ```javascript // vite.config.js import path from "path"; import { partytownVite } from "@qwik.dev/partytown/utils"; export default ({ command }) => ({ plugins: [ partytownVite({ dest: path.join(__dirname, "dist", "~partytown"), }), ], }); ``` -------------------------------- ### Rollup config with partytownRollup plugin Source: https://partytown.qwik.dev/copy-library-files Rollup configuration using the partytownRollup plugin to copy the Partytown lib directory to the given destination. The destination must be an absolute file path. The copying happens at the writeBundle() hook. ```javascript // rollup.config.js import path from "path"; import { partytownRollup } from "@qwik.dev/partytown/utils"; export default { plugins: [ partytownRollup({ dest: path.join(__dirname, "dist", "~partytown"), }), ], }; ``` -------------------------------- ### Copy Partytown library files with partytown copylib Source: https://partytown.qwik.dev/shopify-hydrogen Add a "partytown" NPM script that runs the partytown copylib CLI to copy library files to public/~partytown. This script should run before the build. ```json "scripts": { "dev": "npm run partytown && vite", "build": "npm run partytown && yarn build:client && yarn build:server && yarn build:worker", "build:client": "vite build --outDir dist/client --manifest", "build:server": "vite build --outDir dist/server --ssr src/entry-server.jsx", "build:worker": "cross-env WORKER=true vite build --outDir dist/worker --ssr worker.js", "partytown": "partytown copylib public/~partytown" } ``` -------------------------------- ### Update package.json Scripts Source: https://partytown.qwik.dev/tanstack-start Automate the library file copy process by adding it to your development and build scripts. ```json { "scripts": { "dev": "partytown copylib public/~partytown && vite dev", "build": "partytown copylib public/~partytown && vite build" } } ``` -------------------------------- ### Merge PartyTown library configuration Source: https://partytown.qwik.dev/drupal Configure the merge plugin to include the PartyTown library composer file. ```bash composer config extra.merge-plugin.include --json '[ "web/modules/contrib/partytown/composer.libraries.json" ]' ``` -------------------------------- ### HTML img with crossorigin attribute for COEP require-corp Source: https://partytown.qwik.dev/atomics Example of setting the crossorigin attribute on an image element to allow cross-origin requests when using Cross-Origin-Embedder-Policy: require-corp. Without this attribute, images from other origins would be blocked. ```html ``` -------------------------------- ### Inline script with type="text/partytown" using dangerouslySetInnerHTML Source: https://partytown.qwik.dev/gatsby Add the type="text/partytown" prop to each script that should run from a web worker. This example shows the React-specific way of inlining a script with dangerouslySetInnerHTML. ```jsx ``` -------------------------------- ### Configure Partytown in gatsby-ssr.js with setHeadComponents Source: https://partytown.qwik.dev/gatsby Example of including the component in gatsby-ssr.js. The component is placed in setHeadComponents, and the analytics script uses type="text/partytown". Also includes a noscript tag for GTM added to the body via setPreBodyComponents. ```jsx import React from "react"; import { Partytown } from "@qwik.dev/partytown/react"; export const onRenderBody = ({ setHeadComponents, setPreBodyComponents }) => { setHeadComponents([ , ``` -------------------------------- ### Configure Partytown with debug and forward props in React Source: https://partytown.qwik.dev/react Import the Partytown component from the @qwik.dev/partytown/react submodule and set the debug config to true and forward config for Google Tag Manager. The config properties are passed as JSX props. ```jsx import { Partytown } from "@qwik.dev/partytown/react"; export function Head() { return ( <> ); } ``` -------------------------------- ### Configure Partytown in Shopify Hydrogen root component Source: https://partytown.qwik.dev/shopify-hydrogen Import Partytown from @qwik.dev/partytown/react and include it in the root App component before DefaultSeo. The forward prop is set for Google Tag Manager. ```jsx import { DefaultRoutes } from "@shopify/hydrogen"; import { Suspense } from "react"; import DefaultSeo from "./components/DefaultSeo.server"; import NotFound from "./components/NotFound.server"; import AppClient from "./App.client"; import LoadingFallback from "./components/LoadingFallback"; import { Partytown } from "@qwik.dev/partytown/react"; export default function App({ log, pages, ...serverState }) { return ( }> } /> ); } ``` -------------------------------- ### Nuxt 3 server handler to proxy connect.facebook.net Source: https://partytown.qwik.dev/facebook-pixel A Nuxt 3 API route that dynamically fetches resources from `connect.facebook.net` and returns them with CORS and caching headers. Throws a 500 error for invalid URLs or fetch failures. ```javascript export default defineEventHandler(async (event) => { const query = getQuery(event); const url = String(query?.url) || null; if (!url || !url.includes("connect.facebook.net")) { throw createError({ status: 500, message: "Invalid URL", }); } // Fetch the file content dynamically based on the URL const response = await $fetch(url).catch((error) => { throw createError({ status: 500, message: `Failed to fetch resource: ${error.message}`, }); }); setResponseHeaders(event, { "Access-Control-Allow-Origin": "*", // Ensures proper CORS handling "Access-Control-Allow-Headers": "Content-Type, Authorization", "Access-Control-Allow-Methods": "POST, GET, OPTIONS, PUT, DELETE", "Content-Type": "application/x-javascript; charset=utf-8", "Cache-Control": "public, max-age=5, s-maxage=5, stale-if-error=2678400, stale-while-revalidate=86400", // Add necessary caching headers }); return response; }); ``` -------------------------------- ### Advanced forward configuration with preserveBehavior Source: https://partytown.qwik.dev/forwarding-events Customizing forwarding behavior for specific variables, allowing calls to execute on the main thread while still being forwarded to the web worker. ```html ``` -------------------------------- ### Partytown distribution directory structure Source: https://partytown.qwik.dev/distribution The root directory structure of the @qwik.dev/partytown package. ```text @qwik.dev/partytown/ ├── integration/ ├── lib/ ├── react/ ├── services/ └── utils/ ``` -------------------------------- ### FullStory with Google Tag Manager: strictProxyHas configuration Source: https://partytown.qwik.dev/common-services When loading FullStory via Google Tag Manager (GTM), you need to enable the `strictProxyHas` configuration option. This is because FullStory checks for namespace conflicts using the `in` operator (e.g., `if (!("FS" in window))`), and by default, Partytown's window proxy always returns `true` for the `in` operator for backwards compatibility. Without `strictProxyHas: true`, FullStory will detect a false "namespace conflict" and fail to initialize when loaded via GTM's Custom HTML tag. ```javascript ``` -------------------------------- ### Partytown lib directory contents Source: https://partytown.qwik.dev/distribution The static files in the lib directory that must be hosted from the same origin as the website. ```text @qwik.dev/partytown/lib/ ├── partytown-atomics.js ├── partytown-media.js ├── partytown-sw.js └── partytown.js ``` -------------------------------- ### Partytown configuration for Facebook Pixel Source: https://partytown.qwik.dev/facebook-pixel Partytown config that proxies `connect.facebook.net` requests to a reverse proxy and forwards `fbq` calls to `window.fbq`. The `resolveUrl` function rewrites the URL to the proxy with the original URL as a query parameter. ```javascript // https://partytown.qwik.dev/configuration { resolveUrl: function(url) { if (url.hostname === "connect.facebook.net") { var proxyUrl = new URL('https://my-reverse-proxy.com/'); proxyUrl.searchParams.append('url', url.href); return proxyUrl; } return url; }, forward: [ "fbq" ] } ``` -------------------------------- ### Configure assets in angular.json for Partytown Source: https://partytown.qwik.dev/angular Add the Partytown library files to the assets array in your angular.json file. The glob pattern copies all files from the Partytown lib directory to the /~partytown output path. ```json "projects": { ... "{project-name}": { ... "architect": { ... "build": { ... "options": { "assets": [... { "glob": "**/*", "input": "node_modules/@qwik.dev/partytown/lib", "output": "/~partytown" } ] } } } } } ``` -------------------------------- ### Configure nuxt.config.ts with @nuxtjs/partytown Source: https://partytown.qwik.dev/nuxt Configure Nuxt to use the Partytown module by adding it to the modules array and using the partytown property for Partytown-specific settings. ```typescript import { defineNuxtConfig } from "nuxt"; export default defineNuxtConfig({ modules: ["@nuxtjs/partytown"], partytown: { /* any partytown-specific configuration */ }, }); ```