HL
HL Dynamic Content System Documentation Portal
Version 31.0 Confidential
Proprietary Software

HL Dynamic Content System

Scalable location-based landing pages powered by intelligent data synchronization

๐ŸŽฏ

What is it?

The HL Dynamic Content System is a proprietary marketing technology solution that enables the creation and management of unlimited location-specific landing pages from a single template. Instead of building hundreds of individual pages, you manage one smart page that dynamically renders content based on URL parameters.

โšก

How it works

The system connects GoHighLevel landing pages with Google Sheets data. When a visitor lands on yourpage.com?id=miami, the engine fetches Miami's data from your spreadsheet and instantly renders all location-specific contentโ€”text, images, phone numbers, maps, and tracking codes.

๐Ÿ”ง

Key Components

  • HL Engine: JavaScript that powers dynamic rendering
  • Data Spreadsheet: Central source of truth for all locations
  • Admin Tools: Scripts for image sync and reviews management
  • Tracking Integration: Per-location GTM, GA4, and Hotjar injection
โœจ

Key Features

  • Dynamic text, images, and background replacement
  • Automatic Google Maps directions links
  • Click-to-call phone number handling
  • Google Reviews auto-fetch (4-5 stars only)
  • Image sync from Google Drive with fallbacks
  • SEO meta tags with dynamic suffixes
  • Per-location tracking code injection

Version History

December 2025

Documentation Release

Complete documentation portal with Admin Guide, Production User Guide, ADS Specialist Guide, and Legal Terms. Full code commenting and system architecture documentation.

v31.0
December 2025

Production Deploy

System deployment with full feature set including dynamic meta titles, Google Reviews integration, image synchronization with fallbacks, and comprehensive tracking support.

v30.x
December 2025

Development Phase

Core engine development including CSV parsing, dynamic content rendering, Google Drive image handling, directions URL generation, phone clickability, and FAQ support with MutationObserver.

v1.0 - v29.x

Get Started

Select a guide from the navigation above based on your role:

Admin & Developer Guide

Technical documentation for system administrators and developers. Covers architecture, configuration, and code modification.

System Overview

The HL Dynamic Content System enables location-specific landing pages on GoHighLevel (GHL) by dynamically replacing content based on URL parameters and spreadsheet data.

Key Components

Component Purpose Location
HL Engine JavaScript that renders dynamic content GHL Page Header Code
Spreadsheet Data source for all locations Google Sheets
Spreadsheet Tools Admin scripts for data management Google Apps Script

Data Flow

URL (?id=miami) โ†’ HL Engine โ†’ Google Sheets โ†’ Page Render

1. User visits landing page with ?id=location_id
2. Engine fetches spreadsheet data via CSV export
3. Engine finds matching row by ID
4. Engine replaces all .hl-* elements with data
5. Tracking tags (GTM/GA4/Hotjar) are injected

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    GOOGLE SHEETS                             โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  Data Sheet (e.g., UrgentCare)                      โ”‚    โ”‚
โ”‚  โ”‚  - Location data (clinic_name, address, phone...)   โ”‚    โ”‚
โ”‚  โ”‚  - Tracking IDs (gtmid, hotjar_id, ga4_id)         โ”‚    โ”‚
โ”‚  โ”‚  - Images (logo_url, picture, image_1...)          โ”‚    โ”‚
โ”‚  โ”‚  - Google Reviews (auto-populated)                  โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                           โ”‚                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚ Config Sheet  โ”‚   โ”‚ Google Apps Script              โ”‚    โ”‚
โ”‚  โ”‚ - Folder ID   โ”‚   โ”‚ - Image Sync from Drive         โ”‚    โ”‚
โ”‚  โ”‚ - Sheet names โ”‚   โ”‚ - Google Reviews Fetch          โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ”‚ CSV Export (auto)
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    GOHIGHLEVEL PAGE                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  Header Code: HL Engine v31.0                       โ”‚    โ”‚
โ”‚  โ”‚  - Fetches spreadsheet via ?id= parameter           โ”‚    โ”‚
โ”‚  โ”‚  - Replaces .hl-* elements                          โ”‚    โ”‚
โ”‚  โ”‚  - Injects tracking scripts                         โ”‚    โ”‚
โ”‚  โ”‚  - Handles images, links, phones                    โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ”‚ ?id=location_id
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    AD PLATFORMS                              โ”‚
โ”‚  Google Ads / Facebook Ads / etc.                           โ”‚
โ”‚  Each ad points to: page.com?id=location_id                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Setup & Configuration

Initial Setup Checklist

  • Create Google Spreadsheet with required columns
  • Add spreadsheet tools script to Apps Script
  • Configure API key for Google Reviews
  • Set up Google Drive folder for images
  • Install HL Engine on GHL page
  • Test with sample location

Google Spreadsheet Setup

  1. Create new Google Spreadsheet
  2. Name first sheet (tab) according to your project
  3. Add all required columns (see Spreadsheet Structure)
  4. Make spreadsheet publicly viewable: Share โ†’ Anyone with the link โ†’ Viewer

Google Apps Script Setup

  1. Open spreadsheet
  2. Extensions โ†’ Apps Script
  3. Delete default code
  4. Paste entire hl-spreadsheet-tools.gs content
  5. Save (Ctrl+S)
  6. Refresh spreadsheet
  7. Run "Setup Config Sheet" from Admin Tools menu
  8. Configure API key in script (line 24)

GHL Page Setup

  1. Open page in GHL editor
  2. Settings โ†’ Tracking Code
  3. Paste entire hl-engine-v31.0.js in Header Code
  4. Edit CONFIG section (lines 35-55):
    • sheetID: Your spreadsheet ID
    • sheetName: Your sheet/tab name
  5. Save and publish

Spreadsheet Structure

Required Columns

Column Purpose Example
idUnique location identifiermiami
clinic_nameBusiness nameFastMed Urgent Care
street_addressStreet address123 Main St
city_stateCity and stateMiami, FL
zipZIP code33101

Tracking Columns

ColumnPurposeFormat
gtmidGoogle Tag ManagerGTM-XXXXXXX
hotjar_idHotjar1234567 (numeric)
ga4_idGoogle Analytics 4G-XXXXXXXXXX

Formula Columns

map_url (builds from address):

="https://www.google.com/maps/search/?api=1&query=" & ENCODEURL(E2 & " " & F2 & " " & G2 & " " & H2)

booking_phone (formats raw phone):

=REGEXREPLACE(TO_TEXT(J2), "(\d{3})(\d{3})(\d{4})", "($1) $2-$3")

Engine Configuration

CONFIG Object

const CONFIG = {
  sheetID: '1Yi-0B4lggjOz_vL0kSXv7-WFlwEddATSU_-B-5y2ffE',
  sheetName: 'UrgentCare',
  urlParam: 'id',
  retries: [0, 350, 900]
};
PropertyDescriptionDefault
sheetIDGoogle Spreadsheet IDRequired
sheetNameSheet/tab nameRequired
urlParamURL parameter for IDid
retriesRender timing (ms)[0, 350, 900]
๐Ÿ’ก
Getting Spreadsheet ID

From URL: https://docs.google.com/spreadsheets/d/1Yi-0B4lggjOz.../edit
The ID is between /d/ and /edit.

CSS Class Reference

Text Replacement

Class PatternUsageExample
.hl-{column}Replace text content.hl-clinic_name
<div class="hl-clinic_name">Placeholder</div>

<!-- Inline Span (in rich text) -->
Visit us at <span class="hl-city_state">City, ST</span> today!

Images

Class PatternUsage
.hl-img-{column}Replace img src
.hl-bg-{column}Replace background-image

Links & Phones

ClassUsage
.hl-booking-phonePhone with tel: link
.hl-directions-linkAuto directions link
.hl-map-embedEmbeds Google Map

Google Apps Script Tools

Admin Menu

โšก Admin Tools
โ”œโ”€โ”€ ๐Ÿ–ผ๏ธ Images
โ”‚   โ”œโ”€โ”€ Sync Drive Images (w/ Fallback)
โ”‚   โ””โ”€โ”€ Setup Config Sheet
โ”œโ”€โ”€ โญ Reviews
โ”‚   โ”œโ”€โ”€ Fetch Google Reviews
โ”‚   โ””โ”€โ”€ Clear All Reviews
โ””โ”€โ”€ ๐Ÿ“– Help & Documentation

Image Sync

File Naming Convention:

  • {id}_{column}.{ext} โ†’ Specific image
  • 0_{column}.{ext} โ†’ Fallback image

Examples:

  • miami_logo_url.png โ†’ Row where id="miami", column "logo_url"
  • 0_picture.jpg โ†’ All empty "picture" cells

Troubleshooting

IssueCauseSolution
Content not replacingClass name mismatchCheck column name matches class
Images not loadingDrive permissionsMake file/folder public
Phone not clickableWrong class patternUse .hl-booking-phone
Reviews not fetchingAPI key invalidCheck API key, enable Places API

Console Warnings

WarningMeaning
[HL Engine] ID not foundURL param doesn't match any spreadsheet row
[HL Engine] Error:Network or parsing error

Production User Guide

Operations guide for managing locations, images, and content. No coding required.

Introduction

What is this system?

The HL Dynamic Content System allows you to manage multiple location-specific landing pages from a single Google Spreadsheet. Instead of creating separate pages for each location, you manage one page template and one spreadsheet with all location data.

Key Benefits

  • Single Source of Truth: All location data in one spreadsheet
  • Instant Updates: Change spreadsheet โ†’ Page updates automatically
  • No Coding Required: Just edit cells in the spreadsheet
  • Automatic Reviews: Google Reviews fetched automatically
  • Image Management: Upload images to Drive, system syncs them

How It Works

You edit spreadsheet โ†’ System reads data โ†’ Landing page shows location info

When someone visits yourpage.com?id=miami, the system looks up "miami" in your spreadsheet, finds all the data for that location, and shows it on the page.

Daily Operations

Admin Tools Menu

After opening the spreadsheet, you'll see โšก Admin Tools in the menu bar:

โšก Admin Tools
โ”œโ”€โ”€ ๐Ÿ–ผ๏ธ Images
โ”‚   โ”œโ”€โ”€ Sync Drive Images (w/ Fallback)
โ”‚   โ””โ”€โ”€ Setup Config Sheet
โ”œโ”€โ”€ โญ Reviews
โ”‚   โ”œโ”€โ”€ Fetch Google Reviews
โ”‚   โ””โ”€โ”€ Clear All Reviews
โ””โ”€โ”€ ๐Ÿ“– Help & Documentation

Checking a Location

  1. Find the location row by ID
  2. Copy the ID value (e.g., "miami")
  3. Open the landing page with ?id=miami at the end
  4. Verify all information displays correctly

Adding New Locations

Step-by-Step Process

Step 1: Add Row to Spreadsheet

  1. Go to the last row with data
  2. Add a new row below
  3. Fill in the id column first (e.g., "newcity")

Step 2: Fill Required Fields

FieldWhat to EnterExample
idUnique identifier (lowercase, no spaces)sandiego
clinic_nameFull business nameFastMed Urgent Care
street_addressStreet address only456 Oak Avenue
city_stateCity, State formatSan Diego, CA
zipZIP code92101
RAW PhonePhone number (digits only)6195551234

Step 3: Test the Page

  • Open landing page with ?id=newlocation
  • Check all fields display correctly
  • Test phone links (click to call)
  • Test directions link
  • Verify images load

Managing Images

Image Columns

ColumnPurposeRecommended Size
logo_urlCompany logo200x200px
pictureMain hero image1200x630px
image_1 to image_10Gallery images800x600px

Method 1: Direct Links

  1. Upload image to Google Drive
  2. Right-click โ†’ Share โ†’ Anyone with link
  3. Copy link
  4. Paste in spreadsheet column

Method 2: Image Sync (Recommended)

  1. Upload image to the Drive folder
  2. Name it: {id}_{column}.png (e.g., miami_logo_url.png)
  3. Run Admin Tools โ†’ Images โ†’ Sync Drive Images
๐Ÿ’ก
Fallback Images

Name with 0_ prefix (e.g., 0_logo_url.png) to set a default for all locations missing that image.

Google Reviews

Automatic Fetch

  1. Go to Admin Tools โ†’ Reviews โ†’ Fetch Google Reviews
  2. Wait for process to complete (may take several minutes)
  3. Check the completion message for results

What Gets Fetched

  • Only 4-5 star reviews
  • Top 3 most recent reviews per location
  • Review text and author name

When to Run

  • After adding new locations
  • Monthly refresh recommended
  • After clearing reviews

Quality Assurance

Pre-Launch Checklist

  • ID is unique (no duplicates)
  • All required fields filled
  • Phone number formats correctly
  • Map link works
  • Images load
  • Reviews display (if available)
  • Page title shows correctly
  • Tracking IDs are correct

Testing a Page

  1. Open: yourpage.com?id={location_id}
  2. Check header/logo
  3. Check all text content
  4. Click phone number (should open dialer)
  5. Click directions (should open Maps)
  6. Check images loaded
  7. Check page title in browser tab
  8. Test on mobile device

FAQ

How long until changes appear?

Changes are instant. The page fetches fresh data on each load. You may need to clear browser cache or use incognito mode to see changes immediately.

Can I add custom columns?

Yes! Add any column to the spreadsheet. Then have the dev team add the matching .hl-{column} class to the GHL page.

What if I break something?

Spreadsheet changes can be undone: File โ†’ Version history โ†’ See version history, find a working version and restore.

Why isn't my image showing?

  1. Is the file shared publicly?
  2. Is the filename correct for sync?
  3. Try a direct Drive link instead

ADS Specialist Guide

Campaign setup guide for Google Ads, Facebook Ads, and tracking implementation.

Quick Start

The Core Concept

One landing page serves ALL locations. You just change the URL parameter.

Base URL:
https://yoursite.com/landing-page

Location-Specific URLs:
https://yoursite.com/landing-page?id=miami
https://yoursite.com/landing-page?id=dallas
https://yoursite.com/landing-page?id=sandiego

The ?id= parameter tells the page which location data to display.

What You Need

  1. The base landing page URL
  2. The list of location IDs (from spreadsheet)
  3. Your campaign tracking parameters

Building Campaign URLs

Basic Formula

{base_url}?id={location_id}&{utm_parameters}

Example URLs

Google Ads:

https://yoursite.com/urgent-care?id=miami&utm_source=google&utm_medium=cpc&utm_campaign=urgent_care_miami

Facebook Ads:

https://yoursite.com/urgent-care?id=miami&utm_source=facebook&utm_medium=paid_social&utm_campaign=urgent_care_miami
โš ๏ธ
Important: Case Sensitivity

Location IDs are lowercase. ?id=miami works, ?id=Miami does not.

Google Ads Setup

Campaign Structure

Campaign: Urgent Care - Miami
โ””โ”€โ”€ Ad Group: Urgent Care Near Me
    โ””โ”€โ”€ Ad: [Headlines + Descriptions]
        โ””โ”€โ”€ Final URL: https://site.com/page?id=miami

Setting Up Final URLs

Option 1: Per Ad Group (Recommended)

  1. Create ad groups per location
  2. Set Final URL at ad group level: https://yoursite.com/urgent-care?id=miami
  3. UTM parameters added via tracking template

Tracking Template

Set at campaign or account level:

{lpurl}&utm_source=google&utm_medium=cpc&utm_campaign={_campaign}&utm_content={creative}

Facebook/Meta Ads Setup

Campaign Structure

Campaign: Urgent Care Awareness
โ””โ”€โ”€ Ad Set: Miami (Geo-targeted)
    โ””โ”€โ”€ Ad: [Creative + Copy]
        โ””โ”€โ”€ Website URL: https://site.com/page?id=miami

URL Parameters in Ads Manager

Website URL:

https://yoursite.com/urgent-care?id=miami

URL Parameters Field:

utm_source=facebook&utm_medium=paid_social&utm_campaign={{campaign.name}}

Dynamic Parameters

ParameterInserts
{{campaign.name}}Campaign name
{{adset.name}}Ad set name
{{ad.name}}Ad name
{{campaign.id}}Campaign ID
๐ŸŽฏ
Geo-Targeting Alignment

Match your geo-targeting to the location ID! Miami geo-targeting should use ?id=miami.

Tracking & Attribution

What's Automatically Tracked

The system injects these tracking scripts per location:

  • Google Tag Manager (GTM)
  • Google Analytics 4 (GA4)
  • Hotjar

Set per location in spreadsheet columns.

UTM Parameters

ParameterPurposeExample
utm_sourceTraffic sourcegoogle, facebook, bing
utm_mediumMarketing mediumcpc, paid_social, email
utm_campaignCampaign nameurgent_care_miami
utm_contentAd identifierad_variant_a
utm_termKeyword (search)urgent care near me

Best Practices

Campaign Organization

Do:

  • Create separate ad groups/ad sets per location
  • Use consistent naming conventions
  • Match geo-targeting to location data

Don't:

  • Mix multiple locations in one ad group
  • Use generic geo-targeting for location-specific ads
  • Forget the ?id= parameter

Common Mistakes

MistakeCorrect
?ID=miami?id=miami (lowercase)
?id=Miami?id=miami (lowercase)
?id=miami fl?id=miami (no spaces)
/page/miami/page?id=miami (use parameter)

Quick Reference

URL Formula

{base_url}?id={location_id}&utm_source={source}&utm_medium={medium}&utm_campaign={campaign}

Platform UTM Defaults

Platformutm_sourceutm_medium
Google Adsgooglecpc
Facebookfacebookpaid_social
Bingbingcpc
LinkedInlinkedinpaid_social

Testing Checklist

  • URL includes ?id= parameter
  • ID matches spreadsheet exactly (lowercase)
  • Page shows correct location name
  • Page shows correct phone number
  • Phone link works (tap on mobile)
  • Directions link opens Maps
  • UTM parameters in URL
  • GTM/GA4 tracking fires