Websites / Cloudflare
Site Launch Gate
SOP: Site Launch Tracking Gate
Section titled “SOP: Site Launch Tracking Gate”Last Updated: 2026-06-08 Version: 1.2 Tier: Pre-Launch Quality Gate (MANDATORY)
Purpose
Section titled “Purpose”No Tekton-built client site ships to the client until every item in this checklist is green. This SOP exists because broken tracking on a launched site is invisible — the client sees the site work, they never complain, and then three months later we realize we’ve lost 90 days of attribution data with no way to reconstruct it.
This gate catches tracking failures while they’re still cheap to fix.
When to Use:
- Before the “ready to ship” handoff to CSM for any new client site
- Before any major site rebuild or platform migration
- After adding a new form, lead magnet, or conversion point to an existing site
Owner: Website Specialist (runs the checks), SEO Specialist (signs off), CSM (does not ship until sign-off received) Timeline: 30 minutes to run through. Zero launches without this complete.
Status = GREEN or site does not ship.
A single YELLOW or RED item blocks launch. No exceptions for “we’ll fix it later” — tracking that isn’t working at launch rarely gets fixed after launch.
The 11-Item Gate
Section titled “The 11-Item Gate”Run through these in order. Stop and fix anything that isn’t green before moving on.
1. GSC verified
Section titled “1. GSC verified”- Site property appears in Google Search Console under
nick@tektongrowth.com - Property shows as Verified (not pending)
- Tekton service account (
seo-brain@core-depth-472801-t2.iam.gserviceaccount.com) is an Owner on the property
How to verify: GSC → pick property → Settings → Users and permissions. Service account email should be listed with Owner role.
2. Custom production sitemap built, compared, and submitted
Section titled “2. Custom production sitemap built, compared, and submitted”When a site is approved to launch and go live, the same launch pass that flips robots.txt, removes preview noindex, and removes X-Robots-Tag blocks must also build a fully custom production sitemap. Do not rely on old CMS sitemaps, exported WordPress/Yoast sitemap files, or the default Astro sitemap output as the final launch sitemap. Those often include stale CMS paths, wrong hosts, missing hierarchy, thin placeholder routes, or paths that are not actually going live.
- Build a custom sitemap from the approved pages going live, using the production canonical host.
- Include only indexable, canonical, 200-status pages that should rank. Exclude preview pages, parked/noindexed sections, form thank-you pages unless intentional, 404s, old CMS utility URLs, and duplicate host variants.
- Structure the sitemap so search engines understand the page hierarchy: homepage, core service hubs, child service pages, service-area pages, gallery/project pages, blog/resources, contact/conversion pages, and any other approved live sections.
- Use clean production URLs with trailing-slash/canonical behavior matching the live site.
- Compare the new custom sitemap against the old/source sitemap before launch. Every valuable old URL must either exist in the new sitemap/live site or have a mapped 301 redirect.
- Add any needed 301s before launch, then re-check that redirected old URLs land on the correct new canonical page.
- Verify live custom-domain sitemap XML, not only
*.pages.devor localdist. - Submit the final custom sitemap through Search Console API.
- Shows 0 warnings, 0 errors in GSC Sitemaps view.
- Submitted via
submit_to_gsc.py, not via GSC UI (leaves an audit trail).
Default sitemap URL: use https://<domain>/sitemap.xml when the site exposes the custom sitemap there. If the repo intentionally uses an index file, use https://<domain>/sitemap-index.xml, but the index must still point to the custom production sitemap set, not a blind default generator output.
How to verify submission:
python3 /Users/nick/Projects/scripts/submit_to_gsc.py <domain> --site-url https://<domain>/ --listOutput must show the submitted sitemap with 0/0 warnings/errors.
3. Cloudflare managed robots.txt and crawler permissions are checked
Section titled “3. Cloudflare managed robots.txt and crawler permissions are checked”This check is mandatory whenever a new site goes live, especially during the launch step where preview noindex, X-Robots-Tag, and robots blocks are removed. Do not rely only on the repo, Pages preview, or *.pages.dev robots file. Cloudflare can inject managed robots content at the active custom-domain zone after the deploy is clean.
- Confirm whether the production domain is managed by Cloudflare nameservers. Check both apex and
wwwif both resolve. - In the active Cloudflare zone, turn off Managed robots.txt / managed AI crawler blocking unless a client-specific approval says otherwise.
- Double-check crawler permissions for domains managed by Cloudflare nameservers before launch sign-off.
- After deploy, fetch the live custom-domain robots files, not just the Pages URL:
https://<domain>/robots.txthttps://www.<domain>/robots.txtwhenwwwis active
- Live robots allows normal crawl with
User-agent: *+Allow: /and includes the production sitemap. - Live robots does not contain Cloudflare Managed Content blocks for approved AI/search crawlers such as
GPTBot,ClaudeBot,CCBot,Google-Extended,Bytespider, or similar, unless Nick/client explicitly approved blocking them. - Live robots does not include unexpected
Content-Signalrestrictions that conflict with the launch policy.
How to verify:
curl -sL -H 'Cache-Control: no-cache' https://<domain>/robots.txtcurl -sL -H 'Cache-Control: no-cache' https://www.<domain>/robots.txtBlock launch if: the repo/Pages robots file is clean but the live custom domain shows Cloudflare managed crawler blocks. That means the active Cloudflare zone is injecting policy at the domain layer. Fix the Cloudflare setting first, then re-check the live custom-domain robots file.
4. GA4 property exists
Section titled “4. GA4 property exists”- Created under Tekton Growth account (
accounts/326886214) - Displays
<Client Name>with a Web data stream for the production URL - Measurement ID captured in site config (Astro:
site-config.json → tracking.ga4Id; static HTML: direct reference in tracking JS) - Entered into
clients.json → ga4PropertyIdandga4MeasurementId
5. gtag is firing on production
Section titled “5. gtag is firing on production”- Visit the live production URL in an incognito window
- Open DevTools → Network → filter
collect - Reload the page
- Confirm a POST to
https://www.google-analytics.com/g/collect?...&tid=G-XXXXXXXX&...&en=page_viewreturns 204
If nothing fires: the gtag script didn’t load (ad-blocker check first — disable and retry; if still dead, config is broken).
6. Attribution capture is installed
Section titled “6. Attribution capture is installed”- Open DevTools console on the live site
- Type
window.bctGetAttribution() - Should return
{utm_source, utm_medium, utm_campaign, ..., landing_page, referrer, submission_page}— may be empty strings on first visit, but the object must exist
If bctGetAttribution is undefined: the tracking JS file isn’t loaded on every page, or it’s loaded from the wrong path.
7. bctTrackLead helper is available
Section titled “7. bctTrackLead helper is available”- DevTools console on the live site
- Type
typeof window.bctTrackLead - Should return
"function"
If undefined: the tracking JS is missing the bctTrackLead helper. Copy it from the BCT reference.
8. Every form fires generate_lead on submit
Section titled “8. Every form fires generate_lead on submit”- Identify every form on the site (newsletter, contact, lead magnet, waitlist, tool submit)
- For each form, submit with a test email
- In GA4 Realtime, confirm a
generate_leadevent appears within 30 seconds - Check the event params include
form_name,source_channel, and any UTM values
If missing for any form: grep the repo for the form’s submit handler, verify it calls bctTrackLead('<form_name>') on the success branch. Redeploy.
9. Server-side MP is firing
Section titled “9. Server-side MP is firing”- For every API endpoint that creates a lead (typically
/functions/api/subscribe.js,/functions/api/contact.ts), confirm it hassendGa4Eventwired - CF Pages env vars
GA4_MEASUREMENT_ID+GA4_MP_SECRETare set on Production - Submit a test form while blocking trackers in the browser (use Privacy Badger or uBlock)
- GA4 Realtime should still show a
generate_leadevent withsource_channel=server
If no server event: env vars missing in CF Pages, OR the MP secret is invalid, OR the API endpoint doesn’t call sendGa4Event. Check CF Pages → Settings → Environment variables first.
10. generate_lead is a Key Event
Section titled “10. generate_lead is a Key Event”- GA4 Admin → Events
-
generate_leadrow shows the “Mark as key event” toggle ON (green)
If not toggled: flip it now. This is what makes the event count as a conversion in reports.
11. GSC ↔ GA4 Product Link
Section titled “11. GSC ↔ GA4 Product Link”- GA4 Admin → Product links → Search Console links
- Shows an active link to the GSC property for this site
- GA4 → Reports → Acquisition → Search Console traffic — section exists (data takes 24-48h to populate, but the report must exist)
If not linked: GA4 Admin → Product links → Search Console links → Link → pick the property. No API for this — must be done in UI.
Failure Escalation
Section titled “Failure Escalation”If you hit a blocker on any item and cannot resolve within 30 minutes, escalate to:
- Tracking stack issues (GSC, GA4, MP secret, CF Pages env vars): SEO Specialist, then Nick if unresolved
- Form handler code changes: Website Specialist (yourself) — fix, redeploy, rerun gate
- CF Pages access / env var issues: Nick directly (he owns the CF account)
Do not ship a site with any item in the YELLOW/RED state. If the client is pressuring for launch, launch the site WITHOUT announcing it, keep tracking fixes in progress, and inform CSM that the site is live but not client-facing yet.
Sign-Off
Section titled “Sign-Off”When all 11 items are green:
- Screenshot GA4 Realtime showing both
source_channel=clientANDsource_channel=serverforgenerate_leadafter a test submission - Screenshot GSC Sitemaps page showing “0 warnings, 0 errors”
- Post both to the client’s launch task in TaskTracker with the comment: “Launch tracking gate: GREEN. OK to ship.”
- CSM does not announce the site publicly until this comment is present
Version Control
Section titled “Version Control”- v1.1 (2026-05-30): Added mandatory Cloudflare Managed robots.txt / crawler-permission check for every new site launch during noindex removal and indexing cutover.
- v1.0 (2026-04-21): Initial SOP. 10-item pre-launch gate derived from the
/gsc-verifyskill post-onboarding checklist.