Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
911b04d
feat(linkedin-insight): add LinkedInInsightOptions schema
zizzfizzix May 2, 2026
966fb08
feat(linkedin-insight): add useScriptLinkedInInsight composable
zizzfizzix May 2, 2026
0536203
fix(linkedin-insight): align Window types and move SPA hook into clie…
zizzfizzix May 2, 2026
ef66758
feat(linkedin-insight): add logo
zizzfizzix May 2, 2026
a8284b8
feat(linkedin-insight): register in metadata and async registry
zizzfizzix May 2, 2026
6b72651
chore(linkedin-insight): regenerate registry-types.json
zizzfizzix May 2, 2026
da0929e
feat(linkedin-insight): use LinkedIn-official logo with light/dark va…
zizzfizzix May 2, 2026
3d15aaa
feat(linkedin-insight): add script-meta entry
zizzfizzix May 2, 2026
b494593
test(linkedin-insight): assert registry type is not any
zizzfizzix May 2, 2026
dfff90b
test(linkedin-insight): add proxy-config assertions
zizzfizzix May 2, 2026
480c630
test(linkedin-insight): add to first-party supported scripts list
zizzfizzix May 2, 2026
4851936
test(linkedin-insight): add first-party fixture page
zizzfizzix May 2, 2026
e7690fe
docs(linkedin-insight): add docs page with examples
zizzfizzix May 2, 2026
5453a86
docs(linkedin-insight): clear lint warnings in docs page
zizzfizzix May 2, 2026
ab3ba6b
fix(linkedin-insight): reject empty Partner ID array at schema time
zizzfizzix May 3, 2026
ef95bac
fix(linkedin-insight): preserve full arity in lintrk queue stub
zizzfizzix May 3, 2026
01f1cc5
fix(linkedin-insight): use page:finish hook for SPA tracking
zizzfizzix May 3, 2026
2bb702b
test(linkedin-insight): add e2e suite with bundled and CDN fixtures
zizzfizzix May 3, 2026
281318a
docs(linkedin-insight): add to first-party guides and SPA tracking notes
zizzfizzix May 3, 2026
fc7e3fa
chore(linkedin-insight): add playground demo
zizzfizzix May 3, 2026
41e3d4b
Merge branch 'main' into feat/script-registry/linkedin
zizzfizzix May 3, 2026
067cd25
test(linkedin-insight): probe egress and skip beacon assertions when …
zizzfizzix May 3, 2026
214abdc
chore(linkedin-insight): make placeholder ids more obvious
zizzfizzix May 3, 2026
0b07b39
test(linkedin-insight): replace fixed sleeps with deterministic polling
zizzfizzix May 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion FIRST_PARTY.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Four presets in `proxy-configs.ts` cover all proxy-enabled scripts:
| Preset | Flags | Used by |
|---|---|---|
| `PRIVACY_NONE` | all false | (not currently assigned to any script) |
| `PRIVACY_FULL` | all true | Meta, TikTok, X, Snap, Reddit |
| `PRIVACY_FULL` | all true | Meta, TikTok, X, Snap, Reddit, LinkedIn |
| `PRIVACY_HEATMAP` | ip, language, hardware | GA, Clarity, Hotjar |
| `PRIVACY_IP_ONLY` | ip only | PostHog, Plausible, Umami, Rybbit, Databuddy, Fathom, CF Web Analytics, Vercel, Matomo, Carbon Ads, Lemon Squeezy, Intercom, Gravatar, YouTube, Vimeo |

Expand All @@ -127,6 +127,7 @@ Note: GTM, Segment, Crisp, Mixpanel, and Bing UET are bundle-only (no proxy capa
| `xPixel` | xPixel | `PRIVACY_FULL` | Path A |
| `snapchatPixel` | snapchatPixel | `PRIVACY_FULL` | Path A |
| `redditPixel` | redditPixel | `PRIVACY_FULL` | Path A |
| `linkedinInsight` | linkedinInsight | `PRIVACY_FULL` | Path A |
| `clarity` | clarity | `PRIVACY_HEATMAP` | Path A |
| `hotjar` | hotjar | `PRIVACY_HEATMAP` | Path A |
| `posthog` | posthog | `PRIVACY_IP_ONLY` | **Path B** (npm-only) + autoInject |
Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/1.guides/2.first-party.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@

| Tier | What's anonymised | Scripts |
|------|-------------------|---------|
| **Full** | IP, user agent, language, screen, timezone, hardware fingerprints | Meta Pixel, TikTok Pixel, X Pixel, Snapchat Pixel, Reddit Pixel |
| **Full** | IP, user agent, language, screen, timezone, hardware fingerprints | Meta Pixel, TikTok Pixel, X Pixel, Snapchat Pixel, Reddit Pixel, LinkedIn Insight Tag |
| **Heatmap-safe** | IP, language, hardware fingerprints (preserves screen and user agent for session replay) | Google Analytics, Microsoft Clarity, Hotjar |
| **IP only** | IP addresses anonymised to subnet level | Plausible, PostHog, Umami, Fathom, CF Web Analytics, Vercel Analytics, Rybbit, Databuddy, Matomo, Intercom, YouTube, Vimeo, Gravatar, Carbon Ads, Lemon Squeezy, Google AdSense |

Expand Down Expand Up @@ -180,7 +180,7 @@

### Static Hosting (SSG)

The reverse proxy requires a **server runtime**. For static deployments (`nuxt generate`), the proxy is automatically disabled. Scripts are still bundled and served from your domain, but runtime collection requests (analytics beacons, pixel fires) go directly to third-party servers.

Check warning on line 183 in docs/content/docs/1.guides/2.first-party.md

View workflow job for this annotation

GitHub Actions / lint

Passive voice: "is automatically disabled". Consider rewriting in active voice

If you need proxying with static hosting, configure platform-level rewrites manually. The pattern is `/_scripts/p/<domain>/:path*` → `https://<domain>/:path*`:

Expand Down Expand Up @@ -324,7 +324,7 @@
| Category | Scripts |
|----------|---------|
| **Analytics** | [Google Analytics](/scripts/google-analytics), [Plausible](/scripts/plausible-analytics), [Cloudflare Web Analytics](/scripts/cloudflare-web-analytics), [Umami](/scripts/umami-analytics), [Fathom](/scripts/fathom-analytics), [Rybbit](/scripts/rybbit-analytics), [Databuddy](/scripts/databuddy-analytics), [Vercel Analytics](/scripts/vercel-analytics), [Microsoft Clarity](/scripts/clarity), [Hotjar](/scripts/hotjar) |
| **Ad Pixels** | [Meta Pixel](/scripts/meta-pixel), [TikTok Pixel](/scripts/tiktok-pixel), [X Pixel](/scripts/x-pixel), [Snapchat Pixel](/scripts/snapchat-pixel), [Reddit Pixel](/scripts/reddit-pixel), [Google AdSense](/scripts/google-adsense) |
| **Ad Pixels** | [Meta Pixel](/scripts/meta-pixel), [TikTok Pixel](/scripts/tiktok-pixel), [X Pixel](/scripts/x-pixel), [Snapchat Pixel](/scripts/snapchat-pixel), [Reddit Pixel](/scripts/reddit-pixel), [LinkedIn Insight Tag](/scripts/linkedin-insight), [Google AdSense](/scripts/google-adsense) |
| **Video** | [YouTube Player](/scripts/youtube-player), [Vimeo Player](/scripts/vimeo-player) |
| **Utility** | [Intercom](/scripts/intercom), [Gravatar](/scripts/gravatar) |

Expand Down Expand Up @@ -461,7 +461,7 @@
| Problem | Fix |
|---------|-----|
| Analytics not tracking | Check DevTools → Network for `/_scripts/p/` requests. Check Nitro server logs for proxy errors |
| Proxy not working on static site | The reverse proxy is automatically disabled for SSG. Use platform rewrites or switch to server mode. See [Static Hosting](#static-hosting-ssg) |

Check warning on line 464 in docs/content/docs/1.guides/2.first-party.md

View workflow job for this annotation

GitHub Actions / lint

Passive voice: "is automatically disabled". Consider rewriting in active voice
| Stale script | `rm -rf .nuxt/cache/scripts` and rebuild |
| Build download fails | Set `assets.fallbackOnSrcOnBundleFail: true`{lang="ts"} to fall back to direct loading |
| Debugging | Open Nuxt DevTools → Scripts to see proxy routes and privacy status |
Expand Down
114 changes: 114 additions & 0 deletions docs/content/scripts/linkedin-insight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
title: LinkedIn Insight Tag
description: Use the LinkedIn Insight Tag in your Nuxt app to track conversions, retarget visitors, and learn about your audience.
links:
- label: Source
icon: i-simple-icons-github
to: https://github.com/nuxt/scripts/blob/main/packages/script/src/runtime/registry/linkedin-insight.ts
size: xs
---

The [LinkedIn Insight Tag](https://business.linkedin.com/marketing-solutions/insight-tag) is a lightweight JavaScript snippet for conversion tracking, retargeting, and audience insights on LinkedIn Ads campaigns.

Nuxt Scripts provides a registry script composable [`useScriptLinkedInInsight()`{lang="ts"}](/scripts/linkedin-insight) to integrate it in your Nuxt app.

::script-stats
::

::script-docs
::

::script-types
::

## Examples

### Tracking a conversion

```vue
<script setup lang="ts">
const { proxy } = useScriptLinkedInInsight({
id: '111143',
})

function trackPurchase() {
proxy.lintrk('track', { conversion_id: 1111111177 })
}
</script>
```

### Per-event deduplication with the Conversions API

When you also send conversions through LinkedIn's server-side Conversions API, pass the same `event_id` to both. LinkedIn discards the server-side duplicate and counts the Insight Tag event. See [LinkedIn deduplication](https://learn.microsoft.com/en-us/linkedin/marketing/conversions/deduplication?view=li-lms-2026-01).

```vue
<script setup lang="ts">
const { proxy } = useScriptLinkedInInsight({
id: '111143',
})

function trackSignup() {
const eventId = crypto.randomUUID()
proxy.lintrk('track', { conversion_id: 1111111177, event_id: eventId })
// Send the same eventId to your server-side Conversions API call.
}
</script>
```

### Page-load conversion deduplication

For dedup on the auto-fired page-view, set `eventId` at registration. The composable assigns `window._linkedin_event_id` *before* the Insight Tag base code runs, so the page-view URL includes `&eventId=…` automatically.

```vue
<script setup lang="ts">
const { proxy } = useScriptLinkedInInsight({
id: '111143',
eventId: 'page-load-event-id-123',
})
</script>
```

### Enhanced matching with `setUserData`

Pass plain email; the Insight Tag SHA-256 hashes it on-device. See [LinkedIn enhanced matching](https://www.linkedin.com/help/lms/answer/a6246095).

```vue
<script setup lang="ts">
const { proxy } = useScriptLinkedInInsight({
id: '111143',
})

function onSignupSuccess(email: string) {
proxy.lintrk('setUserData', { email })
}
</script>
```

The Insight Tag stores the hashed email in `localStorage["li_hem"]` and transmits it on the next page-view via a separate POST to `https://px.ads.linkedin.com/wa/...` (the WebsiteActions gateway). The `/collect` URL of the page-view immediately following `setUserData` does not carry it; LinkedIn picks it up on the next full page load when the bootstrap reads it back from `localStorage`.

### SPA virtual page views

By default, the Insight Tag fires a page-view exactly once when the script loads, so SPA route changes go untracked. Opt in to per-route tracking with `enableAutoSpaTracking`:

```vue
<script setup lang="ts">
useScriptLinkedInInsight({
id: '111143',
enableAutoSpaTracking: true,
})
</script>
```

When enabled, the composable suppresses the script's built-in auto-page-view (via `window._wait_for_lintrk = true`) and fires `lintrk('track')`{lang="ts"} on Nuxt's `page:finish` hook instead, so each route (including the initial page) produces exactly one `/collect` beacon.

### Multiple Partner IDs

If you need to push more than one Partner ID onto `window._linkedin_data_partner_ids`, pass an array. The composable promotes the first ID to the primary `_linkedin_partner_id` global.

```vue
<script setup lang="ts">
useScriptLinkedInInsight({
id: ['111143', '111154'],
})
</script>
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"dev": "nuxt dev playground",
"dev:ssl": "nuxt dev playground --https",
"dev:prepare": "pnpm -r dev:prepare && nuxt prepare && nuxt prepare playground && pnpm prepare:fixtures",
"prepare:fixtures": "nuxt prepare test/fixtures/basic && nuxt prepare test/fixtures/cdn && nuxt prepare test/fixtures/extend-registry && nuxt prepare test/fixtures/partytown && nuxt prepare test/fixtures/first-party",
"prepare:fixtures": "nuxt prepare test/fixtures/basic && nuxt prepare test/fixtures/cdn && nuxt prepare test/fixtures/extend-registry && nuxt prepare test/fixtures/partytown && nuxt prepare test/fixtures/first-party && nuxt prepare test/fixtures/linkedin-insight && nuxt prepare test/fixtures/linkedin-insight-cdn",
"typecheck": "nuxt typecheck",
"release": "pnpm build && bumpp -r --output=CHANGELOG.md",
"lint": "eslint .",
Expand Down
4 changes: 4 additions & 0 deletions packages/script/src/registry-logos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const LOGOS = {
},
tiktokPixel: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path d="M224 72a52.059 52.059 0 0 1-52-52a4 4 0 0 0-4-4h-40a4 4 0 0 0-4 4v132a28 28 0 1 1-40.567-25.019a4 4 0 0 0 2.567-3.734V80a4 4 0 0 0-4.652-3.949A84.032 84.032 0 1 0 156 152v-43.047a99.432 99.432 0 0 0 52 14.586a4 4 0 0 0 4-4V76a4 4 0 0 0-4-4z" fill="currentColor"/></svg>`,
redditPixel: `<svg viewBox="0 0 800 800" xmlns="http://www.w3.org/2000/svg" width="32" height="32"> <circle cx="400" cy="400" fill="#ff4500" r="400"/> <path d="M666.8 400c.08 5.48-.6 10.95-2.04 16.24s-3.62 10.36-6.48 15.04c-2.85 4.68-6.35 8.94-10.39 12.65s-8.58 6.83-13.49 9.27c.11 1.46.2 2.93.25 4.4a107.268 107.268 0 0 1 0 8.8c-.05 1.47-.14 2.94-.25 4.4 0 89.6-104.4 162.4-233.2 162.4S168 560.4 168 470.8c-.11-1.46-.2-2.93-.25-4.4a107.268 107.268 0 0 1 0-8.8c.05-1.47.14-2.94.25-4.4a58.438 58.438 0 0 1-31.85-37.28 58.41 58.41 0 0 1 7.8-48.42 58.354 58.354 0 0 1 41.93-25.4 58.4 58.4 0 0 1 46.52 15.5 286.795 286.795 0 0 1 35.89-20.71c12.45-6.02 25.32-11.14 38.51-15.3s26.67-7.35 40.32-9.56 27.45-3.42 41.28-3.63L418 169.6c.33-1.61.98-3.13 1.91-4.49.92-1.35 2.11-2.51 3.48-3.4 1.38-.89 2.92-1.5 4.54-1.8 1.61-.29 3.27-.26 4.87.09l98 19.6c9.89-16.99 30.65-24.27 48.98-17.19s28.81 26.43 24.71 45.65c-4.09 19.22-21.55 32.62-41.17 31.61-19.63-1.01-35.62-16.13-37.72-35.67L440 186l-26 124.8c13.66.29 27.29 1.57 40.77 3.82a284.358 284.358 0 0 1 77.8 24.86A284.412 284.412 0 0 1 568 360a58.345 58.345 0 0 1 29.4-15.21 58.361 58.361 0 0 1 32.95 3.21 58.384 58.384 0 0 1 25.91 20.61A58.384 58.384 0 0 1 666.8 400zm-396.96 55.31c2.02 4.85 4.96 9.26 8.68 12.97 3.71 3.72 8.12 6.66 12.97 8.68A40.049 40.049 0 0 0 306.8 480c16.18 0 30.76-9.75 36.96-24.69 6.19-14.95 2.76-32.15-8.68-43.59s-28.64-14.87-43.59-8.68c-14.94 6.2-24.69 20.78-24.69 36.96 0 5.25 1.03 10.45 3.04 15.31zm229.1 96.02c2.05-2 3.22-4.73 3.26-7.59.04-2.87-1.07-5.63-3.07-7.68s-4.73-3.22-7.59-3.26c-2.87-.04-5.63 1.07-7.94 2.8a131.06 131.06 0 0 1-19.04 11.35 131.53 131.53 0 0 1-20.68 7.99c-7.1 2.07-14.37 3.54-21.72 4.39-7.36.85-14.77 1.07-22.16.67-7.38.33-14.78.03-22.11-.89a129.01 129.01 0 0 1-21.64-4.6c-7.08-2.14-13.95-4.88-20.56-8.18s-12.93-7.16-18.89-11.53c-2.07-1.7-4.7-2.57-7.38-2.44s-5.21 1.26-7.11 3.15c-1.89 1.9-3.02 4.43-3.15 7.11s.74 5.31 2.44 7.38c7.03 5.3 14.5 9.98 22.33 14s16 7.35 24.4 9.97 17.01 4.51 25.74 5.66c8.73 1.14 17.54 1.53 26.33 1.17 8.79.36 17.6-.03 26.33-1.17A153.961 153.961 0 0 0 476.87 564c7.83-4.02 15.3-8.7 22.33-14zm-7.34-68.13c5.42.06 10.8-.99 15.81-3.07 5.01-2.09 9.54-5.17 13.32-9.06s6.72-8.51 8.66-13.58A39.882 39.882 0 0 0 532 441.6c0-16.18-9.75-30.76-24.69-36.96-14.95-6.19-32.15-2.76-43.59 8.68s-14.87 28.64-8.68 43.59c6.2 14.94 20.78 24.69 36.96 24.69z" fill="#fff"/> </svg>`,
linkedinInsight: {
light: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 34 34"><path fill="#0a66c2" d="M34 2.5v29a2.5 2.5 0 0 1-2.5 2.5h-29A2.5 2.5 0 0 1 0 31.5v-29A2.5 2.5 0 0 1 2.5 0h29A2.5 2.5 0 0 1 34 2.5M10 13H5v16h5zm.45-5.5a2.88 2.88 0 0 0-2.86-2.9H7.5a2.9 2.9 0 0 0 0 5.8 2.88 2.88 0 0 0 2.95-2.81zM29 19.28c0-4.81-3.06-6.68-6.1-6.68a5.7 5.7 0 0 0-5.06 2.58h-.14V13H13v16h5v-8.51a3.32 3.32 0 0 1 3-3.58h.19c1.59 0 2.77 1 2.77 3.52V29h5z"/></svg>`,
dark: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 34 34"><g transform="scale(.7083)" fill="none" fill-rule="evenodd"><rect fill="#fff" x="1" y="1" width="46" height="46" rx="4"/><path fill="#0077b5" d="M0 4.01A4.01 4.01 0 014.01 0h39.98A4.01 4.01 0 0148 4.01v39.98A4.01 4.01 0 0143.99 48H4.01A4.01 4.01 0 010 43.99V4.01zM19 18.3h6.5v3.266C26.437 19.688 28.838 18 32.445 18 39.359 18 41 21.738 41 28.597V41.3h-7V30.159c0-3.906-.937-6.109-3.32-6.109-3.305 0-4.68 2.375-4.68 6.109V41.3h-7v-23zM7 41h7V18H7v23zm8-30.5a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0z"/></g></svg>`,
},
googleAdsense: `<svg xmlns="http://www.w3.org/2000/svg" width="36.09" height="32" viewBox="0 0 256 227"><path fill="#FBBC04" d="M161.8 62.158c11.581-19.822 4.705-45.154-15.355-56.603C126.376-5.878 100.723.899 89.142 20.72c-.51.888-.99 1.794-1.44 2.715L48.553 90.41a49.41 49.41 0 0 0-2.401 4.112L5.495 164.681l72.65 40.721l40.45-69.566a40.013 40.013 0 0 0 2.402-4.112l39.15-66.983a45.769 45.769 0 0 0 1.654-2.583"/><path fill="#34A853" d="M78.483 205.189c-11.515 20.142-37.49 27.553-57.434 15.931c-19.954-11.63-27.036-36.847-15.513-56.982c11.523-20.134 37.267-27.578 57.22-15.956c19.954 11.63 27.241 36.872 15.727 56.998"/><path fill="#4285F4" d="M235.257 75.417c-19.83-11.429-45.17-4.661-56.661 15.134l-41.478 71.67c-11.428 19.755-4.678 45.033 15.076 56.46l.107.062c19.835 11.433 45.18 4.66 56.67-15.142l41.469-71.663c11.426-19.76 4.67-45.042-15.09-56.468z"/></svg>`,
carbonAds: {
light: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><rect width="32" height="32" rx="6" fill="#1E1E1E"/><path transform="translate(9.25,3.5)" d="M2.927 17.98c0 3.248 1.225 4.295 4.933 4.295 1.362 0 3.573-.174 5.31-.488l.305 2.584c-1.633.385-4.015.629-5.717.629C2.212 25 0 22.555 0 18.155V7.887c0-4.401 2.212-6.845 7.759-6.845 1.701 0 4.083.244 5.717.628l-.306 2.585c-1.736-.315-3.948-.49-5.309-.49-3.709 0-4.934 1.049-4.934 4.296v9.92Z" fill="#fff"/></svg>`,
Expand Down
48 changes: 48 additions & 0 deletions packages/script/src/registry-types.json
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,33 @@
"code": "interface ScriptLemonSqueezySlots {\n default?: () => any\n}"
}
],
"linkedin-insight": [
{
"name": "LinkedInInsightOptions",
"kind": "const",
"code": "export const LinkedInInsightOptions = object({\n /**\n * Your LinkedIn Insight Tag Partner ID, or an array of Partner IDs to push\n * onto window._linkedin_data_partner_ids. The first ID is used as the\n * primary _linkedin_partner_id global.\n * @example '111143'\n * @example ['111143', '111154']\n * @see https://www.linkedin.com/help/lms/answer/a417869/access-your-linkedin-partner-id\n */\n id: union([pipe(string(), minLength(1)), pipe(array(pipe(string(), minLength(1))), minLength(1))]),\n /**\n * Optional page-load event ID for Conversions API deduplication. Assigned\n * to window._linkedin_event_id BEFORE the Insight Tag base code runs. Must\n * match the eventId sent with the corresponding server-side Conversions\n * API event.\n *\n * Per-event conversion deduplication uses the per-call event_id passed to\n * lintrk('track', { conversion_id, event_id }) instead.\n * @see https://learn.microsoft.com/en-us/linkedin/marketing/conversions/deduplication\n */\n eventId: optional(string()),\n /**\n * Auto-fire lintrk('track') on Vue Router route changes (SPA virtual page\n * views). When true, suppresses the script's built-in auto-page-view via\n * window._wait_for_lintrk and tracks every navigation including the\n * initial page through Nuxt's page:finish hook. When false, the script\n * fires its own page-view exactly once on load and SPA navigations are\n * not tracked unless lintrk('track') is called manually.\n * @default false\n */\n enableAutoSpaTracking: optional(boolean()),\n})"
},
{
"name": "LintrkTrackParams",
"kind": "interface",
"code": "interface LintrkTrackParams {\n conversion_id?: number\n event_id?: string\n commandCallback?: () => void\n [key: string]: any\n}"
},
{
"name": "LintrkUserData",
"kind": "interface",
"code": "interface LintrkUserData {\n /** Plain email; the script SHA-256 hashes it before sending. */\n email: string\n}"
},
{
"name": "LintrkFns",
"kind": "type",
"code": "type LintrkFns\n = & ((cmd: 'track', params?: LintrkTrackParams) => void)\n & ((cmd: 'setUserData', data: LintrkUserData) => void)\n & ((cmd: (string & {}), ...args: any[]) => void)"
},
{
"name": "LinkedInInsightApi",
"kind": "interface",
"code": "export interface LinkedInInsightApi {\n lintrk: LintrkFns & { q?: unknown[] }\n}"
}
],
"matomo-analytics": [
{
"name": "MatomoAnalyticsOptions",
Expand Down Expand Up @@ -2012,6 +2039,27 @@
"description": "Default consent state fired as `uetq.push('consent', 'default', ...)` before UET init."
}
],
"LinkedInInsightOptions": [
{
"name": "id",
"type": "string | string[]",
"required": true,
"description": "Your LinkedIn Insight Tag Partner ID, or an array of Partner IDs to push onto window._linkedin_data_partner_ids. The first ID is used as the primary _linkedin_partner_id global."
},
{
"name": "eventId",
"type": "string",
"required": false,
"description": "Optional page-load event ID for Conversions API deduplication. Assigned to window._linkedin_event_id BEFORE the Insight Tag base code runs. Must match the eventId sent with the corresponding server-side Conversions API event. Per-event conversion deduplication uses the per-call event_id passed to lintrk('track', { conversion_id, event_id }) instead."
},
{
"name": "enableAutoSpaTracking",
"type": "boolean",
"required": false,
"description": "Auto-fire lintrk('track') on Vue Router route changes (SPA virtual page views). When true, suppresses the script's built-in auto-page-view via window._wait_for_lintrk and tracks every navigation including the initial page through Nuxt's page:finish hook. When false, the script fires its own page-view exactly once on load and SPA navigations are not tracked unless lintrk('track') is called manually.",
"defaultValue": "false"
}
],
"SegmentOptions": [
{
"name": "writeKey",
Expand Down
17 changes: 17 additions & 0 deletions packages/script/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
HotjarOptions,
InstagramEmbedOptions,
IntercomOptions,
LinkedInInsightOptions,
MatomoAnalyticsOptions,
MetaPixelOptions,
MixpanelAnalyticsOptions,
Expand Down Expand Up @@ -138,6 +139,7 @@ export const registryMeta: RegistryScriptMeta[] = [
m('tiktokPixel', 'TikTok Pixel', 'ad', 'useScriptTikTokPixel', { bundle: true, proxy: true, partytown: true }, PRIVACY_FULL),
m('snapchatPixel', 'Snapchat Pixel', 'ad', 'useScriptSnapchatPixel', { bundle: true, proxy: true, partytown: true }, PRIVACY_FULL),
m('redditPixel', 'Reddit Pixel', 'ad', 'useScriptRedditPixel', { bundle: true, proxy: true, partytown: true }, PRIVACY_FULL),
m('linkedinInsight', 'LinkedIn Insight Tag', 'ad', 'useScriptLinkedInInsight', { bundle: true, proxy: true, partytown: true }, PRIVACY_FULL),
m('googleAdsense', 'Google Adsense', 'ad', 'useScriptGoogleAdsense', { bundle: true, proxy: true }, PRIVACY_HEATMAP),
m('carbonAds', 'Carbon Ads', 'ad', false, { proxy: true }, PRIVACY_IP_ONLY),
// tag-manager
Expand Down Expand Up @@ -508,6 +510,21 @@ export async function registry(resolve?: (path: string) => Promise<string>): Pro
},
partytown: { forwards: ['rdt'] },
}),
def('linkedinInsight', {
// explicit override: auto-derived would be `useScriptLinkedinInsight` (lowercase i)
composableName: 'useScriptLinkedInInsight',
schema: LinkedInInsightOptions,
label: 'LinkedIn Insight Tag',
src: 'https://snap.licdn.com/li.lms-analytics/insight.min.js',
category: 'ad',
envDefaults: { id: '' },
bundle: true,
proxy: {
domains: ['snap.licdn.com', 'px.ads.linkedin.com'],
privacy: PRIVACY_FULL,
},
partytown: { forwards: ['lintrk'] },
}),
def('googleAdsense', {
schema: GoogleAdsenseOptions,
label: 'Google Adsense',
Expand Down
Loading
Loading