Deploying the 12 landing pages
Single-source step-by-step. Each page in this folder is a self-contained, branded landing page with a multi-step wizard form and a built-in webhook submit handler. They're ready to go live the moment you (a) point them at a webhook URL and (b) host them on any static host.
§0 What's already wired up
Every page now ships with a window.lpSendLead(leadData) helper that runs on form submit. The helper:
- POSTs the lead JSON to a configurable webhook URL
- Fires the Meta
Leadpixel event (if the pixel base code is loaded) - Falls back to console-only if no webhook is configured (safe — won't break in preview)
The payload includes every form field plus lp_id, lp_brand, lp_campaign, ghl_tag, and all UTM/fbclid params captured from the URL.
Step 1 Get a GHL Inbound Webhook URL
In your GHL sub-account (UBI Equity Group, location JEJMusjVFadrt6NphRre):
- Automation → Workflows → + Create Workflow
- Choose Start from Scratch
- Add trigger: Inbound Webhook (Webhook trigger)
- GHL displays a webhook URL like
https://services.leadconnectorhq.com/hooks/<location>/.... Copy it. - Add Action: Create / Update Contact — map JSON fields to contact fields:
firstName←firstName/first_name/first-name(your form sends these — check the LP-META in each file for exact field names)lastName←lastNameemail←emailphone←phone- Custom field
Brand←lp_brand
- Add Action: Add Tag → tag =
{{inboundWebhookRequest.ghl_tag}}(this gives youlp:equity-prequal,lp:group-quote, etc. per page — feeds your existing Brand Router workflows) - Add Action: Send Internal Notification (optional) — Slack/email yourself when a lead lands
- Save and Publish the workflow.
ghl_tag field.
Step 2 Configure the webhook on each page
Three ways. Pick one.
Option A — Meta tag per page (simplest)
Open each HTML file and add ONE line to the <head>:
<meta name="ghl-webhook" content="https://services.leadconnectorhq.com/hooks/JEJMusjVFadrt6NphRre/YOUR-WEBHOOK-ID-HERE">
Same URL across all 12 pages if you used one workflow in Step 1. Different URLs per page if you created 12 workflows.
Option B — Global JS variable (set in your hosting platform)
If your host supports env vars or build-time injection, set:
<script>window.GHL_WEBHOOK_URL = "https://services.leadconnectorhq.com/hooks/..."</script>
Inject this above the closing </head> via your platform (e.g., Cloudflare Pages Build/Env, Netlify build snippet).
Option C — Find and replace (sed/script, do all 12 at once)
WEBHOOK="https://services.leadconnectorhq.com/hooks/JEJMusjVFadrt6NphRre/YOUR-WEBHOOK-ID"
for f in /Users/rolandomoreno/software/socialmedia/landing-pages/*/*.html; do
# Insert meta tag right after <head> (idempotent: skip if already present)
grep -q 'name="ghl-webhook"' "$f" && continue
sed -i '' "s|<head>|<head>\n <meta name=\"ghl-webhook\" content=\"$WEBHOOK\">|" "$f"
done
(macOS uses sed -i ''; Linux uses sed -i.)
Step 3 Test locally
cd /Users/rolandomoreno/software/socialmedia/landing-pages
python3 -m http.server 8080
# then open http://localhost:8080 in a browser
Visit each page, fill the form, submit.
- No webhook configured: you'll see the payload in the browser console (open DevTools)
- Webhook configured: the lead arrives in GHL within seconds
Step 4 Deploy
Pick a static host. None of these require a backend; all serve plain HTML.
Cloudflare Pages — free + fast SSL + per-domain routing
cd /Users/rolandomoreno/software/socialmedia/landing-pages
npx wrangler pages deploy . --project-name=ubi-landing-pages
Then attach the 4 brand subdomains via Cloudflare DNS:
prequal.ubiequitygroup.com→<your-pages>.pages.dev/ubi-equity/prequal.html- (etc. per the matrix in strategy brief §4.1)
Use Cloudflare Page Rules or _routes.json to map clean URLs (e.g., serve /quote from /ubi-group/quote.html).
Netlify
cd /Users/rolandomoreno/software/socialmedia/landing-pages
npx netlify deploy --dir=. --prod
Same subdomain attachment pattern.
GitHub Pages
Push this folder to a public/private repo, enable Pages from the repo's Settings. Custom domains via CNAME as documented.
Your own server / GHL Sites (one-step manual)
Each .html is self-contained. Copy individual files anywhere — no build step, no dependencies (Google Fonts are CDN-fetched at runtime).
Step 5 Add Meta Pixel + CAPI (per brand)
Each page already calls fbq('track', 'Lead', ...) on submit if the pixel base code is loaded. Add the pixel base code in the head (per strategy brief §3.2):
<!-- Meta Pixel base -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;
s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
</script>
Lead events against client-side).
Ref Per-page reference
| Page | File | Form fields summary | UTM campaign default | GHL tag |
|---|---|---|---|---|
| L1 Equity Pre-Qual | ubi-equity/prequal.html | Home price → county → credit → income → realtor Y/N → name/email/phone + SMS consent | equity-prequal-fl | lp:equity-prequal |
| L2 Equity FHA vs Conv | ubi-equity/compare.html | Credit → home price → down payment → location → income → contact | equity-fha-vs-conv | lp:equity-compare |
| L3 Equity Refi | ubi-equity/refi.html | Rate → balance → home value → credit → cash-out goal → contact | equity-refi-breakeven | lp:equity-refi |
| L4 Group Quote | ubi-group/quote.html | Capital tier → property type → state → purpose → as-is → close date → name/company → contact | group-bridge-quote | lp:group-quote |
| L5 Group Value-Add MF | ubi-group/valueadd.html | As-is → units → market → reno budget → ARV → DSCR → contact | group-valueadd-mf | lp:group-valueadd |
| L6 Group CRE Refi | ubi-group/refi.html | Balance → payment → property type → value → NOI/DSCR → market → purpose → contact | group-cre-refi | lp:group-refi |
| L7 Hipoteca ITIN | hipoteca-latina/itin.html | SSN/ITIN → years → ingreso → precio → ciudad → contacto | hipoteca-itin-check | lp:hipoteca-itin |
| L8 Hipoteca FHA calc | hipoteca-latina/calculadora.html | Ingreso → deudas → crédito → enganche → ciudad → contacto | hipoteca-fha-calc | lp:hipoteca-calc |
| L9 Hipoteca Crédito | hipoteca-latina/credito.html | Crédito → tiempo → ingreso → deudas → cobranzas → contacto | hipoteca-credito-6mo | lp:hipoteca-credito |
| L10 305 Run My Numbers | numbers-guy/runmynumbers.html | Purchase price → type → rent → address → loan needed → IG/contact | 305-run-my-numbers | lp:305-runmynumbers |
| L11 305 Value | numbers-guy/value.html | Units → address → rent → year built → reno → owe → owner-occupied → contact | 305-mf-valuation | lp:305-value |
| L12 305 Mixed-Use | numbers-guy/mixeduse.html | Occupy 51%? → biz type → price → years → revenue → credit → contact | 305-mixed-use-qual | lp:305-mixeduse |
UTM Per-page URL pattern (DSCR-style)
Match the DSCR-style URL pattern from your prior campaigns:
https://prequal.ubiequitygroup.com/?utm_source=facebook&utm_medium=Instagram_Feed&utm_campaign=equity-prequal-fl&utm_content={{ad.id}}&utm_term={{adset.id}}&utm_id={{campaign.id}}
fbclid is auto-appended by Meta and auto-captured by the page's UTM helper.
QA Verification checklist (per page after deploy)
Click each item to mark it complete. State is local to this browser session.
- Page loads at the configured domain with valid SSL
- Mobile renders correctly (375px and 414px width)
- Form submits and shows the success state
- Network panel shows a POST to your GHL webhook URL with the lead JSON
- Contact appears in GHL Contacts within 10 seconds with
lp:<brand>-<page>tag - Meta Pixel
Leadevent fires (verify with Meta Pixel Helper extension) - UTM params from URL appear in the contact record (custom fields if mapped)
- SMS consent checkbox is present, required, and language matches state law
§ What changed in this patch session
Each of the 12 HTML files now contains:
<head>injection —window.lpSendLead(leadData)helper that POSTs to a configurable webhook URL.- Submit handler swap — the previous
console.log(...)debug-only handler is replaced withwindow.lpSendLead && window.lpSendLead(<data>).