Skip to main content

Framework Mode

Framework Mode is the full-featured way to use React Router. It wraps Data Mode with a Vite plugin to add type-safe routing, intelligent code splitting, and flexible rendering strategies (SPA, SSR, SSG).

Quick Start

1
Create a new project
2
npx create-react-router@latest my-app
cd my-app
npm install
npm run dev
3
Open your browser
4
Visit http://localhost:5173 to see your app running.

What You Get

Framework Mode provides:
  • Type Safety: Auto-generated types for params, loader data, and actions
  • Code Splitting: Automatic route-based code splitting
  • SSR/SPA/SSG: Choose your rendering strategy per route
  • File-based or Config-based Routing: Use what works for your team
  • Optimized Builds: Production-ready bundling with Vite
  • Development Server: Fast HMR and instant feedback

Project Structure

A typical Framework Mode project looks like this:
my-app/
├── app/
│   ├── routes/
│   │   ├── _index.tsx       # Home page (/)
│   │   ├── about.tsx         # About page (/about)
│   │   └── products.$id.tsx  # Product detail (/products/:id)
│   ├── root.tsx              # Root layout
│   └── routes.ts             # Route configuration
├── public/                   # Static assets
├── react-router.config.ts    # React Router config
└── vite.config.ts            # Vite config

Configuring Routes

Route Modules

Route modules define behavior for each route using exports:
// app/routes/product.$id.tsx
import type { Route } from "./+types/product.$id";

export async function loader({ params }: Route.LoaderArgs) {
  const product = await fetchProduct(params.id);
  return { product };
}

export default function Product({ loaderData }: Route.ComponentProps) {
  return (
    <div>
      <h1>{loaderData.product.name}</h1>
      <p>{loaderData.product.description}</p>
    </div>
  );
}

Type Safety

Framework Mode automatically generates types for your routes:
import type { Route } from "./+types/product.$id";
//                              ^
//          Auto-generated from route file name

export async function loader({ params }: Route.LoaderArgs) {
  //                           ^
  //         params.id is type-safe!
  const product = await fetchProduct(params.id);
  return { product };
}

export default function Product({ loaderData }: Route.ComponentProps) {
  //                              ^
  //            loaderData.product is type-safe!
  return <h1>{loaderData.product.name}</h1>;
}
Types are generated automatically on file changes during development. No manual type definitions needed!

Nested Routes and Layouts

1
Create a parent layout
2
import { Outlet } from "react-router";

export default function DashboardLayout() {
  return (
    <div>
      <aside>
        <nav>{/* sidebar navigation */}</nav>
      </aside>
      <main>
        <Outlet /> {/* Child routes render here */}
      </main>
    </div>
  );
}
3
Configure nested routes
4
import { route, index } from "@react-router/dev/routes";

export default [
  route("dashboard", "./dashboard.tsx", [
    index("./dashboard/home.tsx"),        // /dashboard
    route("settings", "./dashboard/settings.tsx"),  // /dashboard/settings
    route("profile", "./dashboard/profile.tsx"),    // /dashboard/profile
  ]),
];

Data Loading Strategies

// Runs on server for SSR, and on client for navigation
export async function loader({ params }: Route.LoaderArgs) {
  const data = await db.getData(params.id);
  return { data };
}

Rendering Strategies

Configure in react-router.config.ts:
export default {
  ssr: false,
};

Vite Plugin Setup

The plugin is configured in vite.config.ts:
import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [reactRouter()],
});

Next Steps

1
Learn Route Modules
2
Explore all the exports available in route modules: loader, action, meta, headers, ErrorBoundary, and more.
3
Add Authentication
4
Implement protected routes with loaders and redirects.
5
Deploy Your App
6
Deploy to Vercel, Cloudflare, or any Node.js host with adapters.
Framework Mode gives you the full power of React Router with the best developer experience.

Build docs developers (and LLMs) love