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.