Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
180 changes: 97 additions & 83 deletions packages/docs/src/config/webinarContent.ts

Large diffs are not rendered by default.

193 changes: 107 additions & 86 deletions packages/docs/src/pages/webinar-enterprise-ai.tsx

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion packages/docs/src/pages/webinar-thank-you.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,14 @@ function FinalAssurance() {
export default function WebinarThankYou(): JSX.Element {
// Initialize page tracking
useEffect(() => {
trackingService.trackPageView('/webinar-thank-you', 'Webinar Registration Confirmed')
// Track ViewContent for Facebook Pixel (PageView fires on init)
if (window.fbq) {
window.fbq('track', 'ViewContent', {
content_name: 'Webinar Registration Confirmed',
content_category: 'webinar',
content_type: 'product'
})
}

// Track successful conversion landing
trackingService.trackEvent({
Expand Down
70 changes: 41 additions & 29 deletions packages/docs/src/services/trackingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface ConversionData {

export class TrackingService {
private initialized = false
private scrollTrackingInitialized = false

constructor() {
if (typeof window !== 'undefined') {
Expand All @@ -44,11 +45,14 @@ export class TrackingService {
if (!gaId) return

try {
// Load gtag script
const gtagScript = document.createElement('script')
gtagScript.async = true
gtagScript.src = `https://www.googletagmanager.com/gtag/js?id=${gaId}`
document.head.appendChild(gtagScript)
// Load gtag script if not already present
const existingGtag = document.querySelector(`script[src*="googletagmanager.com/gtag/js"]`)
if (!existingGtag) {
const gtagScript = document.createElement('script')
gtagScript.async = true
gtagScript.src = `https://www.googletagmanager.com/gtag/js?id=${gaId}`
document.head.appendChild(gtagScript)
}

// Initialize gtag
window.dataLayer = window.dataLayer || []
Expand All @@ -65,7 +69,6 @@ export class TrackingService {
custom_parameter_2: 'company_size'
}
})

} catch (error) {
console.error('Google Analytics initialization failed:', error)
}
Expand All @@ -77,30 +80,36 @@ export class TrackingService {
if (!linkedInPixel) return

try {
// Load LinkedIn Insight Tag
const linkedInScript = document.createElement('script')
linkedInScript.type = 'text/javascript'
linkedInScript.innerHTML = `
// Load LinkedIn Insight Tag if not already present
const existingLinkedInConfig = document.querySelector('script[data-linkedin-config]')
if (!existingLinkedInConfig) {
const linkedInScript = document.createElement('script')
linkedInScript.type = 'text/javascript'
linkedInScript.setAttribute('data-linkedin-config', 'true')
linkedInScript.innerHTML = `
_linkedin_partner_id = "${linkedInPixel}";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
`
document.head.appendChild(linkedInScript)
document.head.appendChild(linkedInScript)
}

// Load LinkedIn tracking script
const linkedInTrackingScript = document.createElement('script')
linkedInTrackingScript.type = 'text/javascript'
linkedInTrackingScript.async = true
linkedInTrackingScript.src = 'https://snap.licdn.com/li.lms-analytics/insight.min.js'
document.head.appendChild(linkedInTrackingScript)
const existingLinkedInScript = document.querySelector('script[src*="snap.licdn.com"]')
if (!existingLinkedInScript) {
const linkedInTrackingScript = document.createElement('script')
linkedInTrackingScript.type = 'text/javascript'
linkedInTrackingScript.async = true
linkedInTrackingScript.src = 'https://snap.licdn.com/li.lms-analytics/insight.min.js'
document.head.appendChild(linkedInTrackingScript)
}

// Initialize lintrk function
window.lintrk =
window.lintrk ||
function (...args: any[]) {
;(window.lintrk.q = window.lintrk.q || []).push(args)
}

} catch (error) {
console.error('LinkedIn Pixel initialization failed:', error)
}
Expand All @@ -112,22 +121,25 @@ export class TrackingService {
if (!facebookPixel) return

try {
// Facebook Pixel Code
// Facebook Pixel Code - Official stub implementation
window.fbq =
window.fbq ||
function (...args: any[]) {
;(window.fbq.q = window.fbq.q || []).push(args)
}
window._fbq = window.fbq
window.fbq.push = window.fbq
window.fbq.loaded = true
window.fbq.version = '2.0'
window.fbq.queue = []

const facebookScript = document.createElement('script')
facebookScript.async = true
facebookScript.src = 'https://connect.facebook.net/en_US/fbevents.js'
document.head.appendChild(facebookScript)
window.fbq.q = []

// Check if script already exists
const existingScript = document.querySelector('script[src*="fbevents.js"]')
if (!existingScript) {
const facebookScript = document.createElement('script')
facebookScript.async = true
facebookScript.src = 'https://connect.facebook.net/en_US/fbevents.js'
document.head.appendChild(facebookScript)
}

window.fbq('init', facebookPixel)
window.fbq('track', 'PageView')
Comment on lines 121 to 145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Initialize Facebook Pixel without standard queue

The new Facebook Pixel bootstrap writes events into window.fbq.q and never sets fbq.queue or fbq.push = fbq as in the official snippet. When fbevents.js loads it only drains fbq.queue, so the queued init/PageView calls in this block will never be flushed and the first page load will miss its pixel events. This silently drops analytics data for users who load the page before the external script finishes.

Useful? React with 👍 / 👎.

Expand Down Expand Up @@ -165,7 +177,6 @@ export class TrackingService {
currency: 'USD'
})
}

}

// Track webinar registration conversion
Expand Down Expand Up @@ -231,7 +242,6 @@ export class TrackingService {
})
}
}

}

// Track form interactions
Expand All @@ -247,7 +257,8 @@ export class TrackingService {
if (window.fbq) {
try {
if (action === 'start') {
window.fbq('track', 'Lead', {
// Track form engagement with custom event instead of Lead
window.fbq('trackCustom', 'FormStarted', {
content_name: formName,
content_category: 'webinar'
})
Expand Down Expand Up @@ -362,7 +373,7 @@ export class TrackingService {

// Initialize scroll tracking
initializeScrollTracking(): void {
if (typeof window === 'undefined') return
if (typeof window === 'undefined' || this.scrollTrackingInitialized) return

let scrollThresholds = [25, 50, 75, 100]
let firedThresholds: number[] = []
Expand All @@ -381,6 +392,7 @@ export class TrackingService {
}

window.addEventListener('scroll', handleScroll, { passive: true })
this.scrollTrackingInitialized = true
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/docs/src/theme/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useMemo } from 'react'
import { useMemo } from 'react'
import OriginalLayout from '@theme-original/Layout'
import { useLocation } from '@docusaurus/router'
import '@site/src/services/trackingService' // Initialize tracking pixels
import styles from './styles.module.css'

export default function Layout(props) {
Expand Down
2 changes: 1 addition & 1 deletion packages/embed
2 changes: 2 additions & 0 deletions scripts/bws-secure/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ node_modules/
package-lock.json
pnpm-lock.yaml
yarn.lock
testFolder/
testFolder/**
11 changes: 10 additions & 1 deletion scripts/bws-secure/bws-installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
DEFAULT_BWS_VERSION="0.5.0"
BWS_VERSION="${BWS_VERSION:-$DEFAULT_BWS_VERSION}"

# Cross-platform temp base and cleanup trap
TMP_BASE="${TMPDIR:-${TEMP:-${TMP:-/tmp}}}"
cleanup() {
[ -n "$tmp_dir" ] && rm -rf "$tmp_dir" 2>/dev/null || true
}
trap cleanup EXIT
trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERM

main() {
case "$1" in
-u | --uninstall)
Expand Down Expand Up @@ -90,7 +99,7 @@ extract() {
download_bws() {
bws_url="https://github.com/bitwarden/sdk/releases/download/bws-v${BWS_VERSION}/bws-${ARCH}-${PLATFORM}-${BWS_VERSION}.zip"
echo "Downloading bws from: $bws_url"
tmp_dir="$(mktemp -d)"
tmp_dir="$(mktemp -d "$TMP_BASE/bws-secure.XXXXXXXXXX")"
downloader "$bws_url" "$tmp_dir/bws.zip"
}

Expand Down
21 changes: 16 additions & 5 deletions scripts/bws-secure/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ echo -e "${BLUE}🔒 Setting up BWS Secure in $(pwd)/scripts/bws-secure ${NC}"
# Create scripts directory if it doesn't exist
mkdir -p scripts

# Cross-platform temp base and cleanup trap (also used for temp node scripts)
TMP_BASE="${TMPDIR:-${TEMP:-${TMP:-/tmp}}}"
cleanup() {
[ -n "$BWS_TMP_SCRIPT" ] && rm -f "$BWS_TMP_SCRIPT" 2>/dev/null || true
[ -n "$TMP_SCRIPT" ] && rm -f "$TMP_SCRIPT" 2>/dev/null || true
[ -n "$TMP_FILE" ] && rm -f "$TMP_FILE" 2>/dev/null || true
}
trap cleanup EXIT
trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERM

# Helper function to check and initialize git submodules if needed
check_git_submodules() {
# Check if .gitmodules exists
Expand Down Expand Up @@ -77,7 +88,7 @@ if [ "$NODE_VERSION" -lt "20" ]; then
echo "Updating BWS Secure package.json to use glob v10.3.10 compatible with Node.js v$NODE_VERSION..."

# Create temporary script to update BWS package.json
BWS_TMP_SCRIPT=$(mktemp)
BWS_TMP_SCRIPT=$(mktemp "$TMP_BASE/bws-secure.XXXXXXXXXX")
cat > "$BWS_TMP_SCRIPT" << EOF
const fs = require('fs');
try {
Expand Down Expand Up @@ -299,7 +310,7 @@ fi
if [ -f "package.json" ]; then
echo "Updating package.json at: $(pwd)/package.json"

TMP_SCRIPT=$(mktemp)
TMP_SCRIPT=$(mktemp "$TMP_BASE/bws-secure.XXXXXXXXXX")
cat > "$TMP_SCRIPT" << EOF
const fs = require('fs');
try {
Expand Down Expand Up @@ -364,7 +375,7 @@ try {
packageJson.devDependencies['glob'] = '^10.3.10';
}

packageJson.devDependencies['axios'] = packageJson.devDependencies['axios'] || '^1.12.1';
packageJson.devDependencies['axios'] = packageJson.devDependencies['axios'] || '^1.12.2';

// Detect existing indentation or use prettier config
const originalContent = fs.readFileSync(packageJsonPath, 'utf8');
Expand Down Expand Up @@ -691,7 +702,7 @@ for README_FILE in "${README_FILES[@]}"; do
echo "Detected $START_COUNT start markers and $END_COUNT end markers. Removing duplicate sections..."

# Create a temporary script to handle complex README processing
TMP_SCRIPT=$(mktemp)
TMP_SCRIPT=$(mktemp "$TMP_BASE/bws-secure.XXXXXXXXXX")
cat > "$TMP_SCRIPT" << 'EOF'
#!/usr/bin/env node
const fs = require('fs');
Expand Down Expand Up @@ -784,7 +795,7 @@ EOF
# Standard update logic for single section
if [ "$update_standard" = true ]; then
# Create a temporary file
TMP_FILE=$(mktemp)
TMP_FILE=$(mktemp "$TMP_BASE/bws-secure.XXXXXXXXXX")

# Extract everything before the start marker
sed -n '1,/<!-- BWS-SECURE-DOCS-START -->/p' "$README_FILE" | sed '$d' > "$TMP_FILE"
Expand Down
2 changes: 1 addition & 1 deletion scripts/bws-secure/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"scan": "node check-vars/requiredRuntimeVars.js"
},
"dependencies": {
"axios": "^1.12.1",
"axios": "^1.12.2",
"dotenv": "^17.2.2",
"dotenv-cli": "^10.0.0",
"glob": "^11.0.3",
Expand Down
4 changes: 2 additions & 2 deletions scripts/bws-secure/secureRun.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ if (isNestedExecution) {

// 1) Explicitly load .env from the repo root (../../.env) in case we're running from a subdirectory
const dotenvPath = path.join(dirname, '../../.env');
dotenv.config({ path: dotenvPath });
dotenv.config({ path: dotenvPath, quiet: true });

// Platform detection
const isNetlify = process.env.NETLIFY === 'true';
Expand Down Expand Up @@ -1417,7 +1417,7 @@ async function handleUploadCommand() {
ensureBwsInstalled();

// 1. Always load base .env first (but don't override original env vars)
dotenv.config({ override: false });
dotenv.config({ override: false, quiet: true });
log('debug', 'Loaded base environment from .env');

// Only perform BWS setup if this is not a nested execution
Expand Down
2 changes: 1 addition & 1 deletion scripts/bws-secure/update-environments/updateEnvVars.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
} from './vercel.js';
import logger from '../logger.js';

dotenv.config();
dotenv.config({ quiet: true });

// Get the directory name in ESM
const __filename = fileURLToPath(import.meta.url);
Expand Down
Loading