Project Structure

Learn about the Storefront Next project structure to navigate code quickly and follow conventions that keep your codebase maintainable as it grows.

Overview 

A Storefront Next project is built on React Router 7 in framework mode, and uses Vite as the build tool. The structure separates your app code (src/) from configuration files at the project root.

1my-storefront/
2├── src/                        # Application code
3│   ├── routes/                 # Page components (file-based routing)
4│   ├── components/             # Reusable UI components
5│   ├── lib/                    # Utilities and API clients
6│   ├── hooks/                  # Custom React hooks
7│   ├── providers/              # React context providers
8│   ├── middlewares/            # Request/response middleware
9│   ├── locales/                # Translation files
10│   ├── root.tsx                # Application shell and layout
11│   ├── routes.ts               # Route configuration
12│   └── app.css                 # Global styles (Tailwind)
13├── public/                     # Static assets (images, fonts)
14├── types/                      # TypeScript type definitions
15├── config.server.ts            # Commerce API and site configuration
16├── vite.config.ts              # Build configuration
17├── react-router.config.ts      # React Router settings
18└── package.json                # Dependencies and scripts

Application Code in src/ 

Routes 

The routes/ directory contains your page components. Storefront Next uses React Router’s file-based routing, where file names determine URL paths.

1src/routes/
2├── _index.tsx                  # Home page (/)
3├── category.$.tsx              # Category pages (/category/*)
4├── product.$productId.tsx      # Product pages (/product/:productId)
5├── cart.tsx                    # Cart page (/cart)
6├── checkout.tsx                # Checkout (/checkout)
7├── account.tsx                 # Account layout
8├── account._index.tsx          # Account home (/account)
9├── account.orders.tsx          # Order history (/account/orders)
10└── action.cart-item-add.tsx    # Server action for adding to cart

File Naming Conventions 

PatternExampleURLPurpose
_index.tsx_index.tsx/Index route (renders at parent path)
name.tsxcart.tsx/cartStatic route
$paramproduct.$productId.tsx/product/:productIdDynamic segment that captures a value
$.tsxcategory.$.tsx/category/*Splat/catch-all route
parent.child.tsxaccount.orders.tsx/account/ordersNested route
action.*action.cart-item-add.tsxServer action (not a navigable page)

Files starting with underscore (_) have special meaning. _index.tsx renders at the parent path, while a _layout.tsx file creates a layout wrapper without adding a URL segment.

Note

The routes.ts file configures routing behavior. The flatRoutes() function scans your src/routes/ directory and generates route configuration automatically based on file names. You rarely have to modify this file.

1// src/routes.ts
2import { type RouteConfig } from '@react-router/dev/routes';
3import { flatRoutes } from '@react-router/fs-routes';
4
5export default flatRoutes() satisfies RouteConfig;

Components 

The components/ directory contains reusable UI elements organized by feature area.

1src/components/
2├── ui/                         # Base UI primitives (buttons, inputs, dialogs)
3├── header/                     # Site header and navigation
4├── footer/                     # Site footer
5├── product-view/               # Product display components
6├── product-tile/               # Product cards for listings
7├── cart/                       # Cart components
8└── ...

The ui/ subdirectory contains shadcn/ui components—accessible, customizable primitives that you can modify directly.

Create a component when:

  • The UI element is used in multiple places.
  • The component encapsulates complex logic or state.
  • You want to test the UI in isolation (via Storybook).

Lib 

The lib/ directory contains utilities, API clients, and business logic that isn’t tied to React.

1src/lib/
2├── api/                        # Commerce API client functions
3├── utils/                      # General utilities (formatting, validation)
4└── ...

Place code here when it:

  • Doesn’t use React hooks or components.
  • Could be shared across multiple routes or components.
  • Handles data transformation or business logic.

Hooks 

Custom React hooks extract reusable stateful logic from components.

1src/hooks/
2├── use-product.ts              # Product data access
3├── use-cart.ts                 # Cart operations
4├── use-navigation.ts           # Navigation utilities
5└── ...

When to create a custom hook:

  • Multiple components need the same stateful logic.
  • You want to encapsulate complex operations (like API calls with loading states).
  • You must share behavior across routes.

Providers 

React context providers supply data and functionality throughout the app.

1src/providers/
2├── cart-provider.tsx           # Cart state and operations
3├── locale-provider.tsx         # Internationalization context
4└── ...

Providers wrap the app in root.tsx and make data available to any nested component without prop drilling.

Middlewares 

Request and response middleware that runs before route loaders:

1src/middlewares/
2├── auth-middleware.server.ts   # Authentication (server-side)
3├── auth-middleware.client.ts   # Authentication (client-side)
4├── i18n-middleware.ts          # Locale detection and setup
5└── ...

Middleware is registered in root.tsx and executes in order for each request. Use middleware to:

  • Parse authentication tokens
  • Detect user locale
  • Set up shared context that loaders need

For details on implementing middleware, see Storage and Sessions.

Locales 

Translation files for internationalization:

1src/locales/
2├── en-US.json
3├── fr-FR.json
4└── ...

See Internationalization for setup and usage.

Root File (root.tsx) 

The root.tsx file is your app’s entry point. It exports several key pieces that define your app’s behavior:

ExportPurpose
middlewareServer middleware chain (auth, locale detection)
clientMiddlewareClient middleware chain (runs during client navigation)
loaderRoot data loader (fetches data needed by all pages)
LayoutHTML document structure (<html>, <head>, <body>)
default (App)Application shell with header, footer, and <Outlet /> for page content

Most customization happens in middleware and the App component. Typically, you only need to modify Layout when changing document-level meta tags or adding scripts.

Configuration Files 

FilePurpose
config.server.tsCommerce API connection and storefront settings. See Configuration.
vite.config.tsBuild plugins, path aliases, Server-Side Rendering (SSR) settings. See Build Tools.
react-router.config.tsReact Router framework options
tsconfig.jsonTypeScript compiler options
package.jsonDependencies and npm scripts

Where to Put Code Elements 

You want to…Put it in…
Add a new pagesrc/routes/ (file name = URL path)
Create a reusable componentsrc/components/
Add a server actionsrc/routes/action.*.tsx
Add a utility functionsrc/lib/
Create a custom hooksrc/hooks/
Add translationssrc/locales/
Add static assets (images)public/
Add global stylessrc/app.css
Configure commerce or storefront settingsconfig.server.ts

Example: Adding a Wishlist Feature 

Here’s how the project structure guides you when adding a new feature:

1src/
2├── routes/
3│   ├── wishlist.tsx              # 1. Page at /wishlist
4│   └── action.wishlist-add.tsx   # 2. Server action for adding items
5├── components/
6│   └── wishlist/
7│       ├── wishlist-item.tsx     # 3. UI components
8│       └── wishlist-empty.tsx
9├── hooks/
10│   └── use-wishlist.ts           # 4. Hook for wishlist operations
11└── lib/
12    └── api/
13        └── wishlist.ts           # 5. API client functions

This separation keeps your code organized.

  • Routes define what URLs exist and load data.
  • Components handle presentation.
  • Hooks manage stateful logic.
  • Lib contains pure functions and API calls.

Customizing Entry Files 

React Router provides default entry files for client hydration and server rendering. These entry files are hidden by default but can be revealed for advanced customization.

1npx react-router reveal

This command creates entry.client.tsx and entry.server.tsx in your src/ directory.

When to customize:

  • Initialize client libraries before hydration
  • Add custom error reporting (for example, Sentry)
  • Modify server response headers
  • Customize streaming behavior

For most projects, the default entry files work without modification.

See Also