Repository navigation
docs: add Google Analytics and a descriptive home page title - #504
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. - Title the 404 page "Page not found" so missing pages do not show up under the home page's title. - Give the home page a title and description that say what the action does, instead of the site name and "Developer documentation from sources."
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughThe documentation changes configure MkDocs metadata, theme overrides, Google Analytics, and internal-traffic tracking. The home page gains a title and description. A 404 page and a template for handling the ChangesDocumentation Site and Analytics
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to
|
) 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. In Search Console these pages had 317 impressions for the home page alone in three weeks, plus inputs-outputs, pr-review-caveats and examples. 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)mkdocs build --strict)G-JKH4SXC7HCon every pagetraffic_type=internalwhile thecpp-linter-internalflag is set (?internal=1/?internal=0on any page of the origin)<title>C/C++ Linter Actionclang-format and clang-tidy GitHub Action - C/C++ Linter ActionDeveloper documentation from sources.Run clang-format and clang-tidy on the C/C++ files a pull request changes, with annotations, review suggestions and a thread comment.<title>C/C++ Linter Action(same as the home page)Page not found - C/C++ Linter Actiondocs/overrides/in the built siteexclude_docs)Search Console showed this page at an average position of 8.3 with a 0.6% click-through rate. Its title was only the site name, and the description was "Developer documentation from sources."
Evidence: built
<head>ofindex.htmlThe flag script comes before
id="__analytics"(character 1605 vs 1999 in the builtindex.html). The same order holds oninputs-outputs/index.htmland404.html.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.ymlgainshtmltitle(a Jinja block name indocs/overrides/404.html).Summary by CodeRabbit