From 4ec1d5795a3819537e6ee79c89c49862fc0c5d7f Mon Sep 17 00:00:00 2001 From: Dave Kerr's Agent Date: Wed, 2 Sep 2026 14:11:09 +0100 Subject: [PATCH] feat: attribute book buy-clicks to the on-page CTA Add a data-book-cta attribute to every Amazon / No Starch link (chapter lead banner, chapter footer, homepage hero and nav). GTM reads it into a link_location event parameter on the amazon_click and nostarch_click events, surfaced in GA4 as the 'Book CTA location' custom dimension, so buy-clicks can be split by where on the page they came from. Menubar links are matched by their existing header-* class, so the navbar config is untouched. Document the setup in the README. --- .gitignore | 2 ++ README.md | 38 +++++++++++++++++++++++++++++ src/components/BookBanner/index.tsx | 4 +-- src/components/BookFooter/index.tsx | 4 ++- src/pages/index.tsx | 8 +++--- 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 17178afd..1b3d611f 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ yarn-error.log* # Ignore Draw.io backups. *.bkp .playwright-mcp/ +scratch/ +.wf-clone-tmp/ diff --git a/README.md b/README.md index 440da9df..d1e6eb5b 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,44 @@ Components can be added to global scope, i.e. available in call pages, by adding src/theme/MDXComponents.js ``` +## Analytics + +The site uses Google Analytics 4 (`G-8HZFMZV9Z4`), loaded through Google Tag +Manager (`GTM-WS7KMPTS`). Pageviews and outbound clicks are tracked +automatically. Two GTM tags fire custom events when a reader clicks through to +buy the book: `amazon_click` (any `amzn.to` link) and `nostarch_click` (any +`nostarch.com` link). Both are marked as key events in GA4. + +### Book click attribution + +To see *which* button a buy-click came from — the chapter lead banner, the +chapter footer, the homepage hero, or the menu bar — each book link carries a +`data-book-cta` attribute: + +| Value | Where | +|---|---| +| `lead` | Chapter lead banner ([`BookBanner`](src/components/BookBanner)) | +| `finale-cover` / `finale-button` | Chapter footer cover image / buttons ([`BookFooter`](src/components/BookFooter)) | +| `home-hero-button` / `home-hero-cover` / `home-nav` | Homepage hero and nav ([`src/pages/index.tsx`](src/pages/index.tsx)) | +| `menubar` | Docusaurus navbar (toolbar) links, matched by their `header-amazon-link` / `header-nostarch-link` class | +| `sitefooter` | Docusaurus theme footer links, matched by the theme's `.footer` container | + +The last two are config-driven ([`docusaurus.config.js`](docusaurus.config.js)) +and can't take a `data-book-cta` attribute cleanly, so GTM matches them by class +and container instead — no attribute needed. + +GTM reads all this with the `CJS - Book CTA Location` variable, which returns the +clicked link's `data-book-cta`, else `menubar` for the header links, else +`sitefooter` for anything inside the theme footer, and `(unmarked)` otherwise. It +is sent as the `link_location` event parameter and surfaced in GA4 as the +event-scoped custom dimension **Book CTA location**. + +Attribution is not retroactive: GA4 only records `link_location` from the point +the tag is live, so newly added CTAs start showing up once this markup deploys. +**When you add a new book link, give it a `data-book-cta` value** — a missing +attribute never breaks tracking (the click still fires), it just reports as +`(unmarked)`. + ## Versioning The version of the site and the code is defined in the [`package.json`](./package.json) file. diff --git a/src/components/BookBanner/index.tsx b/src/components/BookBanner/index.tsx index e73ea6b5..732b5c2d 100644 --- a/src/components/BookBanner/index.tsx +++ b/src/components/BookBanner/index.tsx @@ -7,11 +7,11 @@ const BookBanner: React.FC = () => { You're reading the free online edition of Effective Shell. If you're finding it useful, please consider picking up the print or Kindle edition from{' '} - + No Starch Press {' '} or{' '} - + Amazon {' '} - or sharing it with someone who'd enjoy it. diff --git a/src/components/BookFooter/index.tsx b/src/components/BookFooter/index.tsx index dbd11a17..5e9d27a8 100644 --- a/src/components/BookFooter/index.tsx +++ b/src/components/BookFooter/index.tsx @@ -4,7 +4,7 @@ import './styles.css'; const BookFooter: React.FC = () => { return (
- + Effective Shell book cover { @@ -29,6 +30,7 @@ const BookFooter: React.FC = () => { diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 3e8def21..94e3d5c4 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -28,18 +28,20 @@ function HeroSection() { Amazon No Starch
- + Read Now
- + Amazon - + No Starch