Repository navigation
docs: add Google Analytics and a sitemap - #237
Conversation
- Send page views to the Google Analytics property that cpp-linter.github.io already uses. These docs share its origin, so one property covers the whole site. - Tag maintainer visits with traffic_type=internal when the cpp-linter-internal flag is set (?internal=1 on any page of the site), so the Internal Traffic data filter can drop them. - Build sitemap.xml with sphinx-sitemap. These were the only cpp-linter docs without one; the organization site's robots.txt lists it.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughThe documentation build now generates a sitemap with configured URL and exclusion settings, and configures Google Analytics. The layout template uses the ChangesDocumentation sitemap
Documentation analytics
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #237 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 26 26
Lines 2008 2008
=========================================
Hits 2008 2008 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
) Follow-up to a review of this site's Google Analytics and Search Console data. Over the last 90 days roughly 55% of users came from data-center cities with 0 s engagement. Maintainer visits were about 21% of engaged sessions and half of the `click_github` key events. Nothing recorded that a reader copied a workflow or hook. Links shared in chats had no preview card, and crawlers asking for `/robots.txt` landed on the 404 page. This PR only changes the site. The Google Analytics side (turning the Internal Traffic filter on, key events, custom dimensions) and Search Console are handled separately. ## Before / After (改动前 / 改动后) None of these changes alters a page's layout. The only new visual is the social card, shown below. ### Behaviour | | Before (live site, `origin/main`) | After (this branch) | |---|---|---| | Maintainer visits | Counted like any other visit | `?internal=1` stores a flag in `localStorage`; from then on every event carries `traffic_type=internal` (sent as `tt=internal`). `?internal=0` removes it. The project docs under `/cpp-linter-action/` etc. read the same flag. | | Copying a code block | No event | `copy_code` event with `snippet` (section id, or `cl-workflow` for the home page block) and `code_title` (the file name above the block) | | Open Graph / Twitter tags | 0 on every page | 13 on every page, with a 1200×630 card | | 404 page `<title>` | `cpp-linter` (same as a real page) | `Page not found - cpp-linter` | | `/robots.txt` | 404 (served the 404 page, which was then counted as a page view) | 200, `Allow: /` plus the sitemaps of this site and the four project docs | | Home page `<title>` | `C/C++ Linting - cpp-linter` | `C/C++ Linter with clang-format and clang-tidy - cpp-linter` | ### Old URLs that Google Analytics recorded as 404s `hooks/redirects.py` writes a small redirect page for each one after the build. Each page has a meta refresh, `location.replace`, a canonical link and `noindex`. | Path | Before | After | |---|---|---| | `/docs/` | 404 | → `/getting-started/` | | `/merch/` | 404 | → `/sponsor/#t-shirt-perk` | | `/inputs-outputs/`, `/examples/`, `/permissions/`, `/pr-review-caveats/` | 404 | → the same page under `/cpp-linter-action/` | | `/cli_args` | 404 | → `/cpp-linter/cli_args.html` | | `/cpp_linter_rs/`, `/cpp_linter_rs/cli.html` | 404 | → `/cpp-linter-rs/`, `/cpp-linter-rs/cli/` | ### Evidence: events sent by the real gtag.js Built this branch with the measurement ID swapped for a fake one (`G-TESTTEST00`), so nothing reached the real property. I served it locally and recorded every `g/collect` request in a browser while going through the pages in this order: | # | Page opened (in order) | Event | `tt` (traffic_type) | `ep.snippet` | `ep.code_title` | |---|---|---|---|---|---| | 1 | `/getting-started/` (no flag) | page_view | — | | | | 2 | same page, copy button in "On every pull request" | copy_code | — | `on-every-pull-request` | `.github/workflows/cpp-linter.yml` | | 3 | `/getting-started/?internal=1` | page_view | `internal` | | | | 4 | same page, copy button in "Before every commit" | copy_code | `internal` | `before-every-commit` | `.pre-commit-config.yaml` | | 5 | `/` (no parameter, flag still stored) | page_view | `internal` | | | | 6 | home page "Copy" button | copy_code | `internal` | `cl-workflow` | `.github/workflows/cpp-linter.yml` | | 7 | `/blog/?internal=0` | page_view | — | | | | 8 | `/blog/` | page_view | — | | | ### Evidence: built `<head>` of the home page Before (live): ```html <title>C/C++ Linting - cpp-linter</title> <!-- no og:* or twitter:* tags --> ``` After (`mkdocs build --strict`): ```html <title>C/C++ Linter with clang-format and clang-tidy - cpp-linter</title> <meta property="og:type" content="website"> <meta property="og:site_name" content="cpp-linter"> <meta property="og:title" content="C/C++ Linter with clang-format and clang-tidy"> <meta property="og:description" content="clang-format and clang-tidy for C and C++ pull requests, pre-commit hooks and CI, with the LLVM version you pin."> <meta property="og:url" content="https://cpp-linter.github.io/"> <meta property="og:image" content="https://cpp-linter.github.io/static/og-image.png"> <meta name="twitter:card" content="summary_large_image"> ``` ### Social card Before: no card. After:  ## Notes - The flag snippet runs in the `analytics` block, before Material's own snippet. That way `gtag('set', {traffic_type: 'internal'})` is queued ahead of the first `page_view`, which rows 3 and 5 above confirm. - To report on `snippet` and `code_title`, they need to be registered as event-scoped custom dimensions in Google Analytics. That happens outside this PR. - `robots.txt` lists `/cpp-linter/sitemap.xml`, which is added by cpp-linter/cpp-linter#237. Until that one is deployed, that URL returns 404 to crawlers, which is harmless. - Companion PRs add the same Google Analytics property and the same flag to the project docs: cpp-linter/cpp-linter-action#504, cpp-linter/clang-tools-pip#229, cpp-linter/cpp-linter-rs#502 and cpp-linter/cpp-linter#237. ## After merging Open `https://cpp-linter.github.io/?internal=1` once on each device and browser you use. To check it is working, wait about a day, open any GA4 report, add the comparison "Test data filter name = Internal Traffic" (it exists while the filter is in Testing), and confirm your own visits show up there. Only then should the filter be switched to Active.
These docs are served from the cpp-linter.github.io origin, but unlike the organization site they have no Google Analytics. So there is no record of what readers look at once they leave the organization's home page. These were also the only cpp-linter docs without a sitemap. This PR adds the same property the organization site uses (
G-JKH4SXC7HC). It also adds the maintainer flag from cpp-linter/cpp-linter.github.io#83, so the maintainers' own reading can be filtered out.This PR only changes the site. The Google Analytics side (the Internal Traffic filter, key events) is handled separately.
Before / After (改动前 / 改动后)
origin/main)sphinx-build docs)G-JKH4SXC7HCon every page (sphinx-immaterial'sanalyticstheme option)traffic_type=internalwhile thecpp-linter-internalflag is set (?internal=1/?internal=0on any page of the origin), viadocs/_templates/layout.htmlsitemap.xmlsearch.html,genindex.html,py-modindex.htmland_modules/*are excluded.sphinx-immaterial+ sphinx-sitemap>=2.9.0(lock updated with uv 0.13.1; the diff only adds sphinx-sitemap and its dependency sphinx-last-updated-by-git)Evidence: built
<head>ofindex.htmlThe flag script comes before
id="__analytics"(character 1160 vs 1554 in the builtindex.html).Evidence:
sitemap.xmlThe organization site's
robots.txt(cpp-linter/cpp-linter.github.io#83) listshttps://cpp-linter.github.io/cpp-linter/sitemap.xml.Notes
analyticsblock, before the theme's own snippet. That waygtag('set', {traffic_type: 'internal'})is queued ahead of the firstpage_view. The same snippet was tested end to end with the real gtag.js and a fake measurement ID in feat: tag maintainer visits, track code copies and add social cards cpp-linter.github.io#83:tt=internalis sent after?internal=1and stops after?internal=0.cspell.config.ymlgainsgenindexandmodindex(Sphinx page names insitemap_excludes).Summary by CodeRabbit