LinkedIn Insight Tag & Conversions API
Conversion tracking, retargeting, website demographics, and server-side tracking implementation.
Introduction to LinkedIn Insight Tag
The LinkedIn Insight Tag is a JavaScript snippet that enables conversion tracking, website retargeting, and website demographics analytics. It's essential for measuring campaign performance, building retargeting audiences, and understanding your website visitors' professional attributes.
Insight Tag Capabilities:
┌─────────────────────────────────────────────────────────────────────┐
│ WHAT THE INSIGHT TAG ENABLES │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Conversion Tracking │
│ ├── Track page load conversions (thank you pages) │
│ ├── Track event-specific conversions (button clicks, form submits) │
│ ├── Track multiple conversion events │
│ ├── View-through attribution (up to 90 days) │
│ └── Click-through attribution (up to 90 days) │
│ │
│ Website Retargeting │
│ ├── All website visitors │
│ ├── Specific page visitors (URL rules) │
│ ├── Event-based audiences (custom triggers) │
│ ├── Time-based segments (7, 30, 60, 90, 180 days) │
│ └── Minimum 300 matched members required │
│ │
│ Website Demographics │
│ ├── Job function breakdown of visitors │
│ ├── Seniority level distribution │
│ ├── Industry representation │
│ ├── Company size distribution │
│ ├── Company name insights │
│ └── Location data │
│ │
│ Implementation Methods: │
│ ├── Browser-based: Insight Tag (JavaScript) │
│ ├── Server-side: Conversions API (CAPI) │
│ └── Recommended: Both for maximum coverage │
│ │
└─────────────────────────────────────────────────────────────────────┘Insight Tag Installation
Basic Installation
The Insight Tag should be installed on every page of your website, typically in the <head> section or via a tag manager.
<!-- LinkedIn Insight Tag - Base Code -->
<script type="text/javascript">
_linkedin_partner_id = "YOUR_PARTNER_ID";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
</script>
<script type="text/javascript">
(function(l) {
if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
window.lintrk.q=[]}
var s = document.getElementsByTagName("script")[0];
var b = document.createElement("script");
b.type = "text/javascript";b.async = true;
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
s.parentNode.insertBefore(b, s);
})(window.lintrk);
</script>
<noscript>
<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=YOUR_PARTNER_ID&fmt=gif" />
</noscript>Next.js Implementation
For Next.js applications, implement the Insight Tag as a client component with proper route change tracking.
// src/components/analytics/linkedin-insight-tag.tsx
'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
import Script from 'next/script';
const LINKEDIN_PARTNER_ID = process.env.NEXT_PUBLIC_LINKEDIN_PARTNER_ID;
// Extend window type for LinkedIn tracking
declare global {
interface Window {
_linkedin_data_partner_ids?: string[];
lintrk?: (action: string, data?: Record<string, unknown>) => void;
}
}
export function LinkedInInsightTag() {
const pathname = usePathname();
const searchParams = useSearchParams();
// Initialize partner IDs
useEffect(() => {
if (LINKEDIN_PARTNER_ID) {
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
if (!window._linkedin_data_partner_ids.includes(LINKEDIN_PARTNER_ID)) {
window._linkedin_data_partner_ids.push(LINKEDIN_PARTNER_ID);
}
}
}, []);
// Track page views on route changes
useEffect(() => {
if (window.lintrk) {
// LinkedIn automatically tracks page views when tag loads
// For SPAs, this tracks virtual page views on navigation
console.log('LinkedIn: Page view tracked', pathname);
}
}, [pathname, searchParams]);
if (!LINKEDIN_PARTNER_ID) {
return null;
}
return (
<>
<Script
id="linkedin-insight-tag"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
_linkedin_partner_id = "${LINKEDIN_PARTNER_ID}";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
(function(l) {
if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
window.lintrk.q=[]}
var s = document.getElementsByTagName("script")[0];
var b = document.createElement("script");
b.type = "text/javascript";b.async = true;
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
s.parentNode.insertBefore(b, s);
})(window.lintrk);
`,
}}
/>
<noscript>
<img
height="1"
width="1"
style={{ display: 'none' }}
alt=""
src={`https://px.ads.linkedin.com/collect/?pid=${LINKEDIN_PARTNER_ID}&fmt=gif`}
/>
</noscript>
</>
);
}
// Helper function for tracking conversions
export function trackLinkedInConversion(conversionId: number) {
if (typeof window !== 'undefined' && window.lintrk) {
window.lintrk('track', { conversion_id: conversionId });
}
}Google Tag Manager Installation
For GTM implementation, use a Custom HTML tag with the Insight Tag code.
GTM Configuration:
┌─────────────────────────────────────────────────────────────────────┐
│ GTM SETUP STEPS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Create Base Tag │
│ ├── Tag Type: Custom HTML │
│ ├── Tag Name: LinkedIn - Insight Tag Base │
│ ├── HTML: [Paste Insight Tag code] │
│ ├── Trigger: All Pages │
│ └── Firing Options: Once per page │
│ │
│ Step 2: Create Conversion Tags │
│ For each conversion event: │
│ ├── Tag Type: Custom HTML │
│ ├── Tag Name: LinkedIn - Conversion [Event Name] │
│ ├── HTML: <script>lintrk('track', {conversion_id: 123456});</script>│
│ ├── Trigger: Custom event or page view trigger │
│ └── Tag Sequencing: Fire after base tag │
│ │
│ Step 3: Verify Installation │
│ ├── Use GTM Preview mode │
│ ├── Check Network tab for li.lms-analytics requests │
│ └── Use LinkedIn Pixel Helper extension │
│ │
│ Common Triggers: │
│ ├── Form Submission: Form Submit trigger │
│ ├── Button Click: Click trigger with element selector │
│ ├── Thank You Page: Page View with URL condition │
│ └── Custom Event: dataLayer.push({'event': 'conversion_name'}) │
│ │
└─────────────────────────────────────────────────────────────────────┘Conversion Tracking
Conversion Types
LinkedIn supports multiple methods for tracking conversions:
Conversion Tracking Methods:
┌─────────────────────────────────────────────────────────────────────┐
│ PAGE LOAD CONVERSIONS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ How It Works: │
│ ├── Fires when specific page loads │
│ ├── No additional code required │
│ ├── Uses URL matching rules │
│ └── Best for: Thank you pages, confirmation pages │
│ │
│ URL Matching Options: │
│ ├── Equals: Exact URL match │
│ │ Example: https://company.com/thank-you │
│ ├── Starts with: URL prefix match │
│ │ Example: https://company.com/thank-you │
│ └── Contains: Partial URL match │
│ Example: /thank-you, /confirmation, /success │
│ │
│ Setup in Campaign Manager: │
│ 1. Go to Account Assets → Conversions │
│ 2. Create Conversion → Online Conversion │
│ 3. Select "Page Load" as trigger │
│ 4. Enter URL rules │
│ 5. Set attribution settings │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ EVENT-SPECIFIC CONVERSIONS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ How It Works: │
│ ├── Fires via JavaScript call │
│ ├── Requires conversion_id parameter │
│ ├── Can fire on any user action │
│ └── Best for: Form submits, button clicks, custom events │
│ │
│ JavaScript Call: │
│ lintrk('track', { conversion_id: YOUR_CONVERSION_ID }); │
│ │
│ Setup in Campaign Manager: │
│ 1. Go to Account Assets → Conversions │
│ 2. Create Conversion → Online Conversion │
│ 3. Select "Event-specific" as trigger │
│ 4. Copy the conversion_id │
│ 5. Implement JavaScript call on your site │
│ │
│ Example Implementation: │
│ document.getElementById('demo-btn').addEventListener('click', () => │
│ lintrk('track', { conversion_id: 12345678 }); │
│ }); │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ OFFLINE CONVERSIONS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ How It Works: │
│ ├── Upload conversion data via CSV │
│ ├── Match using email or LinkedIn member URN │
│ ├── Back-fill conversions up to 90 days │
│ └── Best for: CRM conversions, offline sales, phone calls │
│ │
│ Required Fields: │
│ ├── Conversion timestamp (ISO 8601) │
│ ├── Conversion value (optional) │
│ ├── Email address (for matching) │
│ └── Conversion name (matches Campaign Manager) │
│ │
└─────────────────────────────────────────────────────────────────────┘Conversion Event Implementation
// Comprehensive conversion tracking implementation
const linkedInConversions = {
// Conversion IDs from Campaign Manager
conversionIds: {
demo_request: 12345678,
free_trial: 12345679,
contact_form: 12345680,
whitepaper_download: 12345681,
webinar_registration: 12345682,
purchase: 12345683,
newsletter_signup: 12345684,
},
// Track conversion with optional value
track: (conversionType: keyof typeof linkedInConversions.conversionIds, value?: number) => {
const conversionId = linkedInConversions.conversionIds[conversionType];
if (typeof window !== 'undefined' && window.lintrk && conversionId) {
const trackingData: Record<string, unknown> = {
conversion_id: conversionId,
};
// Add conversion value if provided
if (value !== undefined) {
trackingData.value = value;
trackingData.currency = 'USD';
}
window.lintrk('track', trackingData);
console.log(`LinkedIn conversion tracked: ${conversionType}`, trackingData);
}
},
};
// Usage examples
// Track demo request
linkedInConversions.track('demo_request');
// Track purchase with value
linkedInConversions.track('purchase', 1500);
// React component example
function DemoRequestForm() {
const handleSubmit = async (formData: FormData) => {
// Submit form to backend
const response = await submitDemoRequest(formData);
if (response.success) {
// Track LinkedIn conversion
linkedInConversions.track('demo_request');
// Track in other analytics
// gtag('event', 'demo_request', {...});
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
</form>
);
}Conversions API (CAPI)
The LinkedIn Conversions API enables server-side conversion tracking, providing more reliable data especially with browser privacy changes and ad blockers.
Conversions API Benefits:
┌─────────────────────────────────────────────────────────────────────┐
│ WHY USE CONVERSIONS API │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Reliability Improvements │
│ ├── Works with ad blockers (server-side) │
│ ├── Not affected by browser privacy settings │
│ ├── More accurate conversion attribution │
│ ├── Captures conversions Insight Tag misses │
│ └── First-party data approach │
│ │
│ Data Quality │
│ ├── Richer user matching (email, phone, li_fat_id) │
│ ├── Better cross-device attribution │
│ ├── More complete conversion data │
│ └── Event deduplication support │
│ │
│ Use Cases │
│ ├── High-value conversions (demos, purchases) │
│ ├── CRM-based conversions │
│ ├── Offline conversion upload │
│ └── Backup for client-side tracking │
│ │
│ Recommendation: Use CAPI + Insight Tag together │
│ ├── Insight Tag: Real-time page views, quick events │
│ ├── CAPI: Important conversions, redundancy │
│ └── Deduplication: Use event_id to prevent double-counting │
│ │
└─────────────────────────────────────────────────────────────────────┘CAPI Implementation
// LinkedIn Conversions API implementation
import crypto from 'crypto';
interface LinkedInConversionEvent {
eventName: string;
eventTime: Date;
eventId: string;
user: {
email?: string;
phone?: string;
linkedInFirstPartyId?: string; // li_fat_id from cookie
userAgent?: string;
ipAddress?: string;
};
customData?: {
currency?: string;
value?: number;
conversionId?: number;
};
pageUrl?: string;
}
class LinkedInConversionsAPI {
private accessToken: string;
private adAccountId: string;
constructor(accessToken: string, adAccountId: string) {
this.accessToken = accessToken;
this.adAccountId = adAccountId;
}
// Hash user data for privacy
private hashSHA256(value: string): string {
return crypto
.createHash('sha256')
.update(value.toLowerCase().trim())
.digest('hex');
}
// Normalize and hash email
private hashEmail(email: string): string {
const normalized = email.toLowerCase().trim();
return this.hashSHA256(normalized);
}
// Normalize and hash phone
private hashPhone(phone: string): string {
// Remove all non-numeric characters except +
const normalized = phone.replace(/[^\d+]/g, '');
return this.hashSHA256(normalized);
}
// Send conversion event to LinkedIn
async sendConversion(event: LinkedInConversionEvent): Promise<void> {
const payload = {
conversion: this.adAccountId,
conversionHappenedAt: event.eventTime.getTime(),
eventId: event.eventId,
user: {
userIds: [] as Array<{ idType: string; idValue: string }>,
userInfo: {
...(event.user.ipAddress && { clientIp: event.user.ipAddress }),
...(event.user.userAgent && { userAgent: event.user.userAgent }),
},
},
...(event.customData?.value && {
conversionValue: {
currencyCode: event.customData.currency || 'USD',
amount: String(event.customData.value),
},
}),
};
// Add hashed user identifiers
if (event.user.email) {
payload.user.userIds.push({
idType: 'SHA256_EMAIL',
idValue: this.hashEmail(event.user.email),
});
}
if (event.user.phone) {
payload.user.userIds.push({
idType: 'SHA256_PHONE',
idValue: this.hashPhone(event.user.phone),
});
}
if (event.user.linkedInFirstPartyId) {
payload.user.userIds.push({
idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',
idValue: event.user.linkedInFirstPartyId,
});
}
// Send to LinkedIn Conversions API
const response = await fetch(
'https://api.linkedin.com/rest/conversionEvents',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
'X-Restli-Protocol-Version': '2.0.0',
'LinkedIn-Version': '202401',
},
body: JSON.stringify({
elements: [payload],
}),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`LinkedIn CAPI Error: ${JSON.stringify(error)}`);
}
}
}
// Usage example in Next.js API route
// src/app/api/conversions/linkedin/route.ts
import { NextRequest, NextResponse } from 'next/server';
const linkedInCAPI = new LinkedInConversionsAPI(
process.env.LINKEDIN_ACCESS_TOKEN!,
process.env.LINKEDIN_AD_ACCOUNT_ID!
);
export async function POST(request: NextRequest) {
const body = await request.json();
try {
await linkedInCAPI.sendConversion({
eventName: body.eventName,
eventTime: new Date(body.eventTime),
eventId: body.eventId,
user: {
email: body.email,
phone: body.phone,
linkedInFirstPartyId: body.li_fat_id,
userAgent: request.headers.get('user-agent') || undefined,
ipAddress: request.headers.get('x-forwarded-for')?.split(',')[0] || undefined,
},
customData: {
currency: 'USD',
value: body.value,
},
pageUrl: body.pageUrl,
});
return NextResponse.json({ success: true });
} catch (error) {
console.error('LinkedIn CAPI error:', error);
return NextResponse.json({ error: 'Failed to send conversion' }, { status: 500 });
}
}Event Deduplication
When using both Insight Tag and CAPI, implement deduplication to prevent double-counting conversions.
// Event deduplication strategy
const deduplicationStrategy = {
// Generate unique event ID
generateEventId: () => {
return `evt_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
},
// Store event ID for deduplication
storeEventId: (eventId: string, conversionType: string) => {
// Store in cookie or session for short-term dedup
if (typeof window !== 'undefined') {
const key = `li_evt_${conversionType}`;
sessionStorage.setItem(key, eventId);
}
},
// Get stored event ID
getStoredEventId: (conversionType: string): string | null => {
if (typeof window !== 'undefined') {
return sessionStorage.getItem(`li_evt_${conversionType}`);
}
return null;
},
};
// Dual tracking implementation (Insight Tag + CAPI)
async function trackConversionDual(
conversionType: string,
conversionId: number,
userData: { email?: string; phone?: string },
value?: number
) {
// Generate unique event ID
const eventId = deduplicationStrategy.generateEventId();
deduplicationStrategy.storeEventId(eventId, conversionType);
// Track via Insight Tag (client-side)
if (typeof window !== 'undefined' && window.lintrk) {
window.lintrk('track', {
conversion_id: conversionId,
event_id: eventId, // For deduplication
});
}
// Track via Conversions API (server-side)
try {
await fetch('/api/conversions/linkedin', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
eventName: conversionType,
eventTime: new Date().toISOString(),
eventId: eventId, // Same ID for deduplication
email: userData.email,
phone: userData.phone,
li_fat_id: getCookie('li_fat_id'), // LinkedIn first-party cookie
value: value,
pageUrl: window.location.href,
}),
});
} catch (error) {
console.error('CAPI tracking failed:', error);
// Insight Tag still tracked, so conversion is captured
}
}
// Helper to get li_fat_id cookie
function getCookie(name: string): string | null {
if (typeof document !== 'undefined') {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop()?.split(';').shift() || null;
}
return null;
}Website Retargeting
Build audiences based on website visitor behavior for retargeting campaigns.
Retargeting Audience Setup:
┌─────────────────────────────────────────────────────────────────────┐
│ AUDIENCE CONFIGURATION │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Requirements: │
│ ├── Insight Tag installed and firing │
│ ├── Minimum 300 matched LinkedIn members │
│ ├── Audience builds within 24-48 hours │
│ └── Maximum lookback: 180 days │
│ │
│ Audience Rules: │
│ ├── All website visitors │
│ ├── URL contains: /pricing, /demo, /product │
│ ├── URL equals: exact page match │
│ ├── URL starts with: section matching │
│ └── Exclude: Specific URLs or patterns │
│ │
│ Recommended Segments: │
│ ────────────────────────────────────────────────────────────────── │
│ Segment URL Rule Purpose │
│ ────────────────────────────────────────────────────────────────── │
│ All Visitors [all pages] Broad awareness │
│ High Intent /pricing, /demo Bottom funnel │
│ Product Pages /product, /features Mid funnel │
│ Blog Readers /blog Content nurture │
│ Case Studies /customers, /case Social proof │
│ Converters /thank-you Exclusion or upsell │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ TIME-BASED SEGMENTS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Hot Leads (7 days) │
│ ├── Recently active, high engagement potential │
│ ├── Best for: Demo/trial offers │
│ └── Typical: Aggressive messaging │
│ │
│ Active Interest (30 days) │
│ ├── Standard retargeting window │
│ ├── Best for: Product education │
│ └── Typical: Moderate frequency │
│ │
│ Nurture (60-90 days) │
│ ├── Longer consideration cycle │
│ ├── Best for: Content, thought leadership │
│ └── Typical: Lower frequency │
│ │
│ Re-engagement (90-180 days) │
│ ├── Lapsed visitors │
│ ├── Best for: New product announcements │
│ └── Typical: Special offers │
│ │
└─────────────────────────────────────────────────────────────────────┘Retargeting Audience Implementation
// Retargeting audience strategy configuration
const retargetingStrategy = {
audiences: [
{
name: 'RT_AllVisitors_30d',
rule: { type: 'all_pages', timeframe: 30 },
campaignUse: 'awareness',
expectedSize: '10,000+',
},
{
name: 'RT_PricingPage_14d',
rule: { type: 'url_contains', value: '/pricing', timeframe: 14 },
campaignUse: 'conversion',
expectedSize: '500-2,000',
},
{
name: 'RT_DemoPageAbandoned_7d',
rule: {
type: 'url_contains',
value: '/demo',
timeframe: 7,
exclude: '/demo/thank-you',
},
campaignUse: 'conversion',
expectedSize: '300-1,000',
},
{
name: 'RT_BlogReaders_60d',
rule: { type: 'url_starts_with', value: '/blog', timeframe: 60 },
campaignUse: 'nurture',
expectedSize: '5,000+',
},
{
name: 'RT_ProductPages_30d',
rule: {
type: 'url_contains',
value: ['/product', '/features', '/solutions'],
timeframe: 30,
},
campaignUse: 'consideration',
expectedSize: '2,000-5,000',
},
{
name: 'RT_Converters_90d',
rule: { type: 'url_contains', value: '/thank-you', timeframe: 90 },
campaignUse: 'exclusion_or_upsell',
expectedSize: 'varies',
},
],
// Campaign structure using retargeting
campaignStructure: {
awareness: {
audiences: ['RT_AllVisitors_30d'],
excludeAudiences: ['RT_Converters_90d'],
objective: 'brand_awareness',
content: 'thought_leadership',
},
consideration: {
audiences: ['RT_ProductPages_30d', 'RT_BlogReaders_60d'],
excludeAudiences: ['RT_PricingPage_14d', 'RT_Converters_90d'],
objective: 'website_visits',
content: 'case_studies',
},
conversion: {
audiences: ['RT_PricingPage_14d', 'RT_DemoPageAbandoned_7d'],
excludeAudiences: ['RT_Converters_90d'],
objective: 'lead_generation',
content: 'demo_offer',
},
upsell: {
audiences: ['RT_Converters_90d'],
excludeAudiences: [],
objective: 'website_conversions',
content: 'upgrade_offer',
},
},
};Website Demographics
Gain insights into the professional makeup of your website visitors without running ads.
Website Demographics Features:
┌─────────────────────────────────────────────────────────────────────┐
│ AVAILABLE INSIGHTS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Job Function │
│ ├── Marketing, Sales, IT, Finance, etc. │
│ ├── Shows distribution of visitor roles │
│ └── Compare to campaign targeting │
│ │
│ Seniority │
│ ├── Entry, Senior, Manager, Director, VP, C-Suite │
│ ├── Understand decision-maker presence │
│ └── Inform targeting strategy │
│ │
│ Industry │
│ ├── Top industries visiting your site │
│ ├── Identify new market opportunities │
│ └── Validate targeting choices │
│ │
│ Company Size │
│ ├── Distribution by employee count │
│ ├── Align with ideal customer profile │
│ └── Adjust SMB vs enterprise focus │
│ │
│ Company Name │
│ ├── Top companies visiting (if enough traffic) │
│ ├── Identify ABM opportunities │
│ └── Sales intelligence for outreach │
│ │
│ Location │
│ ├── Country, region, city distribution │
│ ├── Inform geographic targeting │
│ └── Identify expansion markets │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ USING DEMOGRAPHICS DATA │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Campaign Optimization: │
│ ├── Compare visitor demographics to ad targeting │
│ ├── Identify underserved high-value segments │
│ ├── Adjust bid modifiers for valuable audiences │
│ └── Refine exclusions for poor-fit segments │
│ │
│ Content Strategy: │
│ ├── Create content for top visitor personas │
│ ├── Address pain points by job function │
│ └── Tailor messaging to seniority levels │
│ │
│ Sales Intelligence: │
│ ├── Identify companies researching your solution │
│ ├── Prioritize outreach to engaged accounts │
│ └── Personalize sales conversations │
│ │
└─────────────────────────────────────────────────────────────────────┘Testing and Validation
Insight Tag Validation
// Insight Tag testing utilities
const insightTagTesting = {
// Check if Insight Tag is loaded
checkTagLoaded: (): boolean => {
if (typeof window === 'undefined') return false;
return typeof window.lintrk === 'function';
},
// Get Partner ID
getPartnerId: (): string | null => {
if (typeof window === 'undefined') return null;
return window._linkedin_partner_id || null;
},
// Verify tag firing in console
debugMode: () => {
if (typeof window === 'undefined') return;
// Override lintrk to log calls
const originalLintrk = window.lintrk;
window.lintrk = function(action: string, data?: Record<string, unknown>) {
console.log('[LinkedIn Debug]', action, data);
if (originalLintrk) {
originalLintrk.call(this, action, data);
}
};
},
// Check network requests
verifyNetworkRequests: () => {
console.log('Check Network tab for:');
console.log('- https://px.ads.linkedin.com/collect (base tag)');
console.log('- https://snap.licdn.com/li.lms-analytics (tag script)');
console.log('- Response should be 200 OK');
},
// Test conversion tracking
testConversion: (conversionId: number) => {
if (typeof window !== 'undefined' && window.lintrk) {
window.lintrk('track', { conversion_id: conversionId });
console.log(`Test conversion fired: ${conversionId}`);
}
},
};
// Use LinkedIn Pixel Helper Chrome Extension
// https://chrome.google.com/webstore/detail/linkedin-pixel-helperTroubleshooting Guide
Common Issues and Solutions:
┌─────────────────────────────────────────────────────────────────────┐
│ Issue Solution │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Tag not firing │
│ ├── Check Partner ID is correct │
│ ├── Verify tag is on all pages │
│ ├── Check for JavaScript errors │
│ └── Ensure tag fires after consent (GDPR) │
│ │
│ Conversions not tracking │
│ ├── Verify conversion_id is correct │
│ ├── Check tag fires AFTER base tag │
│ ├── Test with Pixel Helper extension │
│ └── Wait 24h for data to appear │
│ │
│ Retargeting audience not building │
│ ├── Need 300+ matched members │
│ ├── Allow 24-48 hours to populate │
│ ├── Verify URL rules match actual URLs │
│ └── Check for typos in URL patterns │
│ │
│ Website Demographics empty │
│ ├── Need sufficient traffic volume │
│ ├── Data requires LinkedIn member visits │
│ ├── Wait 7+ days for data to populate │
│ └── Verify tag is firing on all pages │
│ │
│ Double-counting conversions │
│ ├── Implement event_id for deduplication │
│ ├── Use same event_id for Insight Tag and CAPI │
│ └── Check conversion doesn't fire multiple times │
│ │
│ Ad blockers blocking tag │
│ ├── Implement Conversions API as backup │
│ ├── Use server-side tracking for critical events │
│ └── Consider first-party proxy (advanced) │
│ │
└─────────────────────────────────────────────────────────────────────┘pxlpeak Integration
// pxlpeak LinkedIn tracking integration
import { pxlpeak } from '@pxlpeak/sdk';
// Configure LinkedIn tracking in pxlpeak
await pxlpeak.linkedin.configure({
insightTag: {
partnerId: process.env.LINKEDIN_PARTNER_ID,
enabled: true,
debug: process.env.NODE_ENV === 'development',
},
conversionsApi: {
accessToken: process.env.LINKEDIN_ACCESS_TOKEN,
adAccountId: process.env.LINKEDIN_AD_ACCOUNT_ID,
enabled: true,
deduplication: true,
},
events: {
// Map pxlpeak events to LinkedIn conversions
mapping: [
{ pxlpeakEvent: 'lead', linkedinConversionId: 12345678 },
{ pxlpeakEvent: 'demo_request', linkedinConversionId: 12345679 },
{ pxlpeakEvent: 'purchase', linkedinConversionId: 12345680 },
],
},
});
// Track event through pxlpeak (automatically sends to LinkedIn)
pxlpeak.track('demo_request', {
email: 'user@company.com',
company: 'Acme Corp',
value: 500,
});Related Documentation
- LinkedIn Ads Complete Guide - Platform overview and strategy
- LinkedIn Campaign Types - Ad format specifications
- LinkedIn Targeting - Audience building and ABM
- Lead Gen Forms - Native lead capture
- LinkedIn Optimization - Performance improvement strategies