Architecture
Technical architecture and application structure of the Storefront.
Technology stack
| Component | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| Language | TypeScript 5.4.5 |
| Styling | Tailwind CSS 4.0 + Radix UI + shadcn/ui |
| Data fetching | Apollo Client 3.7 + graphql-request 6.1 |
| State management | React Context + XState 4.38 |
| Client storage | Dexie 4.0 (IndexedDB) |
| Forms | React Hook Form 7.48 + Zod 3.25 |
| Internationalisation | i18next 22.5 + react-i18next 12.3 |
| Animation | Framer Motion 11.18 |
| Monitoring | Datadog RUM + APM |
| Deployment | SST (AWS Lambda + CloudFront) |
| Runtime | Node.js 22.x |
Application structure
experience-marketing-platform/
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── page.tsx # Root home page
│ │ ├── [locale]/ # Locale-specific routes
│ │ │ └── booking/[id]/ # Booking detail with locale
│ │ └── booking/[id]/ # Booking detail page
│ ├── features/ # Major feature modules
│ │ ├── AvailabilityPicker/ # Date and availability selection
│ │ ├── ProductAvailability/ # Product detail + availability
│ │ ├── ProductList/ # Product browsing grid/list
│ │ ├── ProductGallery/ # Image gallery and carousel
│ │ ├── ProductDiscoverySearch/ # Search interface
│ │ ├── DestinationSearch/ # Destination picker
│ │ ├── BookingCheckout/ # Checkout flow
│ │ ├── BookingManage/ # Manage existing bookings
│ │ ├── Menu/ # Navigation menu
│ │ ├── Stack/ # Modal navigation stack
│ │ ├── StoryList/ # Story/itinerary list
│ │ ├── Itinerary/ # Trip itinerary
│ │ ├── BottomModal/ # Bottom sheet modal
│ │ └── Analytics/ # Event tracking
│ ├── components/ # Shared components
│ │ ├── ui/ # shadcn/ui base components
│ │ ├── ProductDetails/ # Product detail sections
│ │ ├── Page/ # Page layout
│ │ ├── Header.tsx # Navigation header
│ │ ├── Footer.tsx # Page footer
│ │ └── PageLayout.tsx # Main layout wrapper
│ ├── contexts/ # React Context providers
│ ├── graphql/ # Queries, mutations, fragments
│ ├── hooks/ # Custom React hooks
│ ├── middleware/ # Next.js middleware
│ ├── storage/ # IndexedDB (Dexie) layer
│ ├── helper/ # Utility functions
│ ├── config/ # Configuration
│ ├── constants/ # App constants
│ ├── datadog/ # Monitoring setup
│ └── types/ # TypeScript types
├── locales/ # i18n translation files
│ ├── en/, es/, fr/, de/
│ ├── it/, nl/, pt/, ar/
├── public/ # Static assets
├── sst.config.ts # AWS infrastructure
├── next.config.mjs # Next.js configuration
├── vitest.config.mts # Test configuration
└── tailwind.config.ts # Styling configuration
Provider stack
The application uses a deep provider composition for cross-cutting concerns:
ApolloProvider (GraphQL client)
└── GraphqlSdkProvider (typed SDK)
└── StorageProvider (IndexedDB)
└── ThemeProvider (brand colours + dark mode)
└── ViewerProvider (brand + distribution channel)
└── CurrencyProvider (selected currency)
└── LanguageProvider (i18next + locale)
└── ConsumerTripProvider (trip context)
└── BookingProvider (cart + booking state)
└── ProductProvider (gallery, availability, sharing)
└── AnalyticsEventProvider (event tracking)
└── StackProvider (modal navigation)
└── MenuProvider (navigation menu)
└── BottomModalProvider
└── TooltipProvider
Middleware
The Next.js middleware handles request processing before pages are rendered. The middleware pipeline:
- State decoding — Decode the
?s=URL parameter containing encoded state. - Viewer data fetch — Load distribution channel and brand information via GraphQL.
- Consumer trip resolution — Identify the consumer trip from URL, state, or cookies.
- Language resolution — Determine language from cookie, header, or distribution channel default.
- Currency resolution — Determine currency from cookie, trip, or distribution channel default.
- Redirects — Handle localisation redirects, consumer trip cookie setup, and frame navigation.
- Response enrichment — Set cookies and headers on the response.
Data layer
GraphQL queries
Key queries include:
| Query | Purpose |
|---|---|
| Viewer | Brand, distribution channel, languages, currencies |
| ConsumerTrip | Trip data, dates, recommendations |
| Product | Product details, pricing, availability |
| ProductList | Product catalogue browsing |
| Availability | Specific availability slots |
| BookingAvailability | Availability for items in cart |
| ProductRecommendationList | Personalised product recommendations |
| DestinationWeatherForecast | Weather data for destinations |
Client-side storage
Dexie (IndexedDB) is used to persist:
- Product availability form data
- Consumer trip information
- Local cart and booking state
Stack-based navigation
The Storefront uses a frame-based navigation model for modals and overlays. Navigation state is encoded in the URL ?s= parameter (base64 JSON), enabling deep linking to any view state. The stack supports breadcrumb-like navigation through the booking flow.