LWS Job Portal’s navigation is built on React Router v7’s Data API — the modernDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/iDevRanjan/lws-ra-b4-assignment-five/llms.txt
Use this file to discover all available pages before exploring further.
createBrowserRouter approach that co-locates data loading with route definitions. Every protected section of the app is guarded at the router layer rather than inside components, so a user who tampers with client-side state still hits a redirect before any protected page renders. An authMiddleware function runs before every route transition, rehydrating authentication context from the server so guards always have fresh, verified data.
Router Setup
The router is created withcreateBrowserRouter in src/routes/AppRoutes.jsx and exposed through a single <RouterProvider> in the AppRoutes component. The root route renders <MainLayout> (shared Header + Footer) and registers the middleware and hydration fallback at the top level.
Route Hierarchy
Auth Middleware
authMiddleware is a React Router v7 middleware function that runs before any route in the tree renders. It reads the pub-sub store, verifies the user’s session by fetching their profile via queryClient.ensureQueryData, and populates a context object that loaders can read downstream.
If the profile fetch fails (e.g., expired token, network error),
authMiddlewareData remains { isLoggedin: false }. This means the middleware gracefully degrades — a broken token results in an unauthenticated state rather than a crash.authContext key (createContext(null) in src/context/index.js) is how middleware data travels to loaders:
Route Guards
PublicRoutes — redirect authenticated users
PublicRoutes prevents already-logged-in users from accessing /login, /jobseeker-register, and /company-register. The publicLoader reads middleware context and passes it as loader data; the component renders <ExistingClient> when a session is already active.
RoleBasedRoute — enforce user role
RoleBasedRoute receives an allowedRole prop ("USER" or "COMPANY") and compares it against the role returned by the loader. Unauthenticated users are redirected to /login inside the loader itself — before the component even mounts.
Middleware runs first
authMiddleware fires before any loader, populates context with { isLoggedin, email, role }.roleBasedLoader checks authentication
If
isLoggedin is false, the loader throws redirect("/login") — the component tree is never rendered.Router Loaders
Router loaders insrc/services/routerLoaders.js use queryClient.ensureQueryData — React Query’s “fetch if not cached, otherwise return cached” primitive. This means navigating back to a page you’ve already visited is instant.
getJobBySlugLoader
getJobBySlugLoader
<JobDetails> renders. If the slug returns a 404, the thrown error activates <ErrorElement> inside the MainLayout.getCompanyBySlugLoader
getCompanyBySlugLoader
editJobLoader
editJobLoader
<CreateAndEditJob> reads jobData and isEditMode via useLoaderData() to pre-fill the form.getCompanyDashboardStatsLoader
getCompanyDashboardStatsLoader
context needed) because this loader only runs inside the COMPANY role-based group where authentication is already guaranteed.getApplicantProfileLoader
getApplicantProfileLoader
<ApplicantProfile> page renders.Error Handling
LWS Job Portal uses two complementary mechanisms to catch errors without breaking theMainLayout chrome.
errorElement: <ErrorElement />
A pathless route wrapping all page routes carries errorElement: <ErrorElement />. Whenever a loader throws or a component crashes inside this group, React Router renders <ErrorElement> in place of the failed subtree — the Header and Footer remain visible.
path: "*" catch-all
errorElement only activates when React Router has already matched a route and something goes wrong inside it. A completely unknown URL (e.g., /this-does-not-exist) never matches any child route, so the pathless error boundary is never entered. The catch-all route handles this case:
errorElement
Fires when a matched route’s loader throws or a component crashes at runtime. Renders inside
MainLayout with the full header and footer.path: *
Fires when no route matches the URL (404 navigation). Also renders
<ErrorElement> inside MainLayout, giving a consistent 404 page.hydrateFallbackElement
hydrateFallbackElement: <RootFallback /> is shown during the initial client hydration pass while the root loader (middleware) is still resolving. Once middleware completes, the fallback is replaced by the real page.