@bgscore/react-router
Version:
Automatic React Router generator for Vite with TypeScript support
266 lines (214 loc) ⢠7.68 kB
Markdown
Vite plugin to automatically generate React Router routes from folder structure.
- š File-based routing
- š§© Automatic layout nesting
- ā” HMR support
- š TypeScript support
```bash
npm install @bgscore/react-router
pnpm add @bgscore/react-router
```
Add this plugin to your Vite configuration (`vite.config.js` or `vite.config.ts`):
```javascript
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc"
import reactRouter from "@bgscore/react-router/plugin";
// https://vite.dev/config/
export default defineConfig({
plugins: [
react(),
reactRouter(),
],
})
```
### Folder Structure
This plugin will automatically generate routes based on your folder structure. Here is an example of a supported folder structure:
```
src/
āāā pages/
ā āāā _layout.tsx
ā āāā index.tsx
ā āāā about.tsx
ā āāā dashboard/
ā ā āāā _layout.tsx
ā ā āāā index.tsx
ā ā āāā settings.tsx
```
### Output
The plugin will generate a router configuration based on the folder structure. Here is an example of the generated router configuration:
```tsx
import { createBrowserRouter } from "react-router-dom";
import React, { lazy } from "react";
import Layout from "pages/_layout";
import DashboardLayout from "pages/dashboard/_layout";
const About = lazy(() => import("pages/about"));
const DashboardIndex = lazy(() => import("pages/dashboard/index"))
const DashboardSettings = lazy(() => import("pages/dashboard/settings"));
const Index = lazy(() => import("pages/index"));
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
children: [
{
path: "about",
element: <About />,
},
{
path: "dashboard",
element: <DashboardLayout />,
children: [
{
index: true,
element: <DashboardIndex />,
},
{
path: "settings",
element: <DashboardSettings />,
}
]
},
{
index: true,
element: <Index />,
}
]
}
]);
export default router;
```
Create a `src/main.tsx` file and add the following code to use the generated routes:
```tsx
import { createRoot } from "react-dom/client"
import { RouterProvider } from "react-router-dom";
import router from "src/shared/routes/bgs-router";
const App = () => (
<RouterProvider router={router} />
);
createRoot(document.getElementById("root")!).render(<App />)
```
You can customize this plugin with additional options. Here is an example configuration with additional options:
```javascript
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc"
import viteReactRoutes from "@bgscore/react-router";
// https://vite.dev/config/
export default defineConfig({
plugins: [
react(),
viteReactRoutes({
sourceDir: "src/pages",
outputDir: "src/shared/routes",
outputName: "bgs-router",
baseUrl: "pages",
layoutName: "_layout",
minify: true,
logging: true
}),
],
})
```
### Configuration Options
- **sourceDir**: The directory where your page components are located. Default: `"src/pages"`.
- **outputDir**: The directory where the generated router file will be saved. Default: `"src/shared/routes"`.
- **outputName**: The name of the generated router file. Default: `"bgs-router"`.
- **baseUrl**: The base URL for importing components. Default: `"pages"`.
- **layoutName**: The name of the layout file. Default: `"_layout"`.
- **minify**: Whether to minify the generated router file. Default: `true`.
- **logging**: Whether to enable logging. Default: `true`.
### Using `useRouter` Hook
You can use the `useRouter` hook to access router-related information and functions in your components. Here is an example:
```tsx
import useRouter, { Metadata } from "@bgscore/react-router"
const ErrorElement = () => <>Error Element</>
export const metadata: Metadata = {
title: "Home",
independent: true,
layout: true,
loader: () => {},
errorElement: <ErrorElement />
}
export default function Page() {
const router = useRouter()
console.log(router, "router-----")
return <>
Home
</>
}
```
- **push(url: To, options?: PushOptions): void**
- Navigates to a new URL.
- `url`: The URL to navigate to.
- `options`: Additional options for navigation.
- `query`: Query parameters to include in the URL.
- `preserveQuery`: Whether to preserve existing query parameters.
- `replaceSameName`: Whether to replace existing query parameters with the same name.
- **pathname: string**
- The current pathname.
- **query: Query**
- The current query parameters.
- **location: Location**
- The current location object.
- **history: NavigateFunction**
- The navigate function from `react-router-dom`.
- **goBack(defaultUrl: string): void**
- Navigates back to the previous page or to a default URL if there is no history.
- `defaultUrl`: The URL to navigate to if there is no history.
- **metadata: M**
- The metadata for the current route.
- **data: D**
- The data for the current route.
- **navigation: Navigation**
- The navigation state.
- **error: unknown**
- The error object for the current route.
- **loading: boolean**
- Whether the current route is loading.
The `metadata` object allows you to define additional information for your routes. Here are the properties you can use:
- **title**: The title of the page.
- **description**: The description of the page.
- **actionCode**: A custom action code for the page.
- **menuCode**: A custom menu code for the page.
- **independent**: Whether the route is independent of the layout. Default: `false`.
- **layout**: Whether to use the layout for the route. Default: `true`.
- **loader**: A function to load data for the route.
- **errorElement**: A React element to display in case of an error.
Here is an example of how to use the `metadata` object in your component:
```tsx
import useRouter, { Metadata } from "@bgscore/react-router/use-router"
const ErrorElement = () => <>Error Element</>
export const metadata: Metadata = {
title: "Home",
description: "This is the home page",
actionCode: "home_action",
menuCode: "home_menu",
independent: true,
layout: true,
loader: async () => {
// Load data for the route
return { data: "Sample data" }
},
errorElement: <ErrorElement />
}
export default function Page() {
const router = useRouter()
console.log(router, "router-----")
return <>
Home
</>
}
```
If you want to contribute to this project, please fork this repository and create a pull request with your changes.
This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for more information.