0. Read This First — Scope, Honesty, and What Squarespace Will Not Let Us Do
What this means for the engagement
2.2 Data-retention and identity settings (do this immediately — it is not retroactive)
2.3 Enhanced Measurement configuration
2.4 Custom events — the full list for Trout Psychology
2.5 Handling the $250/mo subscription correctly
2.6 Key events (conversions) to configure
2.7 Custom dimensions to register
3.2 Installing GTM on Squarespace — exact placement
3.3 Order confirmation page injection — the one commerce hook you get
3.4 Form submission tracking — the reliable Squarespace method
3.9 Testing checklist — do not publish until every line is checked
4. Google Search Console Setup
4.4 The entity-disambiguation problem — what GSC will show you
5.1 Naming rules — non-negotiable
5.3 Campaign-name conventions for this business
6.3 Authority signals — the goal-critical section
6.5 Search Console performance
6.8 Action items for next month
7. One-Page Client-Facing Summary Format
8. Benchmarks and Realistic Expectations
8.2 Seasonality — plan the reporting calendar around it
8.3 The authority timeline — say this out loud in month one
10. Open Items Requiring Kristen's Confirmation
GA4 + Google Tag Manager + Google Search Console
Prepared: August 27, 2026
Client: Trout Psychology (Streamside Coven Co.) — Kristen Bufe
Site: https://www.troutpsychology.com
Platform: Squarespace (7.1, Commerce plan — cart, customer accounts, gift certificates active)
Phone: 206-659-5501
Primary goal: Brand authority — make the Trout Psychology Method the recognized standard in fly fishing education
Supporting goals: Fill guide trips; scale the $250/mo virtual casting lesson subscription
This guide is written to be executed by a non-developer with GTM open in one tab and Squarespace open in another. Where Squarespace genuinely constrains what is trackable, that is stated plainly rather than papered over. Do not promise the client e-commerce reporting that the platform cannot deliver.
1. Squarespace has no developer-accessible dataLayer for e-commerce.
Squarespace Commerce does not push view_item, add_to_cart, begin_checkout, or purchase events into a dataLayer object you can read from GTM. Squarespace's own native GA4 integration (Settings → Analytics → External Services) sends some e-commerce data directly to GA4 server-side, but it bypasses GTM entirely and you cannot modify, enrich, or add parameters to it. Consequence: you cannot build custom GA4 e-commerce tags in GTM that reliably capture item names, SKUs, or values on Squarespace without paid third-party middleware.
2. Checkout runs on a Squarespace-controlled domain.
The Squarespace checkout flow is served from *.squarespace.com (or a Squarespace-controlled checkout subdomain), not from troutpsychology.com. GTM code injected into your site's header does not load on the checkout pages. This is the single biggest tracking limitation.
Consequence: GTM-based purchase tracking on the checkout step is not possible. Purchase data must come from either (a) Squarespace's native GA4 connection, or (b) the order confirmation page injection point, which Squarespace exposes separately (see §3.3).
3. Code Injection availability is plan-dependent.
Header/footer Code Injection requires a Business plan or higher (Commerce plans include it). Since the site already runs Commerce, this is available. If a plan downgrade ever happens, all of this breaks. Note it in the client handoff.
4. Form submission detection is unreliable by default.
Squarespace native form blocks submit via AJAX and do not always fire a clean GTM "Form Submission" trigger. The reliable method is an Element Visibility trigger on the post-submit confirmation message, documented in §3.4. Do not use the built-in Form Submission trigger and assume it works — verify it.
5. Subscriptions report as one-off purchases by default.
The $250/mo virtual casting lesson is a Squarespace subscription product. GA4's native integration will record the first payment as a purchase event and will not record recurring monthly renewals as any web event — renewals happen server-side with no browser session. Consequence: GA4 will systematically understate subscription revenue. §2.5 and §6.4 describe how we handle this: track the signup as a distinct conversion with a modeled LTV, and reconcile actual MRR monthly from Squarespace's own Subscriptions panel. This is a manual reconciliation step and should be scoped as such.
We will get excellent data on: traffic, channels, content engagement, phone clicks, form submissions, booking-intent clicks, email signups, branded vs non-brand search, referral traffic from Instagram and YouTube, and returning-visitor share — i.e. all of the authority metrics that this engagement is actually measured on.
We will get partial data on: e-commerce item-level revenue, cart abandonment, and subscription renewals. These are reconciled monthly from Squarespace's own commerce reporting.
That trade is acceptable because the primary goal is brand authority, not conversion-rate optimization of a checkout funnel. Say this to the client up front so nobody is surprised in month three.
Complete before any tag work. Every item here is a blocker.
| # | Item | Owner | Status |
|---|---|---|---|
| 1 | Confirm which Google account will own GA4/GTM/GSC — use a business-owned account, not a personal Gmail Kristen might lose access to | Kristen | ☐ |
| 2 | Grant agency Admin on GA4, Publish on GTM, Owner on GSC | Kristen | ☐ |
| 3 | Confirm Squarespace plan is Business or Commerce (Code Injection required) | Agency | ☐ |
| 4 | Audit for existing GA4/UA/GTM tags already on the site (view source, search for gtag, GTM-, UA-) — double-tracking is the #1 setup error |
Agency | ☐ |
| 5 | Confirm ownership/access for streamsidecovenco.com (already 301-redirecting — verified Aug 27, 2026; no redirect-type fix needed, this is a registrar-access item only) |
Kristen | ☐ |
| 6 | Confirm YouTube channel ownership so the channel can be linked to GA4 for referral attribution | Kristen | ☐ |
| 7 | Confirm booking system vendor — is it Squarespace Scheduling (Acuity), a third-party embed, or an email/phone request flow? This materially changes §2.4 and §3.5. | Kristen | ☐ |
| 8 | HTTP 429 rate-limiting — *Verified not to affect Googlebot (Aug 27, 2026).* Confirm once via Search Console → Settings → Crawl stats; no longer a gating issue. One-time spot-check, not a prerequisite for sitemap submission | Agency | ☐ |
⚠️ Item 7 is the largest open question in this document. Everything below assumes a Squarespace-native or embedded booking flow. If booking is handled off-site (e.g. a third-party outfitter platform), booking conversions become outbound-click conversions and true booking completion is not trackable without vendor cooperation. Flag this to Kristen in the kickoff call.
Trout Psychology — Webhttps://www.troutpsychology.comTrout Psychology WebsiteG-XXXXXXXXXX) — you will need it in GTM. Record it in the credentials sheet.| Setting | Location | Value | Why |
|---|---|---|---|
| Event data retention | Admin → Data Settings → Data Retention | 14 months (max on free tier) | Default is 2 months. Without this, year-over-year seasonal comparison — critical for a spring-to-fall fishing business — is impossible. |
| Reset user data on new activity | Same screen | ON | Keeps returning visitors identified across the season. |
| Reporting identity | Admin → Reporting Identity | Blended | Best returning-visitor accuracy, which is a core authority metric. |
| Google signals | Admin → Data Settings → Data Collection | ON | Enables demographics + cross-device. Note: adds thresholding to small-sample reports. |
| Internal traffic filter | Admin → Data Streams → Configure tag settings → Define internal traffic | Add Kristen's and Nate's home/office IPs; set filter to Active | Two-person business — their own browsing is a meaningful share of low-volume traffic. This matters more here than for a large site. |
| Unwanted referrals | Same → List unwanted referrals | Add squarespace.com, checkout.squarespace.com, paypal.com, stripe.com |
Otherwise every checkout return is misattributed as a referral, destroying channel attribution. Do not skip this. |
Admin → Data Streams → Trout Psychology Website → Enhanced Measurement → gear icon.
| Measurement | Setting | Notes for this site |
|---|---|---|
| Page views | ON | Also enable "Page changes based on browser history events" — Squarespace uses AJAX page transitions on some templates. |
| Scrolls | ON | Fires at 90%. Useful as an authority-content engagement proxy; we add 25/50/75% depth in GTM (§3.6). |
| Outbound clicks | ON | Captures clicks to Instagram, YouTube, and streamsidecovenco.com. |
| Site search | ON | Squarespace uses ?q= as the search parameter. Enter q in the query-parameter field. High value — search terms reveal what students actually want from the Method. |
| Form interactions | ON | Fires form_start / form_submit. Treat as supplementary only — see §3.4 for the reliable method. |
| Video engagement | ON | Only fires for embedded YouTube players with JS API enabled. Squarespace video blocks usually qualify. Given a YouTube-heavy content strategy, this is worth having. |
| File downloads | ON | Will capture workbook PDFs, gear lists, and river-journal templates once the content engine ships. |
These are the events we build in GTM. Naming follows GA4 snake_case convention. Do not use reserved GA4 event names.
| Event name | What it means | Trigger | Parameters | Mark as key event |
|---|---|---|---|---|
guide_trip_inquiry |
Someone started a guided trip booking | Click on any guided-trip "Book"/"Check Availability" CTA, or booking-form confirmation visible | trip_type (streamer_raft | dry_fly_hardboat | shared_split), instructor (kristen | nate | any), page_location |
YES |
subscription_signup |
Virtual casting lesson subscription started ($250/mo) | Order confirmation page where product = Virtual Casting Lessons (see §3.3) | plan_name, monthly_value (250), modeled_ltv (see §2.5) |
YES |
retreat_registration |
Retreat / school / camp registration completed | Order confirmation where product matches retreat/school/camp SKU list | program_name (retreat_3day | casting_camp | school | streamer_stomp), program_date |
YES |
gift_certificate_purchase |
Gift certificate bought | Order confirmation where product = gift certificate | value, currency |
YES |
phone_click |
Tap/click on 206-659-5501 | Click on tel: link |
phone_number, page_location, link_position (header | footer | body) |
YES |
contact_form_submit |
Contact form completed | Element visibility on form confirmation message | form_name, form_location |
YES |
email_signup |
Newsletter / list signup | Element visibility on newsletter block confirmation | signup_location (footer | popup | blog_inline | landing) |
YES |
These are what actually prove the brand-authority thesis. Do not treat them as secondary just because they aren't revenue.
| Event name | What it means | Trigger | Parameters | Key event? |
|---|---|---|---|---|
method_page_engaged |
Deep engagement with core Method content | Scroll ≥75% AND ≥60s on any /method*, /about*, or blog page |
page_title, engagement_seconds |
No — but report monthly |
social_outbound_click |
Click through to IG or YT from site | Outbound click where hostname contains instagram.com or youtube.com |
social_platform, page_location |
No |
video_engagement_75 |
Watched 75% of an embedded video | GA4 native video_progress where video_percent = 75 |
video_title, video_provider |
No |
resource_download |
Downloaded a workbook / journal template / gear list | File download of .pdf, .docx, .xlsx |
file_name, file_extension |
Consider YES once content ships |
cta_click |
Any primary CTA button click | Click on .sqs-block-button-element |
cta_text, page_location |
No |
pricing_view |
Viewed a pricing/rates section | Element visibility on rates block | service_viewed |
No |
faq_expand |
Expanded an FAQ accordion | Click on accordion header | question_text |
No — but the report of which questions get opened is gold for content planning |
| Event | Source | Reliability |
|---|---|---|
view_item, add_to_cart, begin_checkout |
Squarespace native GA4 integration only | Medium — fires but parameters are not editable |
purchase |
Squarespace native GA4 integration | Medium — captures first payment only, not renewals |
add_payment_info |
Not available | ❌ Checkout is off-domain |
| Cart abandonment rate | Squarespace Commerce panel, not GA4 | Manual pull |
Instruct the client: enable Squarespace's native GA4 connection (Settings → Analytics → External Services → Google Analytics → paste the
G-Measurement ID) in addition to the GTM container. This is the one place where running two tag paths is correct: GTM handles everything custom, Squarespace-native handles the e-commerce events GTM cannot see. Ensure the Squarespace-native integration is set to e-commerce only if that toggle is present in your version; if it is not, verify in DebugView thatpage_viewis not being sent twice. If duplicate page views appear, remove the GA4 Configuration tag from GTM and let Squarespace-native handle base pageviews, keeping GTM for custom events only.
The problem: GA4 sees one purchase at $250 and never sees months 2–12. Reported ROI on the highest-strategic-value product will look 90% too low.
The approach — three parts:
Track the signup as its own key event (subscription_signup), separate from purchase. Never let the subscription be counted only as a $250 transaction.
Assign a modeled LTV, not the first payment. Until real retention data exists, use a placeholder assumption and label it clearly as an assumption in every report:
- Assumed average subscription life: [PLACEHOLDER — 6 months, to be replaced with actual cohort data after month 6]
- Modeled LTV = $250 × 6 = $1,500
- Set this as the event value on subscription_signup.
- Re-derive this number from real Squarespace subscription data at month 6 and month 12. Do not let a placeholder harden into a fact.
Reconcile MRR monthly, by hand. Squarespace → Commerce → Subscriptions gives active subscriber count, new subs, and cancellations. Pull these into the monthly report (§6.4). GA4 tells you where subscribers came from; Squarespace tells you how many you have. Neither alone is sufficient.
Churn is the metric nobody will ask for and everybody will need. Add Subscriptions cancelled to the monthly template from month one, even when the number is zero.
Admin → Events → mark as key event:
guide_trip_inquirysubscription_signupretreat_registrationgift_certificate_purchasephone_clickcontact_form_submitemail_signuppurchase (native — leave on)Do not mark more than these. Every extra key event dilutes the conversion rate metric and makes the report meaningless.
cta_clickandscrollare not conversions no matter how tempting.
Admin → Custom definitions → Create custom dimension. Event-scoped unless noted. Register these or the parameters will not appear in reports.
| Dimension name | Scope | Event parameter |
|---|---|---|
| Trip Type | Event | trip_type |
| Instructor | Event | instructor |
| Program Name | Event | program_name |
| Form Name | Event | form_name |
| Form Location | Event | form_location |
| Signup Location | Event | signup_location |
| CTA Text | Event | cta_text |
| Social Platform | Event | social_platform |
| Link Position | Event | link_position |
| File Name | Event | file_name |
| Question Text | Event | question_text |
| Plan Name | Event | plan_name |
GA4 free tier allows 50 event-scoped custom dimensions. We are using 12. Register them before launch — dimensions are not retroactive, and data collected before registration is unrecoverable.
Admin → Audiences → New audience. Build all of these on day one; audiences only populate forward from creation.
| Audience | Definition | Why it matters here |
|---|---|---|
| Method Students (engaged) | method_page_engaged OR (page_path contains /method AND engagement_time > 60s) |
The authority audience — the core measurement of whether the Method content is landing |
| Guide Trip Intenders | Viewed any /guided* page, no guide_trip_inquiry in 30 days |
Remarketing pool for shoulder season |
| Subscription Intenders | Viewed /virtual* or /casting-lessons*, no subscription_signup |
Highest-value nurture pool |
| Converters (all) | Any Tier 1 key event | Suppression list + lookalike seed |
| Returning Authority Audience | Returning user AND ≥2 sessions in 30 days AND viewed blog or Method page | This is the single best proxy for brand authority. Track its size monthly. |
| Social Referred | Session source = instagram OR youtube OR l.instagram.com | Measures whether social traffic actually engages or bounces |
| Gift Season Shoppers | Viewed gift certificate page, Oct–Dec | Seasonal remarketing |
| PNW Local | Region = Washington OR Oregon | Separates local guide-trip demand from national Method demand |
| National / Non-Local | Region ≠ WA/OR/ID | The virtual-lesson and authority audience — should grow if the strategy works |
The National / Non-Local audience deserves special attention. If the authority strategy is working, non-local traffic should grow faster than local traffic, because the Method is geography-independent. Watch the ratio.
Save these in the GA4 UI (Reports → Insights → Comparisons) so Kristen can self-serve:
- Local (WA/OR) vs. National — the authority-reach test
- New vs. Returning — the authority-loyalty test
- Social referral vs. Organic search — the channel-independence test
Trout Psychologytroutpsychology.com<head> and <body>).Squarespace → Settings → Developer Tools → Code Injection
HEADER field — paste the full <head> snippet:
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
Replace
GTM-XXXXXXXwith the real container ID.
FOOTER field — paste the <noscript> snippet:
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
Honest note: Squarespace has no true
<body>-open injection point. Placing the<noscript>iframe in the Footer field is the standard accepted workaround. It only affects users with JavaScript disabled (a rounding error of traffic) and does not affect normal measurement. Do not spend time trying to "fix" this.
Then click SAVE. Code Injection changes are live immediately — there is no separate publish step in Squarespace for this field.
Squarespace → Settings → Developer Tools → Code Injection → ORDER CONFIRMATION PAGE
This field injects only on the post-purchase confirmation page and does have access to the order object. This is how we capture the subscription, retreat, and gift certificate conversions that GTM otherwise cannot see.
<script>
window.dataLayer = window.dataLayer || [];
// Squarespace exposes order data on the confirmation page.
// VERIFY the shape of window.Static.SQUARESPACE_CONTEXT in a live test order
// before relying on the field names below — Squarespace changes this object
// without notice and it is NOT a documented public API.
(function () {
try {
var ctx = window.Static && window.Static.SQUARESPACE_CONTEXT;
var order = ctx && ctx.order ? ctx.order : null;
if (!order) { return; }
var items = (order.items || []).map(function (i) {
return {
item_id: i.sku || i.productId || '',
item_name: i.productName || '',
price: i.unitPricePaid ? (i.unitPricePaid.value || 0) : 0,
quantity: i.quantity || 1
};
});
var names = items.map(function (i) { return (i.item_name || '').toLowerCase(); }).join(' | ');
window.dataLayer.push({
event: 'sqs_order_complete',
order_id: order.id || '',
order_value: order.grandTotal ? (order.grandTotal.value || 0) : 0,
order_currency: order.grandTotal ? (order.grandTotal.currency || 'USD') : 'USD',
order_items: items,
order_item_names: names
});
} catch (e) {
// Fail silently — never let analytics break a customer's confirmation page.
}
})();
</script>
⚠️ PLACEHOLDER — MUST VERIFY.
window.Static.SQUARESPACE_CONTEXT.orderis an undocumented internal object. Before this goes live, place a real $1 test product order and inspect the object in the browser console. Adjust field names to match what you actually see. Do not ship this untested — but equally, do not skip it, because it is the only route to product-level conversion attribution on this platform.
Product-name matching: the order_item_names string is what GTM triggers key off. This requires that Squarespace product names are stable and distinctive. Before launch, confirm with Kristen the exact product names and lock them:
| Conversion | Product name must contain | Current name [CONFIRM] |
|---|---|---|
| Subscription | casting AND virtual |
[PLACEHOLDER — confirm exact SKU name] |
| Retreat | retreat |
[PLACEHOLDER] |
| Casting Camp | camp |
[PLACEHOLDER] |
| School | school |
[PLACEHOLDER] |
| Streamer Stomp | streamer stomp |
[PLACEHOLDER] |
| Gift certificate | gift |
[PLACEHOLDER] |
If a product is ever renamed, these triggers break silently. Add "check conversion tracking" to the checklist for any product rename.
Do not rely on GTM's built-in Form Submission trigger. Squarespace forms submit via AJAX; the native trigger fires inconsistently and sometimes fires on validation failure.
Correct method — Element Visibility on the confirmation message:
.form-submission-text or a div inside .sqs-block-form containing the confirmation copy..sqs-block-form .form-submission-text50EV — Form Confirmation Visible⚠️ PLACEHOLDER: the exact CSS selector depends on the template version. Verify with DevTools on the live site and record the confirmed selector here:
[CONFIRMED SELECTOR: ______________]
Distinguishing which form was submitted: add a Page Path condition to separate the contact form from the newsletter block, or read the form's data-form-id. If multiple forms exist on one page, capture the parent form's ID via a DOM Element variable.
Scenario A — Squarespace Scheduling / Acuity embed (most likely):
The booking widget loads in an iframe on a different origin. GTM in the parent page cannot see clicks or submissions inside it.
- What you can track: the click that opens the scheduler (guide_trip_inquiry as an intent event).
- What you cannot track from GTM: completed bookings inside the iframe.
- Fix: In Acuity/Scheduling → Integrations, enable the Google Analytics conversion tracking setting and provide the GA4 Measurement ID. Acuity fires its own conversion. Alternatively set the post-booking redirect to a thank-you page on troutpsychology.com and fire a page-view-based trigger there. The redirect method is preferred — it is more reliable and gives you a clean URL to key off.
Scenario B — Booking is a Squarespace product purchase:
Then it flows through §3.3 and is fully tracked.
Scenario C — Booking is by phone/email request:
Then phone_click and contact_form_submit are the booking conversions. Report them as such and say so plainly.
Resolve which scenario applies (Pre-Flight item 7) before building these tags. Building for the wrong scenario wastes a full setup cycle.
| # | Tag name | Type | Trigger | Notes |
|---|---|---|---|---|
| 1 | GA4 — Configuration |
Google Tag | All Pages | Measurement ID G-XXXXXXXXXX. See §2.4 note on duplicate pageviews. |
| 2 | GA4 — Phone Click |
GA4 Event | CL — Phone Link |
Event: phone_click |
| 3 | GA4 — Contact Form Submit |
GA4 Event | EV — Form Confirmation Visible |
Event: contact_form_submit |
| 4 | GA4 — Email Signup |
GA4 Event | EV — Newsletter Confirmation Visible |
Event: email_signup |
| 5 | GA4 — Guide Trip Inquiry |
GA4 Event | CL — Booking CTA |
Event: guide_trip_inquiry |
| 6 | GA4 — Subscription Signup |
GA4 Event | CE — Order: Subscription |
Event: subscription_signup, value = modeled LTV |
| 7 | GA4 — Retreat Registration |
GA4 Event | CE — Order: Retreat/School/Camp |
Event: retreat_registration |
| 8 | GA4 — Gift Certificate |
GA4 Event | CE — Order: Gift Certificate |
Event: gift_certificate_purchase |
| 9 | GA4 — Social Outbound |
GA4 Event | CL — Social Outbound |
Event: social_outbound_click |
| 10 | GA4 — CTA Click |
GA4 Event | CL — Squarespace Button |
Event: cta_click |
| 11 | GA4 — Scroll Depth |
GA4 Event | Scroll — 25/50/75 |
Event: scroll_depth, param percent_scrolled |
| 12 | GA4 — Method Engaged |
GA4 Event | Timer — 60s on Method/Blog |
Event: method_page_engaged |
| 13 | GA4 — FAQ Expand |
GA4 Event | CL — FAQ Accordion |
Event: faq_expand |
| 14 | Google Ads — Conversion Linker |
Conversion Linker | All Pages | Install now even with no ads running; it costs nothing and prevents attribution loss later. |
| Trigger name | Type | Configuration |
|---|---|---|
CL — Phone Link |
Click — Just Links | Click URL contains tel: |
CL — Social Outbound |
Click — Just Links | Click URL matches RegEx instagram\.com\|youtube\.com\|youtu\.be |
CL — Booking CTA |
Click — All Elements | Click Text matches RegEx (ignore case) book\|reserve\|check availability\|schedule |
CL — Squarespace Button |
Click — All Elements | Click Element matches CSS selector .sqs-block-button-element, .sqs-block-button-element--medium, .sqs-block-button-element--large |
CL — FAQ Accordion |
Click — All Elements | Click Element matches CSS selector .accordion-item__title, summary |
EV — Form Confirmation Visible |
Element Visibility | See §3.4. Observe DOM changes = ON |
EV — Newsletter Confirmation Visible |
Element Visibility | CSS: .newsletter-form-success — verify selector |
CE — Order: Subscription |
Custom Event | Event name sqs_order_complete; condition: DL — order_item_names contains casting |
CE — Order: Retreat/School/Camp |
Custom Event | Event name sqs_order_complete; condition: DL — order_item_names matches RegEx retreat\|camp\|school\|streamer stomp |
CE — Order: Gift Certificate |
Custom Event | Event name sqs_order_complete; condition: DL — order_item_names contains gift |
Scroll — 25/50/75 |
Scroll Depth | Vertical, percentages 25,50,75 |
Timer — 60s on Method/Blog |
Timer | Interval 60000ms, Limit 1, condition Page Path matches RegEx ^/(method\|about\|blog) |
Enable these built-ins (Variables → Configure):
Click Element, Click Classes, Click ID, Click Text, Click URL, Form ID, Form Classes, Page Path, Page URL, Page Hostname, Referrer, Event.
Create these user-defined variables:
| Variable name | Type | Configuration |
|---|---|---|
Const — GA4 Measurement ID |
Constant | G-XXXXXXXXXX |
DL — order_id |
Data Layer Variable | order_id |
DL — order_value |
Data Layer Variable | order_value |
DL — order_currency |
Data Layer Variable | order_currency |
DL — order_item_names |
Data Layer Variable | order_item_names |
JS — Phone Number |
Custom JavaScript | Strips tel: prefix from Click URL and returns digits only |
JS — Link Position |
Custom JavaScript | Walks up the DOM from the clicked element; returns header, footer, or body |
LT — Social Platform |
Lookup Table | Input Click URL; instagram → Instagram, youtube → YouTube |
Const — Subscription LTV |
Constant | 1500 — placeholder, revisit at month 6 |
JS — Phone Number:
function () {
var u = {{Click URL}} || '';
return u.replace(/^tel:/i, '').replace(/[^0-9+]/g, '');
}
JS — Link Position:
function () {
try {
var el = {{Click Element}};
while (el && el !== document.body) {
var t = (el.tagName || '').toLowerCase();
var c = (el.className && el.className.baseVal !== undefined)
? el.className.baseVal
: (el.className || '');
c = String(c).toLowerCase();
if (t === 'header' || c.indexOf('header') > -1) { return 'header'; }
if (t === 'footer' || c.indexOf('footer') > -1) { return 'footer'; }
el = el.parentElement;
}
return 'body';
} catch (e) {
return 'unknown';
}
}
Open GTM → Preview and connect to https://www.troutpsychology.com. In parallel open GA4 → Admin → DebugView.
| # | Test | Expected | ☐ |
|---|---|---|---|
| 1 | Load homepage | GA4 — Configuration fires once (not twice) |
☐ |
| 2 | Check DebugView for duplicate page_view |
Exactly one per pageview | ☐ |
| 3 | Click the phone number (mobile emulation) | phone_click with correct phone_number = 2066595501 |
☐ |
| 4 | Submit contact form with test data | contact_form_submit fires once, only after real success |
☐ |
| 5 | Submit contact form with an invalid email | No event fires | ☐ |
| 6 | Sign up to newsletter | email_signup with correct signup_location |
☐ |
| 7 | Click a guided-trip booking CTA | guide_trip_inquiry fires |
☐ |
| 8 | Click Instagram icon in footer | social_outbound_click, social_platform = Instagram |
☐ |
| 9 | Scroll a blog post to bottom | scroll_depth at 25, 50, 75 + native 90% |
☐ |
| 10 | Sit on Method page 60s | method_page_engaged fires once |
☐ |
| 11 | Place a real $1 test order (temporary hidden product) | sqs_order_complete pushes with populated order_item_names |
☐ |
| 12 | Place a test subscription order | subscription_signup fires with value = 1500 |
☐ |
| 13 | Confirm checkout return is not counted as referral | Source is preserved, not squarespace.com |
☐ |
| 14 | Verify from Kristen's own IP | Events are filtered as internal traffic | ☐ |
| 15 | Test on real iPhone + real Android, not just emulator | All click events fire | ☐ |
| 16 | Confirm all custom dimensions appear in DebugView | Parameters populated, not (not set) |
☐ |
Then: delete the test product, refund the test order, and Publish the container with version name v1.0 — Initial Setup and a description listing what shipped.
troutpsychology.com as a Domain property via DNS TXT record. This captures http, https, www, and non-www in one property. Squarespace-hosted DNS: Settings → Domains → DNS Settings → Add TXT record.streamsidecovenco.com as a separate Domain property. It already 301-redirects to the primary domain (verified by direct header inspection at root and deep paths, Aug 27, 2026 — SEO Site Audit.md §3, Citation Audit Report.md §1). There is no 302 to fix. Add the property so we can see what the legacy domain is still receiving and decide whether it is worth building out, but the redirect itself needs no remediation.Squarespace auto-generates https://www.troutpsychology.com/sitemap.xml. Submit it under Indexing → Sitemaps.
✅ Not a blocker — resolved. The engagement brief flagged repeated HTTP 429 responses to crawlers. Verified not to affect Googlebot (Aug 27, 2026). Confirm once via Search Console → Settings → Crawl stats; no longer a gating issue. Eight unspaced Googlebot-UA requests all returned 200 and ~30 audit requests produced zero 429s; the earlier 429s were datacenter-IP throttling of our own fetcher (
SEO Site Audit.md§3;00 - Client Profile.mdADDENDUM). Submit the sitemap normally. Glance at the Crawl stats "By response" panel once after submission; if a429bucket appears against Googlebot, escalate to Squarespace support with timestamps. Otherwise close it out.
The profile flags that "Trout Psychology" reads as a mental-health practice to search engines, and that title tags carry legacy "SCco." branding. GSC is your measurement instrument for whether this gets fixed.
Set up these saved filters in the Performance report and check them monthly:
| Saved filter | Query filter | What it tells you |
|---|---|---|
| Branded — correct | Query contains trout psychology |
Core brand demand |
| Branded — variants | Query contains troutpsych OR trout psych OR kristen bufe OR streamside coven OR streamer stomp |
Total brand equity including the founder's personal brand |
| Non-brand informational | Query does NOT contain the brand terms above AND query contains how OR what OR why OR learn OR tips |
The authority metric. This is the number that must grow. |
| Method-specific | Query contains trout behavior OR think like a trout OR streamer fishing OR casting lesson |
Whether the Method vocabulary is being searched |
| Local guide intent | Query contains yakima OR cle elum OR guide OR washington |
Local demand |
| Disambiguation risk | Query contains therapist OR counseling OR mental health OR psychologist |
Wrong-intent traffic. If this is significant, the brand-entity problem is real and quantified. Report it. |
That last filter is a genuinely useful diagnostic. If people searching for a therapist are landing on a fly fishing site, both the bounce rate and the wasted impressions are measurable — and that gives you the evidence to justify the entity-disambiguation work in the SEO track.
Discovered — currently not indexed (can be a 429 symptom — but 429s were verified not to affect Googlebot on Aug 27, 2026, so look at crawl budget and internal linking first)Instagram and instagram become two separate sources.| Channel | utm_source |
utm_medium |
utm_campaign |
utm_content |
|---|---|---|---|---|
| Instagram bio link | instagram |
social |
bio-link |
— |
| Instagram story link | instagram |
social |
story-YYYY-MM |
reel or post topic |
| Instagram reel caption/link | instagram |
social |
reel-YYYY-MM |
reel topic slug |
| YouTube video description | youtube |
social |
video-[slug] |
description |
| YouTube pinned comment | youtube |
social |
video-[slug] |
pinned-comment |
| Email newsletter | newsletter |
email |
YYYY-MM-[topic] |
link position |
| Email — subscription nurture | newsletter |
email |
nurture-casting-sub |
email number |
| Google Business Profile | google |
organic |
gbp |
website-button |
| Podcast appearance | [podcast-name] |
referral |
podcast-YYYY-MM |
— |
| Press / editorial feature | [publication] |
referral |
press-[slug] |
— |
| Google Ads (future) | google |
cpc |
[campaign] |
ad variant |
| Print / QR code (retreats, fly shops) | print |
offline |
[piece-name] |
placement |
Because the business is seasonal, encode the season:
- spring-2027-guide-trips
- winter-2026-virtual-casting
- holiday-2026-gift-certificates
- streamer-stomp-2027
Maintain a shared Google Sheet with columns: Date created | Destination URL | Source | Medium | Campaign | Content | Full tagged URL | Where used | Notes.
Build URLs with ga-dev-tools.google/campaign-url-builder/.
Practical warning: Instagram strips and re-writes referrers unpredictably, and in-app browsers frequently break attribution. UTM tagging the bio link is the only reliable way to attribute Instagram traffic. Given that Instagram is described as the strongest brand asset, tagging that one link is disproportionately valuable. Do it in week one.
Two documents are produced each month:
- §6.1–6.8 — the full internal report (agency working document)
- §7 — a one-page client-facing summary (what Kristen actually reads)
Reporting period: calendar month. Delivered by the 10th of the following month.
| Metric | This month | Prev month | Δ % | Same month LY | Δ % YoY |
|---|---|---|---|---|---|
| Sessions | |||||
| Total users | |||||
| New users | |||||
| Returning users | |||||
| Returning-visitor share (%) | |||||
| Engaged sessions | |||||
| Engagement rate | |||||
| Avg. engagement time/session | |||||
| Pages per session |
Traffic by channel: Organic Search, Direct, Organic Social, Referral, Email, Paid (when live) — sessions, engagement rate, and conversions for each.
Geographic split:
| Segment | Sessions | % of total | Conversions |
|---|---|---|---|
| Washington | | | |
| Pacific Northwest (OR, ID) | | | |
| Rest of US | | | |
| International | | | |
Watch the "Rest of US" line. For a business whose scalable product is geography-independent, non-local growth is the authority signal.
Top 10 landing pages by sessions with engagement rate and conversions.
This section is the reason this engagement exists. It goes before the conversion section, not after.
| # | Metric | Source | This month | Prev | Δ | 6-mo trend |
|---|---|---|---|---|---|---|
| A1 | Branded search impressions | GSC — "Branded — variants" filter | ||||
| A2 | Branded search clicks | GSC | ||||
| A3 | Non-brand informational impressions | GSC — "Non-brand informational" filter | ||||
| A4 | Non-brand informational clicks | GSC | ||||
| A5 | Method-vocabulary impressions | GSC — "Method-specific" filter | ||||
| A6 | Unique non-brand queries (count of distinct queries with ≥1 impression) | GSC | ||||
| A7 | Returning-visitor share | GA4 | ||||
| A8 | Returning Authority Audience size | GA4 audience | ||||
| A9 | Instagram referral sessions | GA4 | ||||
| A10 | YouTube referral sessions | GA4 | ||||
| A11 | Social referral engagement rate | GA4 | ||||
| A12 | Referring domains (new this month) | GSC → Links | ||||
| A13 | Direct traffic sessions (brand-recall proxy) | GA4 | ||||
| A14 | Avg. engagement time on Method/blog pages | GA4 | ||||
| A15 | method_page_engaged events |
GA4 | ||||
| A16 | Video 75% completions | GA4 | ||||
| A17 | Resource downloads | GA4 | ||||
| A18 | Wrong-intent impressions (therapist/counseling queries) | GSC — "Disambiguation risk" | ↓ is good |
Authority Index — a single composite number so trend is visible at a glance. Index each of A1, A3, A7, A9+A10, A12 to its own month-1 baseline = 100, then take the unweighted mean.
Be honest about what this index is: a directional trend line built from a small-traffic site, not a statistically rigorous measure. It is useful for showing whether the curve bends up over 6–12 months. It is not useful month-to-month on low volume, and it should not be presented as precise. Say this in the footnote every time it appears.
Interpretation guide for the client:
- A1/A2 rising = more people are looking for you by name. This is the purest brand-authority signal.
- A3/A4 rising while A1 is flat = your content is being discovered by strangers. This is the top of the authority funnel and it should move first.
- A3 rising and then A1 rising 3–6 months later = the strategy is working as designed. This lag is expected. Set that expectation in month one so nobody panics in month three.
- A7/A8 rising = people come back. Authority is retention, not just reach.
- A18 falling = the entity-disambiguation work is landing.
| Conversion | Count | Δ vs prev | Conv. rate | Value |
|---|---|---|---|---|
| Guide trip inquiries | ||||
| Subscription signups | modeled LTV | |||
| Retreat/school/camp registrations | ||||
| Gift certificate purchases | ||||
| Phone clicks | ||||
| Contact form submits | ||||
| Email signups | ||||
| Total key events |
Subscription health — reconciled from Squarespace, not GA4:
| Metric | This month | Prev month |
|---|---|---|
| Active subscribers | ||
| New subscriptions | ||
| Cancellations | ||
| Net change | ||
| MRR (active × $250) | ||
| Churn rate | ||
| Avg. subscription age (months) |
Footnote this every month: "GA4 records the first subscription payment only. Recurring revenue is reconciled manually from Squarespace Commerce → Subscriptions. GA4 subscription revenue figures will always understate actual MRR."
Conversion by channel and top converting pages tables follow.
Once the blog ships (currently a flagged gap):
| Post | Sessions | Avg. engagement time | Scroll 75% | Email signups | GSC impressions |
|---|---|---|---|---|---|
Currently not applicable — GBP is unconfirmed/unclaimed and there is no published street address.
Once GBP is claimed as a service-area business (which is the correct model here — see the Schema deliverable), add: profile views, search vs. maps discovery, calls, website clicks, direction requests, review count and rating, photo views, post views.
Honest constraint: a service-area business with no published address has reduced local-pack eligibility compared to a business with a verified storefront. GBP is still worth claiming and will still rank in some local queries, but do not promise map-pack dominance for "fly fishing guide near me" without an address. Set this expectation now.
Three columns: Do more of this / Fix this / Stop this. Every item names an owner and a due date. Maximum 5 items — a list of 15 gets ignored.
Kristen runs a two-person business and guides on the water most days in season. This page is what she actually reads. One page. Plain language. No acronyms without a plain-English gloss.
┌──────────────────────────────────────────────────────────────────┐
│ TROUT PSYCHOLOGY — [MONTH YEAR] │
│ Marketing Snapshot │
├──────────────────────────────────────────────────────────────────┤
│ │
│ THE HEADLINE │
│ [One sentence. What actually happened this month.] │
│ │
├──────────────────────────────────────────────────────────────────┤
│ ARE MORE PEOPLE FINDING YOU? │
│ │
│ Website visitors ............ ____ ( ▲ / ▼ __% vs last month) │
│ People searching your name .. ____ ( ▲ / ▼ __% ) │
│ People who came back ........ ___% ( ▲ / ▼ __ pts ) │
│ Times you appeared in Google │
│ for fly-fishing questions .. ____ ( ▲ / ▼ __% ) │
│ │
│ ► What this means: [2 sentences, plain English] │
│ │
├──────────────────────────────────────────────────────────────────┤
│ WHAT DID PEOPLE DO? │
│ │
│ Guide trip inquiries ................ ____ │
│ New virtual lesson subscribers ...... ____ │
│ Total active subscribers ............ ____ ($____ /mo) │
│ Retreat / school signups ............ ____ │
│ Gift certificates ................... ____ │
│ Phone calls from the site ........... ____ │
│ Contact forms ....................... ____ │
│ Email list signups .................. ____ │
│ │
├──────────────────────────────────────────────────────────────────┤
│ WHERE THEY CAME FROM │
│ │
│ Google search .......... ___% Instagram ......... ___% │
│ Typed you in directly .. ___% YouTube ........... ___% │
│ Other sites ............ ___% Email ............. ___% │
│ │
├──────────────────────────────────────────────────────────────────┤
│ THE ONE NUMBER TO WATCH │
│ │
│ Authority Index: ____ ( baseline 100 in [month] ) │
│ ▁▂▃▄▅▆ [6-month sparkline] │
│ │
│ This blends: brand searches, non-brand discovery, repeat │
│ visitors, social referrals, and new sites linking to you. │
│ It is a trend line, not a precise score — read the direction, │
│ not the decimal. │
│ │
├──────────────────────────────────────────────────────────────────┤
│ THREE THINGS THAT WORKED │
│ 1. ____________________________________________ │
│ 2. ____________________________________________ │
│ 3. ____________________________________________ │
│ │
│ THREE THINGS WE'RE FIXING │
│ 1. ____________________________________________ │
│ 2. ____________________________________________ │
│ 3. ____________________________________________ │
│ │
├──────────────────────────────────────────────────────────────────┤
│ WHAT WE NEED FROM YOU │
│ ▢ ______________________________ by ______ │
│ ▢ ______________________________ by ______ │
│ │
│ Questions? [agency contact] │
└──────────────────────────────────────────────────────────────────┘
Rules for filling this in:
- Never use "impressions," "sessions," "CTR," or "engagement rate" on this page without a plain-English translation.
- "What we need from you" never has more than two items. Kristen is on the water.
- If a number went down, say so on the page. Do not bury it in the appendix.
- The Authority Index caveat sentence stays every single month. Do not drop it once the number looks good.
Read this section aloud in the kickoff call. Setting expectations correctly is worth more than any tag in this document.
Outdoor recreation / guided-experience / niche-education businesses:
| Metric | Typical range | Notes for Trout Psychology |
|---|---|---|
| Engagement rate | 55–70% | Content-heavy authority pages should exceed this |
| Avg. engagement time | 45–90s | Method pages should run higher; if not, the content isn't landing |
| Pages per session | 2.0–3.5 | |
| Returning-visitor share | 25–35% | Target 40%+ if the authority strategy works. This is the KPI. |
| Site-wide conversion rate (all key events) | 2–5% | |
| Phone-click rate (mobile) | 3–8% | Mobile-only denominator |
| Email signup rate | 1–3% of sessions | Requires an actual lead magnet — currently missing |
| Organic traffic growth | 5–15% MoM in year one from a low base | Percentages on small numbers are volatile and can mislead. Report absolute numbers alongside every percentage. |
| E-commerce conversion rate | 1–3% | High-ticket ($250+) products sit at the low end |
Yakima River fishing peaks spring through fall. Expect:
- Mar–Jun: rising traffic, guide-trip bookings peak
- Jul–Aug: high traffic, possible mid-summer heat-closure dip
- Sep–Oct: second peak (fall streamer season — Kristen's specialty)
- Nov–Dec: traffic drops, gift certificate purchases spike
- Jan–Feb: trough for trips, best window for virtual subscription growth and content publishing
Consequence for reporting: month-over-month comparison is close to meaningless in this business. Year-over-year is the only honest comparison, which is why 14-month data retention (§2.2) is set on day one. Until 12 months of data exists, compare against a rolling 3-month average and say that the YoY comparison is not yet available. Do not present a January-vs-December decline as a performance problem.
| Timeframe | Realistic expectation |
|---|---|
| Months 1–2 | Tracking live, baselines set. No performance change. Fixing titles and schema. |
| Months 3–4 | Non-brand impressions begin rising. Clicks lag impressions. |
| Months 5–8 | Non-brand clicks rise. First unprompted links/citations appear. |
| Months 9–12 | Branded search begins rising — the lagging indicator finally moves. |
| Months 12+ | Compounding. Method vocabulary starts appearing in searches nobody prompted. |
Brand authority is a lagging indicator by definition. If the client expects branded search growth in month three, the engagement will be judged a failure while it is actually on track. Set this expectation in writing, in month one.
| Week | Tasks | Owner |
|---|---|---|
| 1 | Pre-flight checklist. Audit existing tags. One-time Crawl-stats spot-check for 429s (verified not a Googlebot issue — see §4). UTM-tag the Instagram bio link. | Agency |
| 1 | Create GA4 property; set data retention to 14 months; configure unwanted referrals + internal traffic | Agency |
| 1 | Create GTM container; install via Code Injection; enable Squarespace-native GA4 for e-commerce | Agency |
| 2 | Verify GSC Domain properties (both domains); submit sitemap; link GSC↔GA4 | Agency |
| 2 | Register all 12 custom dimensions before any traffic accrues | Agency |
| 2 | Build all tags, triggers, variables | Agency |
| 2 | Place and verify a real test order; confirm the order-confirmation dataLayer shape | Agency |
| 3 | Full testing checklist (§3.9); publish container v1.0 | Agency |
| 3 | Build the 9 audiences; save the 3 comparisons; build GSC saved filters | Agency |
| 4 | Baseline report — establishes the Authority Index baseline of 100 | Agency |
| 4 | Client walkthrough: what is tracked, what is not, and why; set the 12-month expectation | Agency + Kristen |
| Month 2+ | Monthly reporting cycle, delivered by the 10th | Agency |
| Month 6 | Replace the placeholder subscription LTV with real cohort data | Agency |
| # | Item | Blocks |
|---|---|---|
| 1 | Booking system vendor — Squarespace Scheduling/Acuity, third-party, or manual? | §3.5 — booking conversion tracking |
| 2 | Exact Squarespace product names for every paid offering | §3.3 — all order-based conversions |
| 3 | Google account that will own the analytics stack | Everything |
| 4 | YouTube channel ownership and URL | §5, referral attribution |
| 5 | Whether streamsidecovenco.com should stay a redirect, or be built out (the redirect is already a 301 — nothing to fix) |
§4.1 |
| 6 | Existing email platform (Squarespace Email Campaigns, Mailchimp, other) | §5.2 UTM conventions |
| 7 | Whether the "split with a stranger" shared trip is a separate bookable product | §2.4 trip_type values |
| 8 | Confirmation that no prior GA/GTM property exists with historical data worth preserving | §1 item 4 |
Fill and store in the client's password manager. Do not store in this document.
| Asset | ID / URL | Owner account | Agency access level |
|---|---|---|---|
| GA4 Property ID | [G-XXXXXXXXXX] |
Administrator | |
| GA4 Property Number | [XXXXXXXXX] |
||
| GTM Container ID | [GTM-XXXXXXX] |
Publish | |
| GSC Property (primary) | troutpsychology.com |
Owner | |
| GSC Property (secondary) | streamsidecovenco.com |
Owner | |
| Squarespace login | Kristen | Contributor (Admin) | |
| Booking system | [TBD] |
Give this list to whoever maintains the site.
SQUARESPACE_CONTEXT object — it is undocumented and unversioned; it can change without notice.Therefore: run the §3.9 testing checklist as a quarterly health check, not just at launch. Silent tag failure is the most common and most expensive analytics problem, and nothing in the interface will tell you it happened.
Prepared for Trout Psychology — Phase 1 Foundation. Every value marked [PLACEHOLDER] or [CONFIRM] must be resolved before this guide is executed.
0. Read This First — Scope, Honesty, and What Squarespace Will Not Let Us Do
What this means for the engagement
2.2 Data-retention and identity settings (do this immediately — it is not retroactive)
2.3 Enhanced Measurement configuration
2.4 Custom events — the full list for Trout Psychology
2.5 Handling the $250/mo subscription correctly
2.6 Key events (conversions) to configure
2.7 Custom dimensions to register
3.2 Installing GTM on Squarespace — exact placement
3.3 Order confirmation page injection — the one commerce hook you get
3.4 Form submission tracking — the reliable Squarespace method
3.9 Testing checklist — do not publish until every line is checked
4. Google Search Console Setup
4.4 The entity-disambiguation problem — what GSC will show you
5.1 Naming rules — non-negotiable
5.3 Campaign-name conventions for this business
6.3 Authority signals — the goal-critical section
6.5 Search Console performance
6.8 Action items for next month
7. One-Page Client-Facing Summary Format
8. Benchmarks and Realistic Expectations
8.2 Seasonality — plan the reporting calendar around it
8.3 The authority timeline — say this out loud in month one
10. Open Items Requiring Kristen's Confirmation