Why This Matters

House of Legends needs one clear conversion story from ad click to paid booking. The landing website sends browser-safe events once; the backend forwards high-confidence events and server-confirmed paid booking outcomes onward. Operators verify outbound sends in each platform’s own event manager.

Platform Pages

PlatformPageStatus
PostHogPostHog AnalyticsActive — browser + server
MetaMeta Pixel + CAPIActive — Pixel + server CAPI
GTMGoogle Tag ManagerConfigured but not mounted

Architecture Overview

Browser events
├── PostHog        → page views, booking funnel, leads, exceptions, replay
├── Meta Pixel     → PageView, ViewContent, InitiateCheckout, Purchase, Lead
└── GTM dataLayer  → (dormant — not mounted)

Server events
├── PostHog node   → reservation created, payment completed/failed, inquiry submitted, check-in
└── Meta CAPI      → Purchase (server-confirmed), InitiateCheckout, AddPaymentInfo, Lead (forwarded)
  • The canonical landing analytics module lives at apps/landing/lib/analytics/analytics.ts. All browser events originate there.
  • Server events originate from apps/hono/src/services/analytics/posthog-analytics.service.ts.
  • Do not add separate landing analytics modules for individual destinations. New browser events should go through analytics.ts so all platforms stay aligned.

Event Inventory

Browser Events (46)

Every browser event fires to PostHog. Events marked with Meta also fire to Meta Pixel. Events marked with CAPI are additionally forwarded by the backend to Meta Conversions API.
  • Browser events originate from the landing analytics module.
  • Server events originate from the Hono analytics service.
#EventMetaCAPIWhen it fires
1page_viewPageView—Every page navigation
2view_itemViewContent—Viewing a show/experience detail
3add_to_cartAddToCart—Adding an experience to the booking cart
4remove_from_cart——Removing an experience from the cart
5addons_update——Adding, removing, or changing addon quantity
6view_cart——Viewing the booking cart summary
7begin_checkoutInitiateCheckoutInitiateCheckoutGuest enters payment checkout
8purchasePurchase—Server-confirmed paid booking (payment-result page)
9add_payment_infoAddPaymentInfoAddPaymentInfoGuest submits payment details
10leadLeadLeadQualified inquiry submitted
11inquiry_start——Guest opens an inquiry form
12form_abandonment——Guest leaves inquiry form without submitting
13form_error——Validation error on a form field
14payment_redirect——Redirect to/from OnePay payment page
15payment_error——Payment redirect failed, timed out, or abandoned
16payment_cta_click——Pay Now / Contact Support CTA clicked
17booking_step——Booking funnel step completed or abandoned
18book_now_click——Book Now CTA clicked (with source and event context)
19select_item——User selects a show/experience from a list
20select_content——User taps a content element
21external_link——User taps an external link
22customer_support_widget——Support widget interaction (open, close, phone, WhatsApp, chat)
23search——Search query submitted with results
24search_refinement——Search query refined
25empty_search——Search submitted with no results
26scroll_depth——User scrolls to a depth threshold
27timing——Performance timing measurement
28section_view——A marked page section becomes visible
29section_read——A marked section viewed for at least 1 second
30session_start——Analytics session begins
31session_end——Analytics session ends
32utm_capture——UTM parameters detected on landing
33$exception——Uncaught frontend error
34api_error——Network, timeout, server, or client API error
35404——Page not found
36video_play——Show page video starts playing
37video_complete——Show page video finishes
38homepage_video_play——Homepage hero video starts playing
39homepage_video_complete——Homepage hero video finishes
40language_switch——User switches locale (en/vi)
41pdf_download——User downloads a PDF
42email_subscribe——User subscribes to email (footer, popup, or booking confirmation)
43mobile_keyboard——Mobile keyboard opens or closes (with viewport change)
44promo_applied——Promo code applied successfully
45promo_rejected——Promo code rejected (invalid or expired)
46promo_removed——Promo code removed from booking

Server Events (8)

All server events fire to PostHog. The payment completed event is also sent to Meta CAPI as a server-confirmed Purchase.
#EventMeta CAPIWhen it fires
1reservation created—New reservation persisted
2checkout started—Guest enters the payment checkout step
3payment completedPurchaseOnePay confirms a successful payment
4payment failed—OnePay reports a payment failure
5reservation cancelled—Reservation status moves to cancelled
6refund processed—Refund amount recorded against a payment
7inquiry submitted—New inquiry created from the public form
8operator check-in completed—Staff checks a guest in through Mission Control

Platform Distribution

PlatformEvents receivedCount
PostHogAll browser + all server54
Meta PixelBrowser events marked Meta7
Meta CAPIServer Purchase + forwarded browser events4
GTM dataLayerAll browser (dormant)0 (not mounted)

PostHog Identity and Replay

Beyond events, PostHog also captures:
FeatureStatusDetails
Person identificationActiveCRM customer ID used as distinctId after early lead capture
Session replayActiveUnmasked form inputs and request/response payloads for booking recovery
AutocaptureDisabledManual event tracking only
Page leaveActiveCaptured automatically

North-Star Conversion Model

The tracking system answers three business questions:
  1. Who is interested?
  2. Who is seriously considering booking?
  3. Who actually becomes a paying customer?
LevelEventsPrimary use
Business outcomeServer-confirmed paid booking (Meta CAPI + PostHog payment completed)Revenue reporting and campaign optimization
Strong intentbegin_checkout, add_payment_info, payment initiated, qualified inquiryFunnel diagnosis and early campaign learning
Interestview_item, section_view, section_read, gallery/video/review engagementRetargeting, page decisions, creative insight
DiagnosticsScroll depth, timing, frontend exceptions, API errorsUX and reliability improvement
Do not optimize campaigns for low-value events just because they have more volume. Use them to understand the journey, then work toward backend-confirmed paid bookings as the clean conversion signal.

Section Reading Time

The landing website tracks how long guests spend reading each page section.
EventMeaning
section_viewA marked section became meaningfully visible on screen
section_readA marked section accumulated at least one second of visible time
Use section_read in PostHog to answer which show-page sections hold attention, where inquiry pages lose readers, and whether booking steps are being reviewed before checkout.
  • SectionReadTracker powers section engagement tracking.
  • Explicit data-analytics-section markers are preferred, but the tracker also discovers meaningful unmarked section elements inside main#main-content.
  • Shared marketing sections are marked through SectionWrapper.
  • Booking flow steps are marked through BookingSectionBlock.

Assisted Booking Feedback Loop

Some paid bookings start in Messenger, Instagram, WhatsApp, phone, or staff conversations. Those conversions are still marketing outcomes and should be recorded when staff confirms payment.
FieldWhy it matters
Reservation ID and referenceStable booking identity
Payment status and paid timestampProof the booking became revenue
Booking value and currencyRevenue optimization and reporting
Show, showEvent, date, guest countCampaign and operations analysis
Channel and campaign referenceAttribution for fanpage-assisted sales
Safe customer referenceCustomer-level analysis without raw PII
Do not forward raw email, phone number, customer name, or conversation text to ad platforms without explicit privacy approval.
All paid social links should include UTM parameters:
utm_source=facebook
utm_medium=paid-social
utm_campaign=<campaign-name>
utm_content=<creative-or-audience-name>

Successful Booking URLs

RoutePurposeFires Purchase?
/booking/payment-resultOnePay payment returnYes (only when payment is confirmed paid)
/booking/confirmationEmail receipt pageNo
  • The payment-result page gates the Purchase event with paymentStatus=PAID — only confirmed payments trigger the event.
  • The confirmation page has shouldTrackPurchase=false because it is a static receipt page linked from sent emails. It must stay live for those links to work.

Verification

Each platform has its own verification checklist:
Verification steps vary by platform but generally include:
  • Confirming events appear in each platform’s live event manager or debugger.
  • Checking that server-side events reach PostHog and Meta CAPI.
  • Validating UTM parameter passthrough from ad link to event payload.
  • Confirming session replay captures booking flow correctly.