Holibob Docs

Architecture

Technical architecture and application structure of the Storefront.

Technology stack

ComponentTechnology
FrameworkNext.js 14 (App Router)
LanguageTypeScript 5.4.5
StylingTailwind CSS 4.0 + Radix UI + shadcn/ui
Data fetchingApollo Client 3.7 + graphql-request 6.1
State managementReact Context + XState 4.38
Client storageDexie 4.0 (IndexedDB)
FormsReact Hook Form 7.48 + Zod 3.25
Internationalisationi18next 22.5 + react-i18next 12.3
AnimationFramer Motion 11.18
MonitoringDatadog RUM + APM
DeploymentSST (AWS Lambda + CloudFront)
RuntimeNode.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:

  1. State decoding — Decode the ?s= URL parameter containing encoded state.
  2. Viewer data fetch — Load distribution channel and brand information via GraphQL.
  3. Consumer trip resolution — Identify the consumer trip from URL, state, or cookies.
  4. Language resolution — Determine language from cookie, header, or distribution channel default.
  5. Currency resolution — Determine currency from cookie, trip, or distribution channel default.
  6. Redirects — Handle localisation redirects, consumer trip cookie setup, and frame navigation.
  7. Response enrichment — Set cookies and headers on the response.

Data layer

GraphQL queries

Key queries include:

QueryPurpose
ViewerBrand, distribution channel, languages, currencies
ConsumerTripTrip data, dates, recommendations
ProductProduct details, pricing, availability
ProductListProduct catalogue browsing
AvailabilitySpecific availability slots
BookingAvailabilityAvailability for items in cart
ProductRecommendationListPersonalised product recommendations
DestinationWeatherForecastWeather 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.