Skip to content

docs: add Google Analytics and a descriptive home page title - #504

Merged
shenxianpeng merged 2 commits into
mainfrom
chore/google-analytics
Oct 18, 2026
Merged

shenxianpeng merged 2 commits into
mainfrom
chore/google-analytics

Conversation

@shenxianpeng

@shenxianpeng shenxianpeng commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

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 (改动前 / 改动后)

Before (live site, origin/main) After (this branch, mkdocs build --strict)
Google Analytics No gtag on any page G-JKH4SXC7HC on every page
Maintainer visits — traffic_type=internal while the cpp-linter-internal flag is set (?internal=1 / ?internal=0 on any page of the origin)
Home page <title> C/C++ Linter Action clang-format and clang-tidy GitHub Action - C/C++ Linter Action
Home page meta description Developer 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.
404 page <title> C/C++ Linter Action (same as the home page) Page not found - C/C++ Linter Action
docs/overrides/ in the built site — Not published (exclude_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> of index.html

<script>
  try {
    var param = new URLSearchParams(location.search).get("internal");
    if (param === "1") localStorage.setItem("cpp-linter-internal", "1");
    if (param === "0") localStorage.removeItem("cpp-linter-internal");
    if (localStorage.getItem("cpp-linter-internal") === "1") {
      window.dataLayer = window.dataLayer || [];
      (function () { dataLayer.push(arguments); })("set", { traffic_type: "internal" });
    }
  } catch (e) {
    // localStorage is unavailable when storage is blocked; the visit is then not tagged.
  }
</script>
<script id="__analytics">function __md_analytics(){ /* … the theme's snippet, unchanged … */ var t=document.createElement("script");t.async=!0,t.src="https://www.googletagmanager.com/gtag/js?id=G-JKH4SXC7HC",document.getElementById("__analytics").insertAdjacentElement("afterEnd",t)}</script>

The flag script comes before id="__analytics" (character 1605 vs 1999 in the built index.html). The same order holds on inputs-outputs/index.html and 404.html.

Notes

  • The flag snippet runs in the theme's analytics block, before the theme's own snippet. That way gtag('set', {traffic_type: 'internal'}) is queued ahead of the first page_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=internal is sent after ?internal=1 and stops after ?internal=0.
  • None of these changes alters a page's layout, so there are no screenshots.
  • cspell.config.yml gains htmltitle (a Jinja block name in docs/overrides/404.html).

Summary by CodeRabbit

  • Documentation
    • Updated the documentation landing page with a clearer title and a summary of the action’s pull-request checks and outputs.
    • Added a custom “Page not found” page to help visitors identify missing documentation pages and return to the site.

- 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."
@shenxianpeng
shenxianpeng requested a review from a team as a code owner October 18, 2026 19:05
@shenxianpeng
shenxianpeng requested review from 2bndy5 and removed request for a team October 18, 2026 19:05
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 18, 2026
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 26f452ab-5354-49d1-9708-3a329d074e4d
📥 Commits

Reviewing files that changed from the base of the PR and between f71829c and 0ea91e2.

📒 Files selected for processing: 5
  • cspell.config.yml
  • docs/index.md
  • docs/overrides/404.html
  • docs/overrides/main.html
  • mkdocs.yml

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

Walkthrough

The 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 internal query parameter are added.

Changes

Documentation Site and Analytics

Layer / File(s) Summary
Configure documentation pages and analytics
mkdocs.yml, docs/index.md
MkDocs excludes the overrides directory from documentation pages, uses it as the theme custom directory, and configures Google Analytics. The home page gains a title and description.
Add theme overrides and internal-traffic tracking
docs/overrides/*, cspell.config.yml
The overrides add a 404 page and update the internal-traffic flag from the query parameter. When analytics is configured and the flag is set to 1, the template queues the internal traffic setting before the parent analytics block. The spelling list adds htmltitle.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 0ea91

The PR adds documentation metadata and Google Analytics with an internal-traffic flag; the Material override preserves analytics output. No actionable merge-blocking risk remains.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main changes: adding Google Analytics and a descriptive home page title. It is concise and specific.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (5 skipped: 5 unsupported.)

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@shenxianpeng
shenxianpeng merged commit 6eae5f9 into main Oct 18, 2026
8 checks passed
@shenxianpeng
shenxianpeng deleted the chore/google-analytics branch October 18, 2026 21:00
shenxianpeng added a commit to cpp-linter/cpp-linter.github.io that referenced this pull request Oct 18, 2026
)

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:

![Social
card](https://raw.githubusercontent.com/cpp-linter/cpp-linter.github.io/pr-assets/feature-analytics-and-seo/og-card-after.png)

## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants