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_viewPageViewEvery page navigation
2view_itemViewContentViewing a show/experience detail
3add_to_cartAddToCartAdding an experience to the booking cart
4remove_from_cartRemoving an experience from the cart
5addons_updateAdding, removing, or changing addon quantity
6view_cartViewing the booking cart summary
7begin_checkoutInitiateCheckoutInitiateCheckoutGuest enters payment checkout
8purchasePurchaseServer-confirmed paid booking (payment-result page)
9add_payment_infoAddPaymentInfoAddPaymentInfoGuest submits payment details
10leadLeadLeadQualified inquiry submitted
11inquiry_startGuest opens an inquiry form
12form_abandonmentGuest leaves inquiry form without submitting
13form_errorValidation error on a form field
14payment_redirectRedirect to/from OnePay payment page
15payment_errorPayment redirect failed, timed out, or abandoned
16payment_cta_clickPay Now / Contact Support CTA clicked
17booking_stepBooking funnel step completed or abandoned
18book_now_clickBook Now CTA clicked (with source and event context)
19select_itemUser selects a show/experience from a list
20select_contentUser taps a content element
21external_linkUser taps an external link
22customer_support_widgetSupport widget interaction (open, close, phone, WhatsApp, chat)
23searchSearch query submitted with results
24search_refinementSearch query refined
25empty_searchSearch submitted with no results
26scroll_depthUser scrolls to a depth threshold
27timingPerformance timing measurement
28section_viewA marked page section becomes visible
29section_readA marked section viewed for at least 1 second
30session_startAnalytics session begins
31session_endAnalytics session ends
32utm_captureUTM parameters detected on landing
33$exceptionUncaught frontend error
34api_errorNetwork, timeout, server, or client API error
35404Page not found
36video_playShow page video starts playing
37video_completeShow page video finishes
38homepage_video_playHomepage hero video starts playing
39homepage_video_completeHomepage hero video finishes
40language_switchUser switches locale (en/vi)
41pdf_downloadUser downloads a PDF
42email_subscribeUser subscribes to email (footer, popup, or booking confirmation)
43mobile_keyboardMobile keyboard opens or closes (with viewport change)
44promo_appliedPromo code applied successfully
45promo_rejectedPromo code rejected (invalid or expired)
46promo_removedPromo 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 createdNew reservation persisted
2checkout startedGuest enters the payment checkout step
3payment completedPurchaseOnePay confirms a successful payment
4payment failedOnePay reports a payment failure
5reservation cancelledReservation status moves to cancelled
6refund processedRefund amount recorded against a payment
7inquiry submittedNew inquiry created from the public form
8operator check-in completedStaff 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.