# 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](https://reactrouter.com/) in framework mode, and uses [Vite](https://vitejs.dev/) as the build tool. The structure separates your app code (`src/`) from configuration files at the project root.

```
my-storefront/
├── src/                        # Application code
│   ├── routes/                 # Page components (file-based routing)
│   ├── components/             # Reusable UI components
│   ├── lib/                    # Utilities and API clients
│   ├── hooks/                  # Custom React hooks
│   ├── providers/              # React context providers
│   ├── middlewares/            # Request/response middleware
│   ├── locales/                # Translation files
│   ├── root.tsx                # Application shell and layout
│   ├── routes.ts               # Route configuration
│   └── app.css                 # Global styles (Tailwind)
├── public/                     # Static assets (images, fonts)
├── types/                      # TypeScript type definitions
├── config.server.ts            # Commerce API and site configuration
├── vite.config.ts              # Build configuration
├── react-router.config.ts      # React Router settings
└── 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](https://reactrouter.com/how-to/file-route-conventions), where file names determine URL paths.

```
src/routes/
├── _index.tsx                  # Home page (/)
├── category.$.tsx              # Category pages (/category/*)
├── product.$productId.tsx      # Product pages (/product/:productId)
├── cart.tsx                    # Cart page (/cart)
├── checkout.tsx                # Checkout (/checkout)
├── account.tsx                 # Account layout
├── account._index.tsx          # Account home (/account)
├── account.orders.tsx          # Order history (/account/orders)
└── action.cart-item-add.tsx    # Server action for adding to cart
```

## File Naming Conventions

| 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)  |

:::note
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.

```typescript
// src/routes.ts
import { type RouteConfig } from '@react-router/dev/routes';
import { flatRoutes } from '@react-router/fs-routes';

export default flatRoutes() satisfies RouteConfig;
```

### Components

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

```
src/components/
├── ui/                         # Base UI primitives (buttons, inputs, dialogs)
├── header/                     # Site header and navigation
├── footer/                     # Site footer
├── product-view/               # Product display components
├── product-tile/               # Product cards for listings
├── cart/                       # Cart components
└── ...
```

The `ui/` subdirectory contains [shadcn/ui](https://ui.shadcn.com/) 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.

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

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.

```
src/hooks/
├── use-product.ts              # Product data access
├── use-cart.ts                 # Cart operations
├── use-navigation.ts           # Navigation utilities
└── ...
```

**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.

```
src/providers/
├── cart-provider.tsx           # Cart state and operations
├── locale-provider.tsx         # Internationalization context
└── ...
```

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:

```
src/middlewares/
├── auth-middleware.server.ts   # Authentication (server-side)
├── auth-middleware.client.ts   # Authentication (client-side)
├── i18n-middleware.ts          # Locale detection and setup
└── ...
```

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](/docs/commerce/b2c-commerce/guide/sfnext-storage-sessions.md).

### Locales

Translation files for internationalization:

```
src/locales/
├── en-US.json
├── fr-FR.json
└── ...
```

See [Internationalization](/docs/commerce/b2c-commerce/guide/sfnext-intl.md) 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:

| 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.

## Configuration Files

| File                                                                                                 | Purpose                                                                                                                                        |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `config.server.ts`                                                                                   | Commerce API connection and storefront settings. See [Configuration](/docs/commerce/b2c-commerce/guide/sfnext-project-config.md).              |
| `vite.config.ts`                                                                                     | Build plugins, path aliases, Server-Side Rendering (SSR) settings. See [Build Tools](/docs/commerce/b2c-commerce/guide/sfnext-build-tools.md). |
| [`react-router.config.ts`](https://reactrouter.com/api/framework-conventions/react-router.config.ts) | React Router framework options                                                                                                                 |
| `tsconfig.json`                                                                                      | TypeScript compiler options                                                                                                                    |
| `package.json`                                                                                       | Dependencies and npm scripts                                                                                                                   |

## Where to Put Code Elements

| 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`                   |

## Example: Adding a Wishlist Feature

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

```
src/
├── routes/
│   ├── wishlist.tsx              # 1. Page at /wishlist
│   └── action.wishlist-add.tsx   # 2. Server action for adding items
├── components/
│   └── wishlist/
│       ├── wishlist-item.tsx     # 3. UI components
│       └── wishlist-empty.tsx
├── hooks/
│   └── use-wishlist.ts           # 4. Hook for wishlist operations
└── lib/
    └── api/
        └── 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.

```bash
npx 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

- [*React Router API Reference:* React Router File Route Conventions](https://reactrouter.com/how-to/file-route-conventions)
- [*React Router API Reference:* React Router root.tsx](https://reactrouter.com/api/framework-conventions/root.tsx)
- [\_Vite:\_Vite Configuration](https://vitejs.dev/config/)
