Next.js with React Router v6 demo
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>
);
};