vite-ssr
Version:
Vite utility for server side rendering
59 lines (58 loc) • 2.36 kB
JavaScript
import React from 'react';
import { useLocation, useParams } from 'react-router-dom';
import { getFullPath } from '../utils/route';
import { createUrl } from '../utils/route';
export function createRouter({ base, routes, initialState, PropsProvider, pagePropsOptions = { passToPage: true }, }) {
let currentRoute = undefined;
function augmentRoute(originalRoute) {
const meta = {
...(originalRoute.meta || {}),
state: null,
};
const augmentedRoute = {
...originalRoute,
meta,
component: (props) => {
const { pathname, hash, search } = useLocation();
const url = createUrl(pathname + search + hash);
const routeBase = base && base({ url });
const from = currentRoute;
const to = {
...augmentedRoute,
path: pathname,
hash,
search,
params: useParams(),
// @ts-ignore -- This should be in ES2019 ??
query: Object.fromEntries(url.searchParams),
fullPath: getFullPath(url, routeBase),
};
if (!currentRoute) {
// First route, use provided initialState
meta.state = initialState;
}
currentRoute = to;
if (PropsProvider) {
return React.createElement(PropsProvider, { ...props, from, to, pagePropsOptions }, originalRoute.component);
}
const { passToPage } = pagePropsOptions || {};
return React.createElement(originalRoute.component, {
...props,
...((passToPage && meta.state) || {}),
});
},
};
if (Array.isArray(originalRoute.routes)) {
augmentedRoute.routes = originalRoute.routes.map(augmentRoute);
// Nested routes compatibility with React Router 6
// @ts-ignore
augmentedRoute.children = augmentedRoute.routes;
}
return augmentedRoute;
}
return {
getCurrentRoute: () => currentRoute,
isFirstRoute: () => !currentRoute,
routes: routes.map(augmentRoute),
};
}