From d20492b6feff089f8a02e21e3b2218c368e76d13 Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Wed, 25 Jun 2025 09:40:50 -0500 Subject: [PATCH] chore(analytics): Migrate to GA4 Google tag. If on the local server, use debug mode and prevent tracking. Add the www.influxdata.com Google tag script. Remove the conditional from header.html. Remove the old, unused GTM ID --- assets/js/code-controls.js | 155 +++++++++++++++++- config/staging/hugo.yml | 3 +- layouts/partials/header.html | 2 +- .../header/google-analytics-head.html | 35 +++- 4 files changed, 184 insertions(+), 11 deletions(-) diff --git a/assets/js/code-controls.js b/assets/js/code-controls.js index 17018a8e8..19ec0ef7c 100644 --- a/assets/js/code-controls.js +++ b/assets/js/code-controls.js @@ -1,4 +1,5 @@ import $ from 'jquery'; +import { context } from './page-context.js'; function initialize() { var codeBlockSelector = '.article--content pre'; @@ -68,9 +69,94 @@ function initialize() { // Trigger copy failure state lifecycle $('.copy-code').click(function () { - let text = $(this) + let codeElement = $(this) .closest('.code-controls') - .prevAll('pre:has(code)')[0].innerText; + .prevAll('pre:has(code)')[0]; + + let text = codeElement.innerText; + + // Extract additional code block information + const codeBlockInfo = extractCodeBlockInfo(codeElement); + + // Add Google Analytics event tracking + const currentUrl = new URL(window.location.href); + + // Determine which tracking parameter to add based on product context + switch (context) { + case 'cloud': + currentUrl.searchParams.set('dl', 'cloud'); + break; + case 'core': + /** Track using the same value used by www.influxdata.com pages */ + currentUrl.searchParams.set('dl', 'oss3'); + break; + case 'enterprise': + /** Track using the same value used by www.influxdata.com pages */ + currentUrl.searchParams.set('dl', 'enterprise'); + break; + case 'serverless': + currentUrl.searchParams.set('dl', 'serverless'); + break; + case 'dedicated': + currentUrl.searchParams.set('dl', 'dedicated'); + break; + case 'clustered': + currentUrl.searchParams.set('dl', 'clustered'); + break; + case 'oss/enterprise': + currentUrl.searchParams.set('dl', 'oss'); + break; + case 'other': + default: + // No tracking parameter for other/unknown products + break; + } + + // Add code block specific tracking parameters + if (codeBlockInfo.language) { + currentUrl.searchParams.set('code_lang', codeBlockInfo.language); + } + if (codeBlockInfo.lineCount) { + currentUrl.searchParams.set('code_lines', codeBlockInfo.lineCount); + } + if (codeBlockInfo.hasPlaceholders) { + currentUrl.searchParams.set('has_placeholders', 'true'); + } + if (codeBlockInfo.blockType) { + currentUrl.searchParams.set('code_type', codeBlockInfo.blockType); + } + if (codeBlockInfo.sectionTitle) { + currentUrl.searchParams.set( + 'section', + encodeURIComponent(codeBlockInfo.sectionTitle) + ); + } + if (codeBlockInfo.firstLine) { + currentUrl.searchParams.set( + 'first_line', + encodeURIComponent(codeBlockInfo.firstLine.substring(0, 100)) + ); + } + + // Update browser history without triggering page reload + if (window.history && window.history.replaceState) { + window.history.replaceState(null, '', currentUrl.toString()); + } + + // Send custom Google Analytics event if gtag is available + if (typeof window.gtag !== 'undefined') { + window.gtag('event', 'code_copy', { + language: codeBlockInfo.language, + line_count: codeBlockInfo.lineCount, + has_placeholders: codeBlockInfo.hasPlaceholders, + dl: codeBlockInfo.dl || null, + section_title: codeBlockInfo.sectionTitle, + first_line: codeBlockInfo.firstLine + ? codeBlockInfo.firstLine.substring(0, 100) + : null, + product: context, + }); + } const copyContent = async () => { try { @@ -84,6 +170,71 @@ function initialize() { copyContent(); }); + /** + * Extract contextual information about a code block + * @param {HTMLElement} codeElement - The code block element + * @returns {Object} Information about the code block + */ + function extractCodeBlockInfo(codeElement) { + const codeTag = codeElement.querySelector('code'); + const info = { + language: null, + lineCount: 0, + hasPlaceholders: false, + blockType: 'code', + dl: null, // Download script type + sectionTitle: null, + firstLine: null, + }; + + // Extract language from class attribute + if (codeTag && codeTag.className) { + const langMatch = codeTag.className.match( + /language-(\w+)|hljs-(\w+)|(\w+)/ + ); + if (langMatch) { + info.language = langMatch[1] || langMatch[2] || langMatch[3]; + } + } + + // Count lines + const text = codeElement.innerText || ''; + const lines = text.split('\n'); + info.lineCount = lines.length; + + // Get first non-empty line + info.firstLine = lines.find((line) => line.trim() !== '') || null; + + // Check for placeholders (common patterns) + info.hasPlaceholders = + /\b[A-Z_]{2,}\b|\{\{[^}]+\}\}|\$\{[^}]+\}|<[^>]+>/.test(text); + + // Determine if this is a download script + if (text.includes('https://www.influxdata.com/d/install_influxdb3.sh')) { + if (text.includes('install_influxdb3.sh enterprise')) { + info.dl = 'enterprise'; + } else { + info.dl = 'oss3'; + } + } else if (text.includes('docker pull influxdb:3-enterprise')) { + info.dl = 'enterprise'; + } else if (text.includes('docker pull influxdb3-core')) { + info.dl = 'oss3'; + } + + // Find nearest section heading + let element = codeElement; + while (element && element !== document.body) { + element = element.previousElementSibling || element.parentElement; + if (element && element.tagName && /^H[1-6]$/.test(element.tagName)) { + info.sectionTitle = element.textContent.trim(); + break; + } + } + + return info; + } + /////////////////////////////// FULL WINDOW CODE /////////////////////////////// /* diff --git a/config/staging/hugo.yml b/config/staging/hugo.yml index 3a0a651c2..7d22ffb17 100644 --- a/config/staging/hugo.yml +++ b/config/staging/hugo.yml @@ -13,6 +13,7 @@ minify: params: env: staging environment: staging -server: +server: { disableLiveReload: true +} \ No newline at end of file diff --git a/layouts/partials/header.html b/layouts/partials/header.html index 7960d5ed8..419f86196 100644 --- a/layouts/partials/header.html +++ b/layouts/partials/header.html @@ -5,7 +5,7 @@ - {{ if not hugo.IsServer }}{{ partial "header/google-analytics-head.html" }}{{ end }} + {{ partial "header/google-analytics-head.html" }} diff --git a/layouts/partials/header/google-analytics-head.html b/layouts/partials/header/google-analytics-head.html index 42d1a516b..0880fb083 100644 --- a/layouts/partials/header/google-analytics-head.html +++ b/layouts/partials/header/google-analytics-head.html @@ -1,7 +1,28 @@ - - - +{{ if and hugo.IsServer (not (eq .Site.Params.environment "staging")) }} + + + +{{ else }} + + + +{{ end }}