Storefront Application
Relevant source files
The following files were used as context for generating this wiki page:
The Storefront Application is a multi-tenant, headless e-commerce platform built with Next.js 16 and React 19. It serves as the customer-facing interface for the Nordcom Commerce ecosystem, providing a unified infrastructure that renders catalog, cart, account, and CMS pages for multiple shops from a single deployment.
The application leverages Shopify for commerce backend operations (catalog, cart, checkout) and a Convex-native CMS for structured content. It utilizes edge-friendly caching and hostname-based tenant resolution to ensure high performance and scalability across diverse merchant environments.
Sources: apps/storefront/README.md:3-8, README.md:16-25, CONTEXT.md:417-419
Architecture and Core Systems
Multi-Tenant Routing
Tenancy is resolved dynamically at the edge. The system identifies the shop based on the request hostname and rewrites the internal URL structure to a tenant-scoped segment.
The middleware strips ports and environment suffixes (like .localhost or Vercel preview suffixes) before querying the Convex database for the corresponding shop record. If no shop is found, the request is redirected to a global service domain status page.
Sources: apps/storefront/README.md:28-36, README.md:144-150, CONTEXT.md:13-22
Data Fetching and Integration
The Storefront acts as a consumer of multiple data sources, primarily Shopify and the internal CMS. All Shopify interactions are abstracted through a specialized client.
| Component | Description |
|---|---|
| AbstractApi | The base class for all Shopify queries, ensuring consistent fetch options. |
| ShopifyApolloApiClient | The primary GraphQL client utilizing Apollo and Hydrogen for commerce data. |
| Block Loaders | Shopify-aware data fetchers injected into the CMS rendering layer. |
| CMS Read Transport | Internal getters that fetch published content from Convex. |
Sources: apps/storefront/README.md:55-65, apps/storefront/README.md:73-82, CONTEXT.md:65-69
Cache Taxonomy and Invalidation
Caching is partitioned by namespace (shopify or cms) to prevent invalidation entanglement. Every cached entity is both tenant-scoped (using a shop ID) and locale-qualified.
Revalidation is triggered via webhooks. Shopify webhooks verify HMAC signatures and map topics to specific entity tags. CMS invalidation is handled via a signed HMAC event from the Convex revalidation pipeline.
Sources: apps/storefront/README.md:67-71, apps/storefront/README.md:84-93, CONTEXT.md:85-93
Components and Rendering
CMS Content Rendering
The Storefront uses a BlockRenderer from the @nordcom/commerce-cms package to render dynamic pages. While the CMS package defines the block shapes, the Storefront provides the actual data fetching logic for Shopify-integrated blocks.
Product Card System
The Product Card is a token-driven primitive used across browse surfaces like collections, recommendations, and search.
- Surface Wrappers: Context-specific compositions (e.g.,
CollectionProductCard). - Picker: The UI for variant selection (modal, sheet, or inline).
- Fast-path: An optimization that adds single-variant products directly to the cart without opening the picker.
Sources: CONTEXT.md:434-450
Configuration and Environment
The application relies on several critical environment variables for tenant resolution and secure provider access.
| Variable | Purpose |
|---|---|
CONVEX_URL | Convex deployment for shop metadata and CMS content. |
CONVEX_SERVER_SECRET | Required for pre-tenant reads in middleware. |
SERVICE_DOMAIN | Fallback hostname for unknown shop errors. |
SHOPIFY_WEBHOOK_SECRET | HMAC validation for Shopify cache revalidation. |
STOREFRONT_PREVIEW_SECRET | Secret used to enter CMS draft mode. |
Sources: apps/storefront/README.md:18-26
Development and Tooling
The application follows strict coding conventions to maintain type safety and performance:
- Server Components: Used by default;
use clientis reserved for hooks and event handlers. - Async APIs: Next.js 16 APIs (params, searchParams, cookies) are treated as promises and awaited.
- Taint Protection: Provider tokens are guarded with
experimental_taintUniqueValueto prevent exposure to the client. - Linting: Biome is the sole tool for linting and formatting; raw
console.logis prohibited.
Sources: CLAUDE.md:104-120, apps/storefront/README.md:124-128
The Storefront Application provides a robust, multi-tenant framework that balances shared infrastructure with tenant-specific content and commerce logic. By centralizing routing and data abstraction, it allows for seamless scaling of merchant storefronts.