Exports static routes for app and uses react router v6 for client side routing.
Inspired by this gist. Props to eddyw and tannerlinsley for the idea & code ❤️
Install deps
yarn
Run locally
yarn dev
Build
yarn build
Here are various ways to have protected routes
import { useAuth } from '@/lib/auth';
const { ProtectedRoutes } = lazyImport(() => import('./ProtectedRoutes'), 'ProtectedRoutes');
const { PublicRoutes } = lazyImport(() => import('./PublicRoutes'), 'PublicRoutes');
export const AppRoutes = () => {
const auth = useAuth();
return auth.user ? <ProtectedRoutes /> : <PublicRoutes />;
};
/**
* Defer loading of components & routes
* named imports for React.lazy: https://github.com/facebook/react/issues/14603#issuecomment-726551598
* @param factory - Component import resolver
* @param name - Name of import key
* @returns React component
* @example
* // Usage
* const { Home } = lazyImport(() => import("./Home"), "Home");
*/
export function lazyImport<
T extends React.ComponentType<any>,
I extends { [K2 in K]: T },
K extends keyof I
>(factory: () => Promise<I>, name: K): I {
return Object.create({
[name]: React.lazy(() => factory().then((module) => ({ default: module[name] }))),
})
}
Private Routes
// ProtectedRoutes.js
import { Navigate, Outlet, Route, Routes } from 'react-router-dom';
import { MainLayout } from '@/components/Layout';
import { DiscussionsRoutes } from '@/features/discussions';
import { Landing, Dashboard } from '@/features/misc';
import { Profile, Users } from '@/features/users';
const App = () => {
return (
<MainLayout>
<Outlet />
</MainLayout>
);
};
export const ProtectedRoutes = () => {
return (
<Routes>
<Route path="/app" element={<App />}>
<Route path="/discussions/*" element={<DiscussionsRoutes />} />
<Route path="/users/*" element={<Users />} />
<Route path="/profile" element={<Profile />} />
<Route path="/" element={<Dashboard />} />
<Route path="*" element={<Navigate to="/" />} />
</Route>
<Route path="/" element={<Landing />} />
</Routes>
);
};
// @/features/discussions DiscussionsRoutes
import { Route, Routes } from 'react-router-dom';
import { Discussion } from './Discussion';
import { Discussions } from './Discussions';
export const DiscussionsRoutes = () => {
return (
<Routes>
<Route path="" element={<Discussions />} />
<Route path=":discussionId" element={<Discussion />} />
</Routes>
);
};
Public Routes
// PublicRoutes.js
import { Navigate, Route, Routes } from 'react-router-dom';
import { AuthRoutes } from '@/features/auth';
import { Landing } from '@/features/misc';
export const PublicRoutes = () => {
return (
<Routes>
<Route path="/auth/*" element={<AuthRoutes />} />
<Route path="/" element={<Landing />} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
);
};
// features/auth Routes
import { Route, Routes } from 'react-router-dom';
import { Login } from './Login';
import { Register } from './Register';
export const AuthRoutes = () => {
return (
<Routes>
<Route path="register" element={<Register />} />
<Route path="login" element={<Login />} />
</Routes>
);
};