Project Structure
Learn about the Storefront Next project structure to navigate code quickly and follow conventions that keep your codebase maintainable as it grows.
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.
The routes/ directory contains your page components. Storefront Next uses React Router’s file-based routing, where file names determine URL paths.
| Pattern | Example | URL | Purpose |
|---|---|---|---|
_index.tsx | _index.tsx | / | Index route (renders at parent path) |
name.tsx | cart.tsx | /cart | Static route |
$param | product.$productId.tsx | /product/:productId | Dynamic segment that captures a value |
$.tsx | category.$.tsx | /category/* | Splat/catch-all route |
parent.child.tsx | account.orders.tsx | /account/orders | Nested route |
action.* | action.cart-item-add.tsx | — | Server 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.
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.
The components/ directory contains reusable UI elements organized by feature area.
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).
The lib/ directory contains utilities, API clients, and business logic that isn’t tied to React.
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.
Custom React hooks extract reusable stateful logic from components.
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.
React context providers supply data and functionality throughout the app.
Providers wrap the app in root.tsx and make data available to any nested component without prop drilling.
Request and response middleware that runs before route loaders:
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.
Translation files for internationalization:
See Internationalization for setup and usage.
The root.tsx file is your app’s entry point. It exports several key pieces that define your app’s behavior:
| Export | Purpose |
|---|---|
middleware | Server middleware chain (auth, locale detection) |
clientMiddleware | Client middleware chain (runs during client navigation) |
loader | Root data loader (fetches data needed by all pages) |
Layout | HTML 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.
| File | Purpose |
|---|---|
config.server.ts | Commerce API connection and storefront settings. See Configuration. |
vite.config.ts | Build plugins, path aliases, Server-Side Rendering (SSR) settings. See Build Tools. |
react-router.config.ts | React Router framework options |
tsconfig.json | TypeScript compiler options |
package.json | Dependencies and npm scripts |
| You want to… | Put it in… |
|---|---|
| Add a new page | src/routes/ (file name = URL path) |
| Create a reusable component | src/components/ |
| Add a server action | src/routes/action.*.tsx |
| Add a utility function | src/lib/ |
| Create a custom hook | src/hooks/ |
| Add translations | src/locales/ |
| Add static assets (images) | public/ |
| Add global styles | src/app.css |
| Configure commerce or storefront settings | config.server.ts |
Here’s how the project structure guides you when adding a new feature:
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.
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.
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.