# ajmalajjuca/storefront architecture

> Architecture diagram of the GitHub repository ajmalajjuca/storefront, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ajmalajjuca/storefront
- Repository: https://github.com/ajmalajjuca/storefront

## Overview

#### Purpose and Runtime
This is a server-rendered, headless Shopify storefront built with Next.js App Router and React Server Components. It is intended for Vercel deployment, with Shopify Storefront API credentials and revalidation secret supplied through environment variables. The main application shell begins at `app/layout.tsx`; storefront entry routes include `app/(browser)/page.tsx` and product, collection, editorial, and policy routes under `app/`.

#### Routing, Rendering, and SEO
App Router pages render catalog and content views on the server, with client islands where interaction is required. Key route families are product detail at `app/products/[handle]/page.tsx`, collections/products indexes at `app/indexes/collections/page.tsx` and `app/indexes/products/page.tsx`, and editorial stories at `app/story/[slug]/page.tsx`. Search-engine discovery is generated by `app/sitemap.ts` and `app/robots.ts`; global failures are handled by `app/error.tsx`.

#### Commerce Provider Boundary
`lib/shopify/` is the provider adapter boundary: it contains the Shopify client and domain-facing types in `lib/shopify/index.ts` and `lib/shopify/types.ts`, reusable GraphQL fragments in `lib/shopify/fragments/`, and operation definitions in `lib/shopify/queries/` and `lib/shopify/mutations/`. Pages and components should consume this layer rather than issue Storefront API calls directly, enabling a provider replacement without broadly changing UI code.

#### Catalog and Content Flow
Route handlers/pages resolve a product handle, collection, page, policy, or metaobject; query modules retrieve it from Shopify; server components transform that data into catalog and editorial UI. Product-facing rendering is centered on `app/products/[handle]/page.tsx` with interactive variant/purchase behavior in `app/products/[handle]/product-client.tsx`. Shared product display primitives include `components/product-card/index.tsx`, `components/product-rail/index.tsx`, and `components/collection-showcase/index.tsx`.

#### Cart and Checkout State
The cart is a client-side context backed by Shopify cart mutations. `components/cart/cart-context.tsx` owns cart state and optimistic updates, while `components/cart/actions.ts` invokes server-side cart operations represented in `lib/shopify/mutations/cart.ts`. The drawer UI at `components/cart/drawer.tsx` consumes that state; Shopify remains authoritative for cart identity, lines, prices, and checkout progression.

#### Personalization and Browser-State Features
Client contexts manage preferences that should not alter Shopify source data: currency selection/exchange-rate display is implemented in `components/currency/currency-preference-context.tsx`, `components/currency/exchange-rates-context.tsx`, and `components/currency/use-display-money.ts`. Wishlist persistence and controls are isolated in `components/wishlist/wishlist-context.tsx` and `app/wishlist/wishlist-client.tsx`. The browser-specific shell is separated under `app/(browser)/layout.tsx`.

#### Invalidation, Domains, and External Interfaces
Shopify-triggered cache invalidation enters through `app/api/revalidate/route.ts`, protected by a revalidation secret, allowing catalog/content changes to refresh rendered routes. `middleware.ts` and `lib/domain-redirects.ts` define request-level domain routing/redirect behavior; `snippets/shopify-theme-domain-redirect.liquid` supports corresponding behavior from the Shopify theme. Newsletter and prebook submissions use server actions at `components/newsletter/actions.ts` and `app/prebook/[handle]/notify-form.tsx`, forming explicit server-side integration boundaries.

Main entry points: [`app/(browser)/layout.tsx`](https://github.com/ajmalajjuca/storefront/blob/main/app/(browser)/layout.tsx) (Browser shell), [`lib/shopify/index.ts`](https://github.com/ajmalajjuca/storefront/blob/main/lib/shopify/index.ts) (Shopify adapter), [`app/products/[handle]/page.tsx`](https://github.com/ajmalajjuca/storefront/blob/main/app/products/%5Bhandle%5D/page.tsx) (Product detail), [`components/cart/cart-context.tsx`](https://github.com/ajmalajjuca/storefront/blob/main/components/cart/cart-context.tsx) (Cart state)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_routing["App Routing"]
  node_app_shell["Application shell<br/>Next.js layout<br/>[layout.tsx]"]
  node_browser_shell["Browser shell<br/>client-aware layout<br/>[layout.tsx]"]
  node_storefront_home["Storefront entry<br/>route page<br/>[page.tsx]"]
  node_product_route["Product detail<br/>server route<br/>[page.tsx]"]
  node_catalog_indexes["Catalog indexes<br/>server routes<br/>[page.tsx]"]
  node_editorial_route["Editorial story<br/>server route<br/>[page.tsx]"]
  node_seo_discovery["SEO discovery<br/>metadata routes<br/>[sitemap.ts]"]
  node_product_primitives["Product display primitives<br/>shared components<br/>[index.tsx]"]
end

subgraph group_commerce["Commerce Boundary"]
  node_shopify_adapter{{"Shopify adapter<br/>provider client<br/>[index.ts]"}}
  node_shopify_types["Commerce types<br/>domain types<br/>[types.ts]"]
  node_graphql_operations["GraphQL operations<br/>queries and mutations"]
  node_shopify_api{{"Shopify Storefront API<br/>external commerce API"}}
end

subgraph group_client["Client State"]
  node_product_client["Variant and purchase UI<br/>client island<br/>[product-client.tsx]"]
  node_cart_context["Cart state<br/>client context<br/>[cart-context.tsx]"]
  node_cart_actions["Cart server actions<br/>[actions.ts]"]
  node_cart_drawer["Cart drawer<br/>client UI<br/>[drawer.tsx]"]
  node_browser_preferences["Browser preferences<br/>client contexts"]
end

subgraph group_interfaces["External Interfaces"]
  node_revalidation{{"Cache invalidation<br/>webhook route<br/>[route.ts]"}}
  node_domain_routing["Domain routing<br/>request middleware<br/>[middleware.ts]"]
  node_submissions["Submission actions<br/>server integrations<br/>[actions.ts]"]
end

node_app_shell -->|"wraps"| node_browser_shell
node_browser_shell -->|"renders"| node_storefront_home
node_browser_shell -->|"routes to"| node_product_route
node_browser_shell -->|"routes to"| node_catalog_indexes
node_browser_shell -->|"routes to"| node_editorial_route
node_product_route -->|"loads product"| node_shopify_adapter
node_catalog_indexes -->|"loads catalog"| node_shopify_adapter
node_editorial_route -->|"loads content"| node_shopify_adapter
node_seo_discovery -->|"discovers routes"| node_shopify_adapter
node_shopify_adapter -->|"uses"| node_shopify_types
node_shopify_adapter -->|"executes"| node_graphql_operations
node_graphql_operations -->|"Storefront API"| node_shopify_api
node_product_route -->|"hydrates interaction"| node_product_client
node_product_route -->|"composes"| node_product_primitives
node_product_client -->|"adds variants"| node_cart_context
node_cart_drawer -->|"consumes"| node_cart_context
node_cart_context -->|"persists changes"| node_cart_actions
node_cart_actions -->|"cart mutations"| node_graphql_operations
node_browser_shell -->|"provides"| node_browser_preferences
node_revalidation -.->|"refreshes cached data"| node_shopify_adapter
node_domain_routing -->|"routes requests"| node_browser_shell
node_submissions -.->|"server-side integration"| node_shopify_api

click node_app_shell "https://github.com/ajmalajjuca/storefront/blob/main/app/layout.tsx"
click node_browser_shell "https://github.com/ajmalajjuca/storefront/blob/main/app/(browser)/layout.tsx"
click node_storefront_home "https://github.com/ajmalajjuca/storefront/blob/main/app/(browser)/page.tsx"
click node_product_route "https://github.com/ajmalajjuca/storefront/blob/main/app/products/%5Bhandle%5D/page.tsx"
click node_product_client "https://github.com/ajmalajjuca/storefront/blob/main/app/products/%5Bhandle%5D/product-client.tsx"
click node_catalog_indexes "https://github.com/ajmalajjuca/storefront/blob/main/app/indexes/collections/page.tsx"
click node_editorial_route "https://github.com/ajmalajjuca/storefront/blob/main/app/story/%5Bslug%5D/page.tsx"
click node_seo_discovery "https://github.com/ajmalajjuca/storefront/blob/main/app/sitemap.ts"
click node_shopify_adapter "https://github.com/ajmalajjuca/storefront/blob/main/lib/shopify/index.ts"
click node_shopify_types "https://github.com/ajmalajjuca/storefront/blob/main/lib/shopify/types.ts"
click node_product_primitives "https://github.com/ajmalajjuca/storefront/blob/main/components/product-card/index.tsx"
click node_cart_context "https://github.com/ajmalajjuca/storefront/blob/main/components/cart/cart-context.tsx"
click node_cart_actions "https://github.com/ajmalajjuca/storefront/blob/main/components/cart/actions.ts"
click node_cart_drawer "https://github.com/ajmalajjuca/storefront/blob/main/components/cart/drawer.tsx"
click node_browser_preferences "https://github.com/ajmalajjuca/storefront/blob/main/components/currency/currency-preference-context.tsx"
click node_revalidation "https://github.com/ajmalajjuca/storefront/blob/main/app/api/revalidate/route.ts"
click node_domain_routing "https://github.com/ajmalajjuca/storefront/blob/main/middleware.ts"
click node_submissions "https://github.com/ajmalajjuca/storefront/blob/main/components/newsletter/actions.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app_shell,node_browser_shell,node_storefront_home,node_product_route,node_catalog_indexes,node_editorial_route,node_seo_discovery,node_product_primitives toneBlue
class node_shopify_adapter,node_shopify_types,node_graphql_operations,node_shopify_api toneAmber
class node_product_client,node_cart_context,node_cart_actions,node_cart_drawer,node_browser_preferences toneMint
class node_revalidation,node_domain_routing,node_submissions toneRose
```

## Components

### App Routing

Server-rendered storefront routes and discovery.

- [Application shell](https://github.com/ajmalajjuca/storefront/blob/main/app/layout.tsx): Next.js layout · `app/layout.tsx`
- [Browser shell](https://github.com/ajmalajjuca/storefront/blob/main/app/(browser)/layout.tsx): client-aware layout · `app/(browser)/layout.tsx`
- [Storefront entry](https://github.com/ajmalajjuca/storefront/blob/main/app/(browser)/page.tsx): route page · `app/(browser)/page.tsx`
- [Product detail](https://github.com/ajmalajjuca/storefront/blob/main/app/products/%5Bhandle%5D/page.tsx): server route · `app/products/[handle]/page.tsx`
- [Catalog indexes](https://github.com/ajmalajjuca/storefront/blob/main/app/indexes/collections/page.tsx): server routes · Collection and product listing pages. · `app/indexes/collections/page.tsx`
- [Editorial story](https://github.com/ajmalajjuca/storefront/blob/main/app/story/%5Bslug%5D/page.tsx): server route · `app/story/[slug]/page.tsx`
- [SEO discovery](https://github.com/ajmalajjuca/storefront/blob/main/app/sitemap.ts): metadata routes · Sitemap and robots generation. · `app/sitemap.ts`
- [Product display primitives](https://github.com/ajmalajjuca/storefront/blob/main/components/product-card/index.tsx): shared components · Cards, rails, and collection showcases. · `components/product-card/index.tsx`

### Commerce Boundary

Shopify adapter and Storefront API operations.

- [Shopify adapter](https://github.com/ajmalajjuca/storefront/blob/main/lib/shopify/index.ts): provider client · UI-facing commerce access boundary. · `lib/shopify/index.ts`
- [Commerce types](https://github.com/ajmalajjuca/storefront/blob/main/lib/shopify/types.ts): domain types · `lib/shopify/types.ts`
- **GraphQL operations**: queries and mutations · Uses reusable fragments for Storefront API operations.
- **Shopify Storefront API**: external commerce API · Authoritative catalog, cart, and checkout service.

### Client State

Interactive browser contexts and UI islands.

- [Variant and purchase UI](https://github.com/ajmalajjuca/storefront/blob/main/app/products/%5Bhandle%5D/product-client.tsx): client island · `app/products/[handle]/product-client.tsx`
- [Cart state](https://github.com/ajmalajjuca/storefront/blob/main/components/cart/cart-context.tsx): client context · Owns optimistic cart state. · `components/cart/cart-context.tsx`
- [Cart server actions](https://github.com/ajmalajjuca/storefront/blob/main/components/cart/actions.ts): server action · `components/cart/actions.ts`
- [Cart drawer](https://github.com/ajmalajjuca/storefront/blob/main/components/cart/drawer.tsx): client UI · `components/cart/drawer.tsx`
- [Browser preferences](https://github.com/ajmalajjuca/storefront/blob/main/components/currency/currency-preference-context.tsx): client contexts · Currency display and persistent wishlist state. · `components/currency/currency-preference-context.tsx`

### External Interfaces

Invalidation, domain, and submission boundaries.

- [Cache invalidation](https://github.com/ajmalajjuca/storefront/blob/main/app/api/revalidate/route.ts): webhook route · Secret-protected Shopify-triggered revalidation. · `app/api/revalidate/route.ts`
- [Domain routing](https://github.com/ajmalajjuca/storefront/blob/main/middleware.ts): request middleware · Request redirects coordinated with the Shopify theme. · `middleware.ts`
- [Submission actions](https://github.com/ajmalajjuca/storefront/blob/main/components/newsletter/actions.ts): server integrations · Newsletter and prebook submission boundary. · `components/newsletter/actions.ts`

## Connections

- Application shell → Browser shell: wraps
- Browser shell → Storefront entry: renders
- Browser shell → Product detail: routes to
- Browser shell → Catalog indexes: routes to
- Browser shell → Editorial story: routes to
- Product detail → Shopify adapter: loads product
- Catalog indexes → Shopify adapter: loads catalog
- Editorial story → Shopify adapter: loads content
- SEO discovery → Shopify adapter: discovers routes
- Shopify adapter → Commerce types: uses
- Shopify adapter → GraphQL operations: executes
- GraphQL operations → Shopify Storefront API: Storefront API
- Product detail → Variant and purchase UI: hydrates interaction
- Product detail → Product display primitives: composes
- Variant and purchase UI → Cart state: adds variants
- Cart drawer → Cart state: consumes
- Cart state → Cart server actions: persists changes
- Cart server actions → GraphQL operations: cart mutations
- Browser shell → Browser preferences: provides
- Cache invalidation → Shopify adapter: refreshes cached data
- Domain routing → Browser shell: routes requests
- Submission actions → Shopify Storefront API: server-side integration
