-
Notifications
You must be signed in to change notification settings - Fork 69
/
Copy pathRoutes.jsx
69 lines (61 loc) · 2.13 KB
/
Routes.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Routes as ReactRouterRoutes, Route } from "react-router-dom";
/**
* File-based routing.
* @desc File-based routing that uses React Router under the hood.
* To create a new route create a new .jsx file in `/pages` with a default export.
*
* Some examples:
* * `/pages/index.jsx` matches `/`
* * `/pages/blog/[id].jsx` matches `/blog/123`
* * `/pages/[...catchAll].jsx` matches any URL not explicitly matched
*
* @param {object} pages value of import.meta.glob(). See https://vitejs.dev/guide/features.html#glob-import
*
* @return {Routes} `<Routes/>` from React Router, with a `<Route/>` for each file in `pages`
*/
export default function Routes({ pages }) {
const routes = useRoutes(pages);
const routeComponents = routes.map(({ path, component: Component }) => (
<Route key={path} path={path} element={<Component />} />
));
const NotFound = routes.find(({ path }) => path === "/notFound").component;
return (
<ReactRouterRoutes>
{routeComponents}
<Route path="*" element={<NotFound />} />
</ReactRouterRoutes>
);
}
function useRoutes(pages) {
const routes = Object.keys(pages)
.map((key) => {
let path = key
.replace("./pages", "")
.replace(/\.(t|j)sx?$/, "")
/**
* Replace /index with /
*/
.replace(/\/index$/i, "/")
/**
* Only lowercase the first letter. This allows the developer to use camelCase
* dynamic paths while ensuring their standard routes are normalized to lowercase.
*/
.replace(/\b[A-Z]/, (firstLetter) => firstLetter.toLowerCase())
/**
* Convert /[handle].jsx and /[...handle].jsx to /:handle.jsx for react-router-dom
*/
.replace(/\[(?:[.]{3})?(\w+?)\]/g, (_match, param) => `:${param}`);
if (path.endsWith("/") && path !== "/") {
path = path.substring(0, path.length - 1);
}
if (!pages[key].default) {
console.warn(`${key} doesn't export a default React component`);
}
return {
path,
component: pages[key].default,
};
})
.filter((route) => route.component);
return routes;
}