typescript
65 lines · 2 tabs
Maya Patel
Jan 2026
2 tabs
import { Navigate, useLocation } from 'react-router-dom'
import { useAuth } from '@/contexts/AuthContext'
interface ProtectedRouteProps {
children: React.ReactNode
}
export function ProtectedRoute({ children }: ProtectedRouteProps) {
const { isAuthenticated, loading } = useAuth()
const location = useLocation()
if (loading) {
return <div>Loading...</div>
}
if (!isAuthenticated) {
return <Navigate to="/login" state={{ from: location }} replace />
}
return <>{children}</>
}
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { Suspense, lazy } from 'react'
import { AuthProvider } from '@/contexts/AuthContext'
import { ProtectedRoute } from '@/components/ProtectedRoute'
import Layout from '@/components/Layout'
const Home = lazy(() => import('@/pages/Home'))
const Login = lazy(() => import('@/pages/Login'))
const Posts = lazy(() => import('@/pages/Posts'))
const PostDetail = lazy(() => import('@/pages/PostDetail'))
const NewPost = lazy(() => import('@/pages/NewPost'))
function App() {
return (
<AuthProvider>
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/login" element={<Login />} />
<Route element={<Layout />}>
<Route path="/" element={<Home />} />
<Route path="/posts" element={<Posts />} />
<Route path="/posts/:id" element={<PostDetail />} />
<Route
path="/posts/new"
element={
<ProtectedRoute>
<NewPost />
</ProtectedRoute>
}
/>
</Route>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</BrowserRouter>
</AuthProvider>
)
}
export default App
2 files · typescript
Explain with highlit
React Router v6 provides declarative routing with data loading and authentication guards. I wrap protected routes in a ProtectedRoute component that checks authentication state from context and redirects to login if needed. The Navigate component handles redirects while preserving the attempted URL so users land where they intended after logging in. Nested routes share layouts via Outlet, avoiding component duplication. The useNavigate hook enables programmatic navigation after form submissions. Lazy loading route components with React.lazy and Suspense keeps initial bundle sizes small. This routing setup handles complex multi-page apps while maintaining type safety with TypeScript.
Related snips
typescript
export interface RetryOptions {
retries: number;
baseMs: number;
maxMs: number;
signal?: AbortSignal;
onRetry?: (attempt: number, delay: number, err: unknown) => void;
Exponential backoff with jitter for retries
typescript
reliability
retry
by codesnips
2 tabs
python
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
Django URL namespacing and reverse lookups
django
python
urls
by Priya Sharma
3 tabs
typescript
import axios, { AxiosError } from 'axios'
import { v4 as uuidv4 } from 'uuid'
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api/v1',
timeout: 15000,
Axios API client with interceptors
react
axios
api
by Maya Patel
1 tab
typescript
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
interface FilterState {
search: string
category: string | null
Zustand for lightweight state management
react
zustand
state-management
by Maya Patel
2 tabs
typescript
import React from "react";
type FallbackProps = {
error: Error;
reset: () => void;
};
React Error Boundary + error reporting hook
react
frontend
error-boundary
by codesnips
3 tabs
javascript
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
openAnalyzer: true,
});
/** @type {import('next').NextConfig} */
Next.js bundle analyzer for targeted performance work
nextjs
performance
tooling
by codesnips
4 tabs
Share this code
Here's the card — post it anywhere.