Building a Dynamic App Router in React with Vite and TypeScript
Learn how to implement file-based routing in React applications using Vite and TypeScript, inspired by Next.js routing system.
Building a Dynamic App Router in React with Vite and TypeScript
Introduction
In modern web development, routing is a fundamental feature for any single-page application (SPA). As projects grow, managing routes manually can become tedious and error-prone. To address this, I built a React application that automatically generates routes based on the files present in a specific directory. This approach streamlines the development process, making it easier to scale and maintain large React projects.
Motivation
Traditional React routing requires developers to manually import page components and define routes, which can quickly become cumbersome as the number of pages increases. Inspired by file-based routing systems in frameworks like Next.js and Remix, I wanted to bring a similar developer experience to a Vite-powered React app using TypeScript and React Router v7+.
The Idea
The core idea is simple: every file in the src/pages
directory automatically becomes a route in the application. The file name determines the route path, and the component exported from that file is rendered when the route is accessed. This eliminates the need for repetitive route declarations and makes adding new pages as easy as creating a new file.
Implementation
Stack
- React 19 for building the UI
- Vite for fast development and build tooling
- TypeScript for type safety
- React Router v7+ for routing
- ESLint for code quality
How It Works
-
Dynamic Importing: Using Vite's
import.meta.glob
, all.tsx
files in thesrc/pages
directory are dynamically imported. -
Route Generation: The file names are converted into route paths. For example,
home.tsx
becomes/
,about.tsx
becomes/about
, and so on. -
Automatic Registration: The app iterates over the imported modules and creates a
<Route>
for each, using React Router's<Routes>
and<BrowserRouter>
components. -
Adding Pages: To add a new route, simply create a new file in
src/pages
. No need to touch the routing logic.
Example
Suppose you have the following files in src/pages
:
home.tsx
→/
about.tsx
→/about
help.tsx
→/help
Each file exports a React component that is rendered at its respective route.
Code Snippet
const pages = import.meta.glob("./pages/*.tsx");
const loadRoutes = async () => {
const routeElements: JSX.Element[] = [];
for (const path in pages) {
const loader = pages[path];
const module = (await loader()) as { default: React.ComponentType };
let routePath = path
.replace("./pages/", "")
.replace(".tsx", "")
.toLowerCase();
if (routePath === "home") {
routePath = "/";
} else {
routePath = "/" + routePath;
}
routeElements.push(
<Route key={routePath} path={routePath} element={<module.default />} />
);
}
};
Benefits
- Scalability: Easily add or remove pages without modifying routing code.
- Maintainability: Reduces boilerplate and the risk of routing errors.
- Developer Experience: Inspired by modern frameworks, making onboarding and collaboration easier.
- Performance: Leveraging Vite's fast HMR and build process.
Conclusion
This project demonstrates how to implement a file-based dynamic router in a React app using Vite and TypeScript. It brings the convenience of automatic routing to standard React projects, making them easier to scale and maintain. If you're looking for a way to simplify your routing logic and improve your development workflow, consider adopting this approach in your next React project.