Add Google Analytics injection to deployment workflow - #1
Conversation
Adds a placeholder comment to src/index.html that the deploy workflow replaces with the GA4 gtag snippet at build time using the GA_MEASUREMENT_ID repository variable. If the variable is unset or fails format validation (^G-[A-Z0-9]+$), the placeholder is removed cleanly so the site deploys without errors or leftover comments. https://claude.ai/code/session_01YRP3nqtybUtdG2Jqs5tggo
There was a problem hiding this comment.
Pull request overview
This PR adds build-time Google Analytics (GA4) injection to the GitHub Pages deployment workflow by inserting the GA snippet into src/index.html at a dedicated placeholder during deployment.
Changes:
- Added a
<!-- GOOGLE_ANALYTICS_PLACEHOLDER -->marker insrc/index.htmlto define the injection point. - Added a deployment workflow step that validates
GA_MEASUREMENT_IDand injects (or removes) the placeholder accordingly before uploading the Pages artifact.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/index.html |
Adds a placeholder comment in <head> where GA will be injected at deploy time. |
.github/workflows/deploy.yml |
Adds an inline Python step to validate and inject GA4 tracking code before artifact upload. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ' </script>' | ||
| ) | ||
| html = html.replace(placeholder, snippet) | ||
| print('Google Analytics injected:', ga_id) |
There was a problem hiding this comment.
The script does not verify that the placeholder replacement actually happened. If src/index.html no longer contains the placeholder (or contains it multiple times), html.replace(...) will be a no-op (or replace multiple locations) but the step may still print that analytics was injected. Consider asserting the placeholder exists exactly once and failing the step (or at least warning) when a valid GA ID is provided but the placeholder is missing/ambiguous.
| with open('src/index.html', 'r') as f: | ||
| html = f.read() |
There was a problem hiding this comment.
index.html contains non-ASCII characters (e.g. em dashes). Reading/writing the file without an explicit encoding relies on the runner locale; to make this deterministic, open the file with encoding="utf-8" for both the read and write.
| else: | ||
| html = html.replace(placeholder, '') | ||
| if ga_id: | ||
| print('WARNING: GA_MEASUREMENT_ID "' + ga_id + '" is not a valid GA4 ID (expected G-XXXXXXXXXX). Skipping.') |
There was a problem hiding this comment.
The warning text says the expected format is G-XXXXXXXXXX, but the validation regex accepts any length (^G-[A-Z0-9]+$). Either tighten the regex to match the format described in the message or adjust the message to reflect the actual validation rule so users aren’t misled.
| html = html.replace(placeholder, snippet) | ||
| print('Google Analytics injected:', ga_id) | ||
| else: | ||
| html = html.replace(placeholder, '') |
There was a problem hiding this comment.
When the GA ID is missing/invalid, the placeholder is replaced with an empty string, which leaves a whitespace-only line in the <head> (because the indentation remains). Consider replacing the whole placeholder line (including leading whitespace and trailing newline) to avoid leaving stray blank/indented lines in the output HTML.
| html = html.replace(placeholder, '') | |
| # Remove the entire line containing the placeholder (including indentation and newline) | |
| pattern = r'^[ \t]*' + re.escape(placeholder) + r'[ \t]*\r?\n?' | |
| new_html, count = re.subn(pattern, '', html, flags=re.MULTILINE) | |
| if count > 0: | |
| html = new_html | |
| else: | |
| # Fallback: if the placeholder was not on its own line, just remove the placeholder text | |
| html = html.replace(placeholder, '') |
- Open index.html with explicit encoding='utf-8' (read + write) to handle non-ASCII characters deterministically across runner locales - Verify placeholder occurs exactly once before replacing; exit 1 if count != 1 so a missing/duplicate placeholder surfaces as a build failure rather than a silent no-op - Use re.sub with MULTILINE to strip the entire placeholder line (including indentation and newline) when skipping injection, leaving no blank or whitespace-only lines in the deployed HTML - Fix warning message to accurately describe the actual regex rule (any length G-[A-Z0-9]+) rather than implying a fixed 10-char format https://claude.ai/code/session_01YRP3nqtybUtdG2Jqs5tggo
Summary
This PR adds automated Google Analytics integration to the deployment pipeline. The deployment workflow now injects a GA4 tracking script into the HTML during the build process, with validation and conditional injection based on configuration.
Key Changes
<!-- GOOGLE_ANALYTICS_PLACEHOLDER -->comment insrc/index.htmlwhere the GA script will be injectedGA_MEASUREMENT_IDfrom GitHub variablesG-[A-Z0-9]+pattern for GA4)Implementation Details
https://claude.ai/code/session_01YRP3nqtybUtdG2Jqs5tggo