Analytics¶
Homebase automatically tracks every link click and sends structured events to Google Analytics 4 (GA4). This gives you full visibility into which links your audience clicks, where they came from, and which sections of your page drive the most engagement — without any third-party analytics tool.
Prerequisites¶
GA tracking must be enabled. Set the GOOGLE_ANALYTICS_ID environment variable to your GA4 Measurement ID (e.g. G-XXXXXXXXXX). See CI/CD for how to set environment variables in GitHub Actions.
What Gets Tracked¶
Every <a> link rendered by Homebase — link buttons, portfolio cards, social icons, and featured video links — fires a GA event on click with these parameters:
| Parameter | Description | Example values |
|---|---|---|
destination |
The link label (what was clicked) | "YouTube", "GitHub", "course" |
link_type |
The component type | link_button, portfolio_card, social_icon, featured_video |
section |
Which section it belongs to | "Top Links", "social_icons", "featured_video" |
link_category |
Auto-classified destination type | "video", "social", "newsletter", "booking", "external" |
The event name defaults to creator_link_click. You can change it in site.yaml (see Configuration below).
link_category is computed automatically from the destination URL — no configuration needed. Classification rules:
| Category | URL patterns matched |
|---|---|
video |
youtube.com, youtu.be, vimeo.com, twitch.tv |
social |
twitter.com, x.com, linkedin.com, instagram.com, tiktok.com, threads.net, bsky.app, mastodon.*, facebook.com, pinterest.com, reddit.com |
newsletter |
substack.com, convertkit.com, mailchimp.com, beehiiv.com |
booking |
tidycal.com, calendly.com, cal.com |
external |
Everything else |
One-Time GA4 Setup¶
GA4 collects the raw event data automatically, but custom event parameters must be registered as Custom Dimensions before they appear in Explorations or Standard Reports.
Step 1 — Register Custom Dimensions¶
- Open Google Analytics → Admin (gear icon, bottom left)
- Under the Property column, click Custom definitions
- Click Create custom dimension and add all four:
| Display name | Scope | Event parameter |
|---|---|---|
| Link Destination | Event | destination |
| Link Type | Event | link_type |
| Link Section | Event | section |
| Link Category | Event | link_category |
- Save each one.
24–48 hour delay
After registering, allow 24–48 hours for data to start populating in the UI. The events are collected immediately — the delay is only for the dimension values to appear in reports.
Step 2 — Build a Link Click Exploration¶
- Go to Explore in the left sidebar
- Click Blank to start a new exploration
- In the Variables panel, click + next to Dimensions and add:
Event nameLink Destination(the custom dimension you registered)Link TypeLink SectionSession default channel group(orSession sourcefor more detail)
- Click + next to Metrics and add
Event count - In the Tab Settings panel:
- Technique: Free form
- Drag
Link Destinationinto Rows - Drag
Event countinto Values
- Add a Filter:
Event nameexactly matchescreator_link_click
Example output:
| Destination | Event Count |
|---|---|
| YouTube | 210 |
| GitHub | 175 |
| Blog | 82 |
| Course | 64 |
To add traffic source breakdown, drag Session default channel group into Columns.
Step 3 (Optional) — Mark High-Value Links as Conversions¶
If you want to track newsletter signups, course purchases, or other high-value links as conversions:
- GA4 → Admin → Events
- Find
creator_link_clickin the event list - Toggle Mark as conversion
Or create a more specific conversion using Conditions — for example, only when destination equals "newsletter". This requires no code changes; everything is configured inside GA.
Configuration¶
ga_event_name¶
Controls the GA event name sent on every link click. Set this once before deploying — GA4 cannot rename historical events, so changing it later starts a new, separate data series in your reports.
Common alternatives: link_click, outbound_click. Use a value that fits your existing GA naming convention if you already have one.
ga_label (per-link override)¶
By default, the destination parameter uses the link's title. If you use seasonal or campaign-specific titles that change over time, add ga_label to pin a stable key in GA regardless of how the title changes.
sections:
- title: "Courses"
links:
- title: "C# Masterclass (Spring Sale — 80% Off!)"
url: "https://example.com/course"
ga_label: "course" # GA always records "course", not the seasonal title
Looker Studio (Optional)¶
For a richer visual dashboard, connect GA4 to Looker Studio:
- Looker Studio → Create → Data source
- Choose Google Analytics, select your property
- Build charts for: top destinations, top traffic sources, clicks per link type, and conversion rate per source
No changes to Homebase are needed — Looker Studio reads from the same GA4 data.
Shop Analytics¶
When the shop is enabled, two additional GA4 events are fired automatically.
shop_item_click¶
Fired when a visitor clicks the CTA button on any shop card.
| Parameter | Type | Description | Example |
|---|---|---|---|
item_id |
string | Stable item identifier (ga_label if set, else id) |
"csharp-mastery" |
item_title |
string | Item title at the time of click | "C# .NET Mastery" |
collection_id |
string | Parent collection id |
"courses" |
item_type |
string | Item type field value |
"course", "ebook" |
item_price |
number | Item price (omitted if price is not set) | 97, 0 |
destination |
string | The destination URL | "https://…" |
The event name is configurable via shop.ga_event_name in site.yaml. Set it once before launch — GA4 cannot rename historical events.
shop_item_view¶
Fired once per item per page visit when a shop card enters the viewport (≥ 50% visible). Powered by IntersectionObserver.
| Parameter | Type | Description | Example |
|---|---|---|---|
item_id |
string | Stable item identifier | "csharp-mastery" |
item_title |
string | Item title | "C# .NET Mastery" |
collection_id |
string | Parent collection id |
"courses" |
item_type |
string | Item type field value |
"course" |
Observer not available
shop_item_view requires IntersectionObserver, which is available in all modern browsers. In environments where it is absent the impression event is silently skipped — click tracking is unaffected.
Register Shop Custom Dimensions¶
Open Admin → Custom definitions → Create custom dimension and add:
| Display name | Scope | Event parameter |
|---|---|---|
| Shop Item ID | Event | item_id |
| Shop Item Title | Event | item_title |
| Shop Collection ID | Event | collection_id |
| Shop Item Type | Event | item_type |
| Shop Item Price | Event | item_price |
Build a Shop Exploration¶
- Explore → Blank
- Add Dimensions:
Event name,Shop Item Title,Shop Collection ID,Shop Item Type - Add Metrics:
Event count - Filter:
Event nameexactly matchesshop_item_click - Drag
Shop Item Titleinto Rows andEvent countinto Values
To see conversion rate (clicks ÷ views), run two separate explorations — one filtered to shop_item_click and one to shop_item_view — then compare totals in a spreadsheet or Looker Studio.
Engagement Events¶
Three additional engagement events fire automatically on every page when GA4 is configured. No setup or configuration is required.
scroll_depth¶
Fires once per page visit at each scroll depth milestone.
| Parameter | Type | Values |
|---|---|---|
percent_scrolled |
number | 25, 50, 75, 100 |
Use this to see whether visitors are reading to the bottom of your page or bouncing early. Build an exploration filtered to scroll_depth with percent_scrolled as a dimension.
time_on_page¶
Fires once per milestone while the tab is in focus (pauses if the user switches tabs).
| Parameter | Type | Values |
|---|---|---|
time_on_page_sec |
number | 30, 60, 120, 300 |
A time_on_page_sec: 300 event means the visitor spent at least 5 active minutes on the page — a strong quality signal.
first_interaction¶
Fires once, on the first click, keypress, or touch anywhere on the page.
| Parameter | Type | Description |
|---|---|---|
element_type |
string | Tag name of the element first interacted with |
time_to_first_interaction_ms |
number | Milliseconds from page load to first interaction |
Register Engagement Custom Dimensions¶
Open Admin → Custom definitions → Create custom dimension and add:
| Display name | Scope | Event parameter |
|---|---|---|
| Scroll Depth % | Event | percent_scrolled |
| Time on Page (s) | Event | time_on_page_sec |
| First Interaction Element | Event | element_type |
| Time to First Interaction | Event | time_to_first_interaction_ms |
UTM Persistence¶
Homebase automatically persists UTM parameters across same-origin navigation using sessionStorage. If a visitor arrives at your page with a UTM-tagged URL (e.g. from a newsletter), those UTM values are re-attached to any same-origin links they click — so attribution is not lost when navigating between pages (e.g. from the home page to the shop).
This runs on every page load regardless of whether GA4 is configured. No configuration is needed.