← All stories

BRANCH · ef-029-multi-page-event-sites

Multiple Site Pages — Guest Navigation

EF-029 Persona: Public guest (no auth) Stage: Public Roots in: public-event-page

A public event site can have a primary page plus about, schedule, travel, sponsor, or FAQ pages. The guest needs navigation that deep-links, refreshes safely, preserves canonical URLs, and keeps metadata page-specific without leaking unpublished or deleted pages.

Preconditions

Inherits public-event-page in the page-resolves state. Organizer-side page builder, templates, and page publishing controls are out of scope here; this branch covers guest navigation across published pages.

Happy path

  1. Guest opens /p/:slug.

    The primary page renders and a visible site nav lists the published pages for this event only.

  2. Guest navigates to About and Schedule.

    URLs become /p/:slug/about and /p/:slug/schedule. Refreshing either deep link renders the same page without relying on SPA memory.

  3. Guest shares a secondary page.

    Canonical URL and Open Graph tags match the specific page, while event identity remains consistent.

Failure modes

Capacity full mid-fill

Trigger: guest starts registration from a secondary page and capacity fills before submit.

The flow shows the same waitlist handoff on the secondary page and preserves return navigation back to that page after resolution.

Two-tab idempotency

Trigger: guest opens Register from two different event pages and submits both.

Server dedupes one registration for the event. Both pages show the existing registration state without page-specific duplicates.

Network drop during submit

Trigger: registration from About or Schedule loses the response.

Retry uses the same Idempotency-Key and keeps the originating page slug in the return URL without double-booking.

Invalid input rejected without info leak

Trigger: guessed event slug, fake token, or fake page slug.

The response does not reveal whether the event exists with no such page, whether the page is unpublished, or whether the token was malformed.

Source page archived, draft, or deleted

Trigger: secondary page is open when the event is archived, moved to draft, or deleted.

Refresh and navigation both return a generic unavailable/not-found state with no lifecycle distinction.

Browser back after success

Trigger: guest registers from Schedule, sees success, then presses back.

The browser returns to Schedule with an already-registered view. It does not resubmit and does not route to the primary page accidentally.

Open Graph tags present per page

Trigger: About or Schedule URL is shared.

Each page has its own og:title, og:description, and canonical og:url, while og:image uses the event hero unless the page overrides it.

Bot-fill rate-limited

Trigger: repeated registration submits from secondary pages.

429 or captcha appears in the registration surface and does not break page navigation. The nav stays visible so the guest can keep browsing.

Secondary page slug missing

Trigger: guest visits /p/:slug/speakers when no speakers page exists.

The page shows a generic not-found for that event site, not a full app crash or a redirect that hides the failed deep link.

Unpublished page in nav cache

Trigger: a page was removed from publication after the guest loaded nav.

Clicking the stale nav item returns the same generic unavailable state as a missing page and does not expose unpublished content.

Canonical URL consistency

Trigger: guest opens trailing slash, mixed case, or query-param variants.

The page resolves to one canonical URL per page and metadata uses that canonical value consistently.

Mobile nav overflow

Trigger: event has seven published pages on a 375px viewport.

Navigation wraps or scrolls accessibly without hiding links behind hover-only UI. The active page is still perceivable without color alone.

Stable test attributes

Visibility teeth. Each attribute must be visible for the active event-page route or route state.

data-testWherePurpose
event-site-navPublic event siteNavigation across published pages
event-site-nav-itemInside navOne published page link
event-site-nav-activeInside navCurrent page indicator
event-site-pagePage bodyRoot for current published page
event-site-page-titleInside page bodyCurrent page heading
event-site-page-aboutAbout routeAbout page body
event-site-page-scheduleSchedule routeSchedule page body
event-site-page-not-foundMissing page routeGeneric missing page state
event-site-unavailableArchived/draft/deleted routeGeneric unavailable state
event-site-canonical-linkDocument headCanonical URL for current page
event-site-og-titleDocument headPage-specific OG title
event-site-og-descriptionDocument headPage-specific OG description
event-site-og-imageDocument headEvent hero or page override image
event-site-og-urlDocument headCanonical OG URL for current page
event-site-registration-returnRegistration success stateReturn-to-page link after registration
event-site-rate-limitRegistration 429 stateRetry-after or captcha message

Agent test plan

Navigate primary, about, schedule, missing, unpublished, canonicalized, and mobile-overflow fixtures. Registration probes verify that inherited public registration behavior keeps page slug context.