Skip to main content

How to Structure Routing in React (Vite + TypeScript) Like a Pro (2026 Guide)

Sakar Khadka
6 min read
How to Structure Routing in React (Vite + TypeScript) Like a Pro (2026 Guide)

πŸš€ React Routing Done Right (Vite + TypeScript)#

Let’s be honest.

Most React apps start simple… and then routing becomes a mess.

  • Guards everywhere
  • Duplicate wrappers
  • Confusing structure

So in this guide, I’ll show you a clean, scalable routing setup you can actually use in real projects.


🧠 The Core Idea#

Instead of thinking:

β€œWhich page goes where?”

Think:

β€œWho is allowed to access this route?”


πŸ“ Folder Structure#

Folder structure is very importaint for scalable applications. If you know better do let me know

src
β”œβ”€β”€ router
β”‚   β”œβ”€β”€ protected-route.tsx
β”‚   β”œβ”€β”€ auth-route.tsx
β”‚   └── index.tsx
β”‚
β”œβ”€β”€ components
β”‚   └── ui
β”‚
β”œβ”€β”€ layouts
β”‚   β”œβ”€β”€ app-layout.tsx
β”‚   └── auth-layout.tsx
β”‚
β”œβ”€β”€ pages
β”‚   β”œβ”€β”€ login.tsx
β”‚   β”œβ”€β”€ register.tsx
β”‚   β”œβ”€β”€ dashboard.tsx
β”‚   β”œβ”€β”€ home.tsx
β”‚   └── about.tsx
β”‚
β”œβ”€β”€ Main.tsx
└── index.css

πŸ”‘ Three Types of Routes#

🌍 1. Public Routes (No Guard)#

Accessible by everyone.

  • /
  • /about
  • /contact
{ path: "/", element: <Home /> }

🟒 2. Auth Routes (Only for Logged-Out Users)#

Used for:

  • /login
  • /register
import { Navigate } from 'react-router-dom';
 
export default function AuthRoute({ children }: any) {
  const isAuthenticated = true; // testing
 
  if (isAuthenticated) {
    return <Navigate to="/dashboard" replace />;
  }
 
  return children;
}

πŸ‘‰ If user is logged in β†’ redirect to dashboard


πŸ”’ 3. Protected Routes (Only for Logged-In Users)#

Used for:

  • /dashboard
  • /profile
import { Navigate } from 'react-router-dom';
 
export default function ProtectedRoute({ children }: any) {
  const isAuthenticated = true; // testing
 
  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }
 
  return children;
}

πŸ‘‰ If user is NOT logged in β†’ redirect to login


🧩 Clean Routing Setup#

Here’s the actual structure πŸ‘‡

import { createBrowserRouter } from 'react-router-dom';
 
import { Login } from '../pages/login';
import { Register } from '../pages/register';
import { Dashboard } from '../pages/dashboard';
import AuthLayout from '../layout/auth-layout';
import AppLayout from '../layout/app-layout';
import { Home } from '../pages/home';
import { AboutPage } from '../pages/about';
import AuthRoute from './auth-route';
import ProtectedRoute from './protected-route';
 
export const router = createBrowserRouter([
  //   Public Routes No Guard
 
  { path: '/', element: <Home /> },
  { path: '/about', element: <AboutPage /> },
 
  //   Auth Guarded Routes
  {
    element: (
      <AuthRoute>
        <AuthLayout />
      </AuthRoute>
    ),
    children: [
      { path: '/login', element: <Login /> },
      { path: '/register', element: <Register /> },
    ],
  },
 
  // PROTECTED Routes
  {
    element: (
      <ProtectedRoute>
        <AppLayout />
      </ProtectedRoute>
    ),
    children: [{ path: '/dashboard', element: <Dashboard /> }],
  },
]);

🧱 Why Layouts Matter#

Instead of repeating UI everywhere:

  • Navbar
  • Sidebar
  • Auth container

πŸ‘‰ You define them once using layouts.


Example: App Layout#

function AppLayout() {
  return (
    <div>
      <Sidebar />
      <main>
        <Outlet />
      </main>
    </div>
  );
}

Example: Auth Layout#

function AuthLayout() {
  return (
    <div className="centered-container">
      <Outlet />
    </div>
  );
}

πŸ” Route Guards#

AuthRoute#

if (isAuthenticated) {
  return <Navigate to="/dashboard" />;
}

ProtectedRoute#

if (!isAuthenticated) {
  return <Navigate to="/login" />;
}

⚠️ Common Mistakes#

❌ Using "PublicRoute" for everything#

This blocks logged-in users from normal pages like /about.


❌ Wrapping every route manually#

Leads to messy and repetitive code.


❌ Mixing layout + auth logic#

Keep them separate.


🧠 Mental Model (Remember This)#

TypeAccessGuard
PublicEveryone❌ None
AuthLogged-outβœ… AuthRoute
ProtectedLogged-inβœ… ProtectedRoute

⚑ Pro Tips#

  • Use route grouping with <Outlet />
  • Keep routes centralized
  • Use layouts for UI reuse
  • Don’t over-engineer early

🏁 Final Thoughts#

You don’t need file-based routing like Next.js to build scalable apps.

With:

  • React Router
  • Layouts
  • Route guards

πŸ‘‰ You already have a production-ready system.


πŸ’¬ Final Takeaway#

Routing is not about pages.

It’s about access control + structure.

Get that right early, and your app stays clean forever.