1/* eslint-disable react/display-name */
2/* eslint-disable react-hooks/rules-of-hooks */
3
4import React from 'react';
5import { useBasepath, useStaticInfo } from 'react-static';
6import { BrowserRouter, StaticRouter, withRouter } from 'react-router-dom';
7
8const Location = withRouter(({ children, location }) => children(location));
9
10const ReactRouterPlugin = ({ RouterProps: userRouterProps = {} }) => ({
11 Root:
12 PreviousRoot =>
13 ({ children }) => {
14 const routerProps = { basename: useBasepath() || '' };
15 if (routerProps.basename)
16 routerProps.basename = `/${routerProps.basename}`;
17 const staticInfo = useStaticInfo();
18
19 // Test for document to detect the node stage
20 let Router;
21 if (typeof document !== 'undefined') {
22 // NOTE: React Router is inconsistent in how it handles base paths
23 // This will need a trailing slash while the StaticRouter does not
24 if (routerProps.basename) routerProps.basename += '/';
25 // If in the browser, just use the browser router
26 Router = BrowserRouter;
27 } else {
28 Router = StaticRouter;
29 routerProps.location = staticInfo.path; // Required
30 routerProps.context = {}; // Required
31 }
32
33 return (
34 <PreviousRoot>
35 <Router {...routerProps} {...userRouterProps}>
36 {children}
37 </Router>
38 </PreviousRoot>
39 );
40 },
41 Routes: PreviousRoutes => props => (
42 <Location>
43 {location => <PreviousRoutes {...props} location={location} />}
44 </Location>
45 ),
46});
47
48export default ReactRouterPlugin;