Installations
npm install react-router-config
Developer Guide
Typescript
No
Module System
CommonJS
Node Version
12.11.0
NPM Version
lerna/3.16.4/node@v12.11.0+x64 (linux)
Score
57.4
Supply Chain
97.6
Quality
79.4
Maintenance
100
Vulnerability
99.6
License
Releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (98.81%)
JavaScript (0.77%)
CSS (0.41%)
Developer
Download Statistics
Total Downloads
66,185,082
Last Day
44,620
Last Week
328,413
Last Month
1,447,621
Last Year
17,837,363
GitHub Statistics
53,573 Stars
9,239 Commits
10,373 Forks
806 Watching
33 Branches
1,001 Contributors
Bundle Size
1.13 kB
Minified
579.00 B
Minified + Gzipped
Package Meta Information
Latest Version
5.1.1
Package Id
react-router-config@5.1.1
Size
9.26 kB
NPM Version
lerna/3.16.4/node@v12.11.0+x64 (linux)
Node Version
12.11.0
Publised On
27 Sept 2019
Total Downloads
Cumulative downloads
Total Downloads
66,185,082
Last day
-31.6%
44,620
Compared to previous day
Last week
-9.3%
328,413
Compared to previous week
Last month
-5.3%
1,447,621
Compared to previous month
Last year
20.3%
17,837,363
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
1
Peer Dependencies
2
React Router Config
Static route configuration helpers for React Router.
This is alpha software, it needs:
- Realistic server rendering example with data preloading
- Pending navigation example
Installation
Using npm:
$ npm install --save react-router-config
Then with a module bundler like webpack, use as you would anything else:
1// using an ES6 transpiler, like babel 2import { matchRoutes, renderRoutes } from "react-router-config"; 3 4// not using an ES6 transpiler 5var matchRoutes = require("react-router-config").matchRoutes;
The UMD build is also available on unpkg:
1<script src="https://unpkg.com/react-router-config/umd/react-router-config.min.js"></script>
You can find the library on window.ReactRouterConfig
Motivation
With the introduction of React Router v4, there is no longer a centralized route configuration. There are some use-cases where it is valuable to know about all the app's potential routes such as:
- Loading data on the server or in the lifecycle before rendering the next screen
- Linking to routes by name
- Static analysis
This project seeks to define a shared format for others to build patterns on top of.
Route Configuration Shape
Routes are objects with the same properties as a <Route>
with a couple differences:
- the only render prop it accepts is
component
(norender
orchildren
) - introduces the
routes
key for sub routes - Consumers are free to add any additional props they'd like to a route, you can access
props.route
inside thecomponent
, this object is a reference to the object used to render and match. - accepts
key
prop to prevent remounting component when transition was made from route with the same component and samekey
prop
1const routes = [ 2 { 3 component: Root, 4 routes: [ 5 { 6 path: "/", 7 exact: true, 8 component: Home 9 }, 10 { 11 path: "/child/:id", 12 component: Child, 13 routes: [ 14 { 15 path: "/child/:id/grand-child", 16 component: GrandChild 17 } 18 ] 19 } 20 ] 21 } 22];
Note: Just like <Route>
, relative paths are not (yet) supported. When it is supported there, it will be supported here.
API
matchRoutes(routes, pathname)
Returns an array of matched routes.
Parameters
- routes - the route configuration
- pathname - the pathname component of the url. This must be a decoded string representing the path.
1import { matchRoutes } from "react-router-config"; 2const branch = matchRoutes(routes, "/child/23"); 3// using the routes shown earlier, this returns 4// [ 5// routes[0], 6// routes[0].routes[1] 7// ]
Each item in the array contains two properties: routes
and match
.
routes
: A reference to the routes array used to matchmatch
: The match object that also gets passed to<Route>
render methods.
1branch[0].match.url; 2branch[0].match.isExact; 3// etc.
You can use this branch of routes to figure out what is going to be rendered before it actually is rendered. You could do something like this on the server before rendering, or in a lifecycle hook of a component that wraps your entire app
1const loadBranchData = (location) => { 2 const branch = matchRoutes(routes, location.pathname) 3 4 const promises = branch.map(({ route, match }) => { 5 return route.loadData 6 ? route.loadData(match) 7 : Promise.resolve(null) 8 }) 9 10 return Promise.all(promises) 11} 12 13// useful on the server for preloading data 14loadBranchData(req.url).then(data => { 15 putTheDataSomewhereTheClientCanFindIt(data) 16}) 17 18// also useful on the client for "pending navigation" where you 19// load up all the data before rendering the next page when 20// the url changes 21 22// THIS IS JUST SOME THEORETICAL PSEUDO CODE :) 23class PendingNavDataLoader extends Component { 24 state = { 25 previousLocation: null, 26 currentLocation: this.props.location 27 } 28 29 static getDerivedStateFromProps(props, state) { 30 const currentLocation = props.location 31 const previousLocation = state.currentLocation 32 33 const navigated = currentLocation !== previousLocation 34 if (navigated) { 35 // save the location so we can render the old screen 36 return { 37 previousLocation, 38 currentLocation 39 } 40 } 41 42 return null 43 } 44 45 componentDidUpdate(prevProps) { 46 const navigated = prevProps.location !== this.props.location 47 48 if (navigated) { 49 // load data while the old screen remains 50 loadNextData(routes, this.props.location).then(data => { 51 putTheDataSomewhereRoutesCanFindIt(data) 52 // clear previousLocation so the next screen renders 53 this.setState({ 54 previousLocation: null 55 }) 56 }) 57 } 58 } 59 60 render() { 61 const { children, location } = this.props 62 const { previousLocation } = this.state 63 64 // use a controlled <Route> to trick all descendants into 65 // rendering the old location 66 return ( 67 <Route 68 location={previousLocation || location} 69 render={() => children} 70 /> 71 ) 72 } 73} 74 75// wrap in withRouter 76export default withRouter(PendingNavDataLoader) 77 78///////////// 79// somewhere at the top of your app 80import routes from './routes' 81 82<BrowserRouter> 83 <PendingNavDataLoader routes={routes}> 84 {renderRoutes(routes)} 85 </PendingNavDataLoader> 86</BrowserRouter>
Again, that's all pseudo-code. There are a lot of ways to do server rendering with data and pending navigation and we haven't settled on one. The point here is that matchRoutes
gives you a chance to match statically outside of the render lifecycle. We'd like to make a demo app of this approach eventually.
renderRoutes(routes, extraProps = {}, switchProps = {})
In order to ensure that matching outside of render with matchRoutes
and inside of render result in the same branch, you must use renderRoutes
instead of <Route>
inside your components. You can render a <Route>
still, but know that it will not be accounted for in matchRoutes
outside of render.
1import { renderRoutes } from "react-router-config"; 2 3const routes = [ 4 { 5 component: Root, 6 routes: [ 7 { 8 path: "/", 9 exact: true, 10 component: Home 11 }, 12 { 13 path: "/child/:id", 14 component: Child, 15 routes: [ 16 { 17 path: "/child/:id/grand-child", 18 component: GrandChild 19 } 20 ] 21 } 22 ] 23 } 24]; 25 26const Root = ({ route }) => ( 27 <div> 28 <h1>Root</h1> 29 {/* child routes won't render without this */} 30 {renderRoutes(route.routes)} 31 </div> 32); 33 34const Home = ({ route }) => ( 35 <div> 36 <h2>Home</h2> 37 </div> 38); 39 40const Child = ({ route }) => ( 41 <div> 42 <h2>Child</h2> 43 {/* child routes won't render without this */} 44 {renderRoutes(route.routes, { someProp: "these extra props are optional" })} 45 </div> 46); 47 48const GrandChild = ({ someProp }) => ( 49 <div> 50 <h3>Grand Child</h3> 51 <div>{someProp}</div> 52 </div> 53); 54 55ReactDOM.render( 56 <BrowserRouter> 57 {/* kick it all off with the root route */} 58 {renderRoutes(routes)} 59 </BrowserRouter>, 60 document.getElementById("root") 61);
No vulnerabilities found.
Reason
30 commit(s) and 16 issue activity found in the last 90 days -- score normalized to 10
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE.md:0
- Info: FSF or OSI recognized license: MIT License: LICENSE.md:0
Reason
Found 7/27 approved changesets -- score normalized to 2
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/deduplicate-lock-file.yml:1
- Warn: no topLevel permission defined: .github/workflows/format.yml:1
- Warn: no topLevel permission defined: .github/workflows/integration-full.yml:1
- Warn: no topLevel permission defined: .github/workflows/integration-pr-ubuntu.yml:1
- Warn: no topLevel permission defined: .github/workflows/integration-pr-windows-macos.yml:1
- Warn: no topLevel permission defined: .github/workflows/release-comments.yml:1
- Warn: no topLevel permission defined: .github/workflows/release-experimental.yml:1
- Warn: no topLevel permission defined: .github/workflows/release-nightly.yml:1
- Warn: no topLevel permission defined: .github/workflows/release.yml:1
- Warn: no topLevel permission defined: .github/workflows/shared-build.yml:1
- Warn: no topLevel permission defined: .github/workflows/shared-integration.yml:1
- Warn: no topLevel permission defined: .github/workflows/test.yml:1
- Info: no jobLevel write permissions found
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deduplicate-lock-file.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/deduplicate-lock-file.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/deduplicate-lock-file.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/deduplicate-lock-file.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/deduplicate-lock-file.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/deduplicate-lock-file.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/format.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/format.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/format.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/format.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/format.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/format.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/no-response.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/no-response.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-comments.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-comments.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-comments.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-comments.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-experimental.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-experimental.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-experimental.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-experimental.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-experimental.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-experimental.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-nightly.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-nightly.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-nightly.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-nightly.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-nightly.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release-nightly.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:74: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:77: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:80: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/shared-build.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-build.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/shared-build.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-build.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/shared-build.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-build.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/shared-build.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-build.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/shared-integration.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-integration.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/shared-integration.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-integration.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/shared-integration.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-integration.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/shared-integration.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/shared-integration.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/support.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/support.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/test.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/test.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/test.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/remix-run/react-router/test.yml/main?enable=pin
- Info: 0 out of 20 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 15 third-party GitHubAction dependencies pinned
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'main'
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 11 are checked with a SAST tool
Reason
26 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55
- Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-c24v-8rfc-w8vw
- Warn: Project is vulnerable to: GHSA-8jhw-289h-jh2g
- Warn: Project is vulnerable to: GHSA-64vr-g452-qvp3
- Warn: Project is vulnerable to: GHSA-9cwx-2883-4wfx
- Warn: Project is vulnerable to: GHSA-353f-5xf4-qw67
- Warn: Project is vulnerable to: GHSA-92r3-m2mg-pj97
- Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7
- Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc
- Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx
- Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j
- Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w
- Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg
- Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p
- Warn: Project is vulnerable to: GHSA-hpx4-r86g-5jrg
- Warn: Project is vulnerable to: GHSA-prr3-c3m5-p7q2
- Warn: Project is vulnerable to: GHSA-8hc4-vh64-cxmj
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
Score
3.6
/10
Last Scanned on 2024-12-23
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to react-router-config
@types/react-router-config
TypeScript definitions for react-router-config
gitee-router-react
React components for Router
@pixeloven/react-router-config
React Router configuration helpers and components
@react-router/remix-config-routes-adapter
Remix config route support for React Router