{"_id":"@curiosity26/redux-saga-router","_rev":"2-415313faf9ecc00edd911784d91bbd4a","name":"@curiosity26/redux-saga-router","dist-tags":{"latest":"2.3.4"},"versions":{"2.3.3":{"name":"@curiosity26/redux-saga-router","version":"2.3.3","description":"A router for Redux Saga","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","check":"npm run lint && npm test","clean":"rimraf lib","lint":"eslint src __tests__","prepublish":"npm run clean && npm run build","test":"jest","watch:test":"jest --watch"},"repository":{"type":"git","url":"git+https://github.com/curiosity26/redux-saga-router.git"},"keywords":["redux","redux-saga","saga","router","routing","history"],"authors":["Alex Boyce <curiosity26@gmail.com>","Jeremy Fairbank <elpapapollo@gmail.com> (http://jeremyfairbank.com)"],"license":"MIT","bugs":{"url":"https://github.com/curiosity26/redux-saga-router/issues"},"homepage":"https://github.com/curiosity26/redux-saga-router#readme","dependencies":{"fsm-iterator":"^1.1.0","history":"^4.10.1","ruta3":"^2.0.1"},"devDependencies":{"@babel/cli":"^7.8.4","@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-export-default-from":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.9.0","@babel/plugin-transform-async-to-generator":"^7.8.3","@babel/plugin-transform-runtime":"^7.9.0","@babel/polyfill":"^7.8.7","@babel/preset-env":"^7.9.0","@babel/preset-react":"^7.9.4","@babel/runtime":"^7.9.2","@types/jest":"^25.2.1","babel-eslint":"^7.0.0","babel-jest":"^26.0.1","babel-loader":"^8.1.0","eslint":"^4.19.1","eslint-config-airbnb":"^12.0.0","eslint-config-airbnb-base":"^8.0.0","eslint-import-resolver-node":"^0.2.3","eslint-plugin-import":"^1.16.0","eslint-plugin-jsx-a11y":"^2.2.2","eslint-plugin-react":"^6.3.0","express":"^4.14.0","jest":"^25.2.7","prop-types":"^15.7.2","react":"^16.13.1","react-dom":"^16.13.1","react-redux":"^7.2.0","react-router":"^5.1.2","redux":"^4.0.5","redux-saga":"^1.1.3","redux-saga-test-plan":"^4.0.0-rc.3","rimraf":"^3.0.2","webpack":"^4.42.1","webpack-dev-server":"^3.11.0"},"peerDependencies":{"redux-saga":">=1.1.3"},"gitHead":"0ce9b1cd2ceb8604d3bbf84afbc4b9831796b9d5","_id":"@curiosity26/redux-saga-router@2.3.3","_nodeVersion":"10.16.3","_npmVersion":"6.9.0","dist":{"integrity":"sha512-+ufdIRM0b3N3TczHw1DKh6CVRmMbYQNelPGtZCkzqE6BukgeE8lBe9dqSrLbXtD+b0FgBCBydF7PyZmXMG8tpw==","shasum":"caa8bb8438f7f95ced5a3c53bcddaa570521badc","tarball":"https://registry.npmjs.org/@curiosity26/redux-saga-router/-/redux-saga-router-2.3.3.tgz","fileCount":11,"unpackedSize":35809,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeugYgCRA9TVsSAnZWagAAZBwP/jPbLL5k4CKaDs9n7KKB\nsKVwWW47FHUjy8t3nJVrvKoXz4qdjjAV/ommUx/57+H6RTlred9LDcHwYjMW\noSabtkUt+MN4rCddox11t1+Htn0XeawPv8KJyHsBIFHMcy++cK9fikCqjc2C\n7SgoSDYAMHv2IBSBDxdbPEeuc8HLZSPU80CCGA/VXf6rDrq68TR4q8Ix0Yfl\nQiHNjvgLosMyN4RWM4Iim2PPlmaGk0eEZzOvwZ4Ilb2cj6FeQbLDLXsVY6gw\n73i1udVVZIFMIOeV76mkrnK/p/C0yHVvgAQaVRr0fHOBPTitPj1FmoYgBSN4\ntdPJH0yjf0NKmcPE72jxKgFZIIncH6f3fb5Mot9OqMkuDpmLluUGyMKqZvTn\nSC1Ack2tJWaphpgaX2Zgni6G7tDZEpbFPoquRGPiY2sN6nU+6T7ixtP0rGBl\nO77d/OnlEhrkkLQgsIM0bW2pFIZLQ6wPDN09e+Mf9QqJb3akPeBJ/6K+3+mV\n5hJO2YOHicxDFe6m7Ea0pyZsx7q/T9FZAgTWMZlIVN/ZRqdaFeIekgnad7o1\ncl3i4OHT9vs1m/sNvtypTCWZ0r8ULjOwDm4oT56yyEZ2dNNkaX3X/UTxGp3W\naG2VexFZL/shvSRYoHAOKZ7VXD6rwyEBHnhqQE+HD4eeZKVW/oSORE6v7c8Y\nJi5U\r\n=tfgg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFtJKtCQFyXFIhCCb1jyT8ud7zlBmx3p1LTXqvPo+jPYAiEA1vnzTHbmDwcWYjFpN/97mpW+p1RfTL4IlnpAmt7CeO8="}]},"maintainers":[{"name":"curiosity26","email":"curiosity26@gmail.com"}],"_npmUser":{"name":"curiosity26","email":"curiosity26@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/redux-saga-router_2.3.3_1589249568538_0.8413731553356052"},"_hasShrinkwrap":false},"2.3.4":{"name":"@curiosity26/redux-saga-router","version":"2.3.4","description":"A router for Redux Saga","main":"lib/index.js","scripts":{"build":"babel src --out-dir lib","check":"npm run lint && npm test","clean":"rimraf lib","lint":"eslint src __tests__","prepublish":"npm run clean && npm run build","test":"jest","watch:test":"jest --watch"},"repository":{"type":"git","url":"git+https://github.com/curiosity26/redux-saga-router.git"},"keywords":["redux","redux-saga","saga","router","routing","history"],"authors":["Alex Boyce <curiosity26@gmail.com>","Jeremy Fairbank <elpapapollo@gmail.com> (http://jeremyfairbank.com)"],"license":"MIT","bugs":{"url":"https://github.com/curiosity26/redux-saga-router/issues"},"homepage":"https://github.com/curiosity26/redux-saga-router#readme","dependencies":{"fsm-iterator":"^1.1.0","history":"^4.10.1","ruta3":"^2.0.1"},"devDependencies":{"@babel/cli":"^7.10.0","@babel/core":"^7.10.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-export-default-from":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.10.0","@babel/plugin-transform-async-to-generator":"^7.8.3","@babel/plugin-transform-runtime":"^7.10.0","@babel/polyfill":"^7.8.7","@babel/preset-env":"^7.10.0","@babel/preset-react":"^7.10.0","@babel/runtime":"^7.10.0","@redux-saga/core":"^1.1.3","@types/jest":"^25.2.3","babel-eslint":"^7.2.3","babel-jest":"^26.0.1","babel-loader":"^8.1.0","enzyme":"^3.11.0","enzyme-adapter-react-16":"^1.15.2","eslint":"^4.19.1","eslint-config-airbnb":"^12.0.0","eslint-config-airbnb-base":"^8.0.0","eslint-import-resolver-node":"^0.2.3","eslint-plugin-import":"^1.16.0","eslint-plugin-jsx-a11y":"^2.2.2","eslint-plugin-react":"^7.20.0","express":"^4.14.0","jest":"^26.0.1","prop-types":"^15.7.2","react":"^16.13.1","react-dom":"^16.13.1","react-redux":"^7.2.0","react-router":"^5.2.0","redux":"^4.0.5","redux-saga":"^1.1.3","redux-saga-test-plan":"^4.0.0-rc.3","rimraf":"^3.0.2","webpack":"^4.42.1","webpack-dev-server":"^3.11.0"},"peerDependencies":{"@redux-saga/core":">=1.1.3"},"jest":{"setupFilesAfterEnv":["<rootDir>/__tests__/setup.js"],"testRegex":"(/__tests__/.*\\.(test|spec))\\.jsx?$","collectCoverage":true},"gitHead":"77220f986e9bab4158f1ff2319a7e17e757e9b8e","_id":"@curiosity26/redux-saga-router@2.3.4","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-VPCThbnPHMK6oy3ZAMeVS/Y5aPuY3U2dXyNlVmv9aYWd526r2gccgDHKITTf+pCx5nxzae7Yb67TVdB9VlQV9w==","shasum":"c52a3e557aadad7822af3d126442bbdf5586a701","tarball":"https://registry.npmjs.org/@curiosity26/redux-saga-router/-/redux-saga-router-2.3.4.tgz","fileCount":11,"unpackedSize":31507,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezd1UCRA9TVsSAnZWagAAo8gQAI+SMt2ORVQMez8hWDcs\nT8Nv4LEMufW+wEjmqI+DVy+wuzYSY9GGdyPp9/zGkX7aSMOLxHoBgZOugTFS\nPDAOunLAu07aqvlQPPdoDYtzf9rD3aqngp+Boyj4qEV9K2cP1AYmHmmRvh0L\nhfXowHUNGd6L71zAWb893opojIXYA5/Wr6s9/xkGn8GkfkNAmevNRnPEGa90\n9WMniV0/pJPs4YgewUB8VNuRNppeJ5GHgcX90Hbdh7InS6NgeHUsxH9amyPp\nxbCov45XqfbuvVOwCPJv0K3+gR4ANufIP3PqjH8gihDj8+UbWRFDJSS0qIlP\nXrYwyFis0MgvL4HueaE3EBSlslkxV0jJBaFXmqdn7MUBfrl8hT/1Kq79w9ZF\nsMXsrgWSlOdX7G/MKKckZ36+8Idjsp3CRnmfbGXiazTeqM0b1HqI5gZC1FSs\nrukX3JqRJ1Vyg1vXpIPB2v0iZz3xFygRdpyHS8QLKIQS/IZlXg721aJLZTrO\nG3ZbXG/i/1cvS97oAAQMZhBuGNnNLNR4g3GYdQQ5uog3AuymBgCATXt7RzUC\nu07kZEphR0FxfktRnzLCvepXdm1VOULqLqyobvbQ83uv+YMXnlfxeur6z2TZ\na8CiVhE6RfGHxEc+5DoNGib5rR42sYZhgEJpD0AzXd0UJX1FrD62OW58FtVq\n1xxW\r\n=QhT6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDIQil9y+qMQbz/gbBjmwJR7z43BqtwfVYXtrIIaWgIawIgUR2QgDSiO4g+jtAgmo2cwN95muRRVZv+hBBWzK4CvvI="}]},"maintainers":[{"name":"curiosity26","email":"curiosity26@gmail.com"}],"_npmUser":{"name":"curiosity26","email":"curiosity26@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/redux-saga-router_2.3.4_1590549843587_0.004026272694092281"},"_hasShrinkwrap":false}},"time":{"created":"2020-05-12T02:12:48.505Z","2.3.3":"2020-05-12T02:12:48.668Z","modified":"2022-04-05T02:18:58.740Z","2.3.4":"2020-05-27T03:24:03.739Z"},"maintainers":[{"name":"curiosity26","email":"curiosity26@gmail.com"}],"description":"A router for Redux Saga","homepage":"https://github.com/curiosity26/redux-saga-router#readme","keywords":["redux","redux-saga","saga","router","routing","history"],"repository":{"type":"git","url":"git+https://github.com/curiosity26/redux-saga-router.git"},"bugs":{"url":"https://github.com/curiosity26/redux-saga-router/issues"},"license":"MIT","readme":"# Redux Saga Router\n\n![Node.js CI](https://github.com/curiosity26/redux-saga-router/workflows/Node.js%20CI/badge.svg)\n\n#### A router for Redux Saga\n\nRedux Saga Router gives you a saga for handling clientside routes in your Redux\nSaga application. This affords you a perfect way to manage side effects or\ndispatch Redux actions in response to route changes.\n\n## Table of Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [Behavior](#behavior)\n- [Routes](#routes)\n- [Options](#options)\n- [Navigation](#navigation)\n  - [Hash History](#hash-history)\n  - [Browser History](#browser-history)\n  - [Browser History with React](#browser-history-with-react)\n  - [React Router](#react-router)\n\n## Install\n\nYarn or npm.\n\n```sh\nyarn add @curiosity26/redux-saga-router\n```\n\n```sh\nnpm install --save @curiosity26/redux-saga-router\n```\n\n## Usage\n\nRedux Saga Router comes equipped with a `router` saga and two history\nstrategies, `createBrowserHistory` and `createHashHistory`.\n\nThe `router` saga expects a history object and a routes object with key-value\npairs of route paths to other sagas. It also takes an optional third argument with\n[additional options](#options).\n\nTo create a history object, you can use `createBrowserHistory` or\n`createHashHistory`. `createBrowserHistory` uses HTML5 `pushState` while\n`createHashHistory` uses (you guessed it) hashes, which is perfect for older\nbrowsers. These two history creation functions in fact come from the\n[history](https://github.com/mjackson/history) library.\n\n```js\nimport { call, fork, put } from 'redux-saga';\nimport { router, createBrowserHistory } from 'redux-saga-router';\n\nconst history = createBrowserHistory();\n\nconst routes = {\n  '/users': function* usersSaga() {\n    const users = yield call(fetchUsers);\n    yield put(setUsers(users));\n  },\n\n  '/users/:id': function* userSaga({ id }) {\n    const user = yield call(fetchUser, id);\n    yield put(setCurrentUser(user));\n  },\n};\n\nfunction* mainSaga() {\n  const data = yield call(fetchInitialData);\n\n  yield put(ready(data));\n\n  // The recommended way is to `fork` the router, but you can delegate with\n  // yield* too\n  yield fork(router, history, routes);\n}\n```\n\n## Behavior\n\nRedux Saga Router will `spawn` the **first** matching route saga. When the location\nchanges, the current running saga will be cancelled. As such, you might want to\n[clean up](https://redux-saga.js.org/docs/advanced/TaskCancellation.html)\nyour saga in that event.\n\nIf you wish to avoid your saga's being cancelled, you can `spawn` a sub saga in\nyour route saga like the following:\n\n```js\nconst routes = {\n  '/': function* homeSaga() {\n    yield spawn(subSaga);\n  },\n};\n```\n\nIn the event of an unhandled error occurring in one of your sagas, the error\nwill stop the running saga and will not propagate to the router. That means that\nyour application will continue to function when you hit other routes. That also\nmeans you should ensure you handle any potential errors that could occur in your\nroute sagas.\n\n## Routes\n\nRoutes may be expressed as either an object or an array with the main difference \nbeing that the array form preserves order and, therefore, the precedence of\nroutes.\n\n```js\nconst objectFormRoutes = {\n  '/foo': fooHandler,\n  '/bar': barHandler,\n};\n\nconst arrayFormRoutes = [\n  { pattern: '/foo', handler: fooHandler },\n  { pattern: '/bar', handler: barHandler },\n];\n```\n\n### Exact Matching\n\nThis route will only match `/foo` exactly.\n\n```js\nconst routes = {\n  '/foo': saga,\n};\n```\n\n### Path Parameters\n\nYou can capture dynamic path parameters by prepending them with the `:` symbol.\nThe name you use will be assigned to a property of the same name on a parameters\nobject that is passed into your route saga.\n\n```js\nconst routes = {\n  // Capture the user id with `:id` into an `id` property of the parameters\n  // object that is passed into `userSaga`.\n  '/users/:id': function* userSaga({ id }) {\n    const user = yield call(fetchUser, id);\n    yield put(setCurrentUser(user));\n  },\n\n  // You can capture multiple dynamic path parameters too.\n  '/dogs/:id/friends/:friendId': function* dogSaga({ id, friendId }) {\n    // ...\n  },\n};\n```\n\nIf you specify a dynamic path parameter, then it will be required. This route\nwill match `/bar/42` but NOT `/bar`.\n\n```js\nconst routes = {\n  '/bar/:id': saga,\n};\n```\n\n### Optional Named Parameters\n\nHowever, you can make a path parameter optional, by ending it with `?`.\n\nThis route will match `/bar/42` AND `/bar`.\n\n```js\nconst routes = {\n  '/bar/:id?': saga,\n};\n```\n\nUsing a `period` before an optional parameter can be optional too.\n\nThis route will match `/bar/LICENSE` and `/bar/README.md`.\n\n```js\nconst routes = {\n  '/bar/:fname.:ext?': saga,\n};\n```\n\n### Wildcard\n\nYou can use `*` as a wildcard to match many routes.\n\nThis route would match `/bar` and `/bar/baz/foo`.\n\n```js\nconst routes = {\n  '/bar/*': saga,\n};\n```\n\n### Route Precedence\n\nSometimes you want some routes to take precedence over others. For example,\nconsider a `/users/invite` route and a `/users/:id` route. JavaScript objects\ndon't guarantee order, so the `/users/:id` route could take precedence and match\n`/users/invite`. So, the `newUser` handler would never run.\n\n```js\n// Can't guarantee precedence with an object\nconst routes = {\n  '/users/invite': inviteUser,\n  '/users/:id': newUser,\n};\n```\n\nTo fix this problem, you can define routes with an array of route objects like\nso.\n\n```js\nconst routes = [\n  { pattern: '/users/invite', handler: inviteUser },\n  { pattern: '/users/:id', handler: newUser },\n];\n```\n\nThe array form will register routes in the order you provide, ensuring\nprecedence.\n\n## Options\n\nAs mentioned earlier, the `router` saga may also take a third argument, an\noptional `options` object, which allows you to specify additional behaviour as\ndescribed below:\n\nKey                 | Description\n--------------------|--------------------------------------------------------\n`matchAll`          | If set to `true`, it allows all matching routes to run instead of the first matching route.\n`beforeRouteChange` | Set to a saga to run any time location changes. This is useful for dispatching a cleanup action before route changes.\n\n\n```js\nconst options = {\n  matchAll: true,\n\n  *beforeRouteChange() {\n    yield put(clearNotifications());\n  },\n};\n\nfunction* mainSaga() {\n  yield fork(router, history, routes, options);\n}\n```\n\n## Navigation\n\n### Hash History\nIf you use hash history, then navigation will work right out of the box.\n\n```js\nimport { router, createHashHistory } from 'redux-saga-router';\n\nconst history = createHashHistory();\n\nconst routes = {\n  // ...\n};\n\nfunction* mainSaga() {\n  const data = yield call(fetchInitialData);\n\n  yield put(ready(data));\n\n  yield fork(router, history, routes);\n}\n```\n\n```html\n<nav>\n  <ul>\n    <li><a href=\"#/users\">Users</a></li>\n    <li><a href=\"#/users/1\">A Specific User</a></li>\n  </ul>\n</nav>\n```\n\n### Browser History\n\nBrowser history depends on `pushState` changes, so you'll need a method for\nmaking anchor tags change history state instead of actually exhibiting their\ndefault behavior. Also, if you're building a single-page application, your\nserver will need to support your client side routes to ensure your app loads\nproperly.\n\n```js\nimport { router, createBrowserHistory } from 'redux-saga-router';\n\nconst history = createBrowserHistory();\n\n// This is a naive example, so you might want something more robust\ndocument.addEventListener('click', (e) => {\n  const el = e.target;\n\n  if (el.tagName === 'A') {\n    e.preventDefault();\n    history.push(el.pathname);\n  }\n});\n\nconst routes = {\n  // ...\n};\n\nfunction* mainSaga() {\n  // ...\n}\n```\n\n### Browser History with React\n\nIf you're using React in your application, then Redux Saga Router does export a\nhigher-order component (HOC) that allows you to abstract away dealing with\n`pushState` manually. You can import the `createLink` HOC from\n`redux-saga-router/react` to create a `Link` component similar to what's\navailable in React Router. Just pass in your `history` object to the\n`createLink` function to create the `Link` component. You'll probably want a\nseparate file in your application for exporting your `history` object and your\n`Link` component.\n\nIf you are also using React Router, you can use the `Link` component that is shipped with React Router.\n\n```js\n// history.js\n\nimport { createLink } from 'redux-saga-router/react'\n\n// Without React Router v4:\nimport { createBrowserHistory } from 'redux-saga-router';\n\n// With the history npm package:\nimport createBrowserHistory from 'history/createBrowserHistory';\n\nconst history = createBrowserHistory();\n\nexport const Link = createLink(history);\nexport { history };\n```\n\n```js\n// saga.js\n\nimport { router } from 'redux-saga-router';\nimport { history } from './history';\n\nconst routes = {\n  // ...\n};\n\nfunction* mainSaga() {\n  const data = yield call(fetchInitialData);\n\n  yield put(ready(data));\n\n  yield fork(router, history, routes);\n}\n```\n\n```jsx\n// App.js\n\nimport React from 'react';\nimport { Link } from './history';\n\nexport default function App() {\n  return (\n    <nav>\n      <ul>\n        <li><Link to=\"/users\">Users</Link></li>\n        <li><Link to=\"/users/1\">A Specific User</Link></li>\n      </ul>\n    </nav>\n  );\n}\n```\n\n### React Router\n\nRedux Saga Router can also work in tandem with React Router (v2, v3, and v4)! Instead of\nusing one of Redux Saga Router's history creation functions, just use your\nhistory object from React Router (v2, v3) or use the history creation functions provided by the history npm package (v4).\n\n```js\n// saga.js\n\nimport { router } from 'redux-saga-router';\n\n// React Router v2 and v3:\nimport { browserHistory as history } from 'react-router';\n\n// React Router v4:\nimport createBrowserHistory from 'history/createBrowserHistory';\nconst history = createBrowserHistory();\n\nconst routes = {\n  // ...\n};\n\nexport default function* mainSaga() {\n  const data = yield call(fetchInitialData);\n\n  yield put(ready(data));\n\n  yield fork(router, history, routes);\n}\n```\n\n```jsx\n// App.js\n\nimport React from 'react';\nimport { Link } from 'react-router';\n\nexport default function App({ children }) {\n  return (\n    <div>\n      <nav>\n        <ul>\n          <li><Link to=\"/users\">Users</Link></li>\n          <li><Link to=\"/users/1\">A Specific User</Link></li>\n        </ul>\n      </nav>\n\n      <div>\n        {children}\n      </div>\n    </div>\n  );\n}\n```\n\n```jsx\nimport React from 'react';\nimport { render } from 'react-dom';\nimport { applyMiddleware, createStore } from 'redux';\nimport createSagaMiddleware from 'redux-saga';\nimport App from './App';\nimport Users from './Users';\nimport User from './User';\nimport mainSaga from './saga';\n\n// React Router v2 and v3:\nimport { Router, Route, browserHistory as history } from 'react-router';\n\n// React Router v4:\nimport createBrowserHistory from 'history/createBrowserHistory';\nimport { Router, Route } from 'react-router';\nconst history = createBrowserHistory();\n\nfunction reducer() {\n  return {};\n}\n\nconst sagaMiddleware = createSagaMiddleware();\nconst store = createStore(reducer, applyMiddleware(sagaMiddleware));\n\nsagaMiddleware.run(mainSaga);\n\nrender((\n  <Router history={history}>\n    <Route path=\"/\" component={App}>\n      <Route path=\"/users\" component={Users} />\n      <Route path=\"/users/:id\" component={User} />\n    </Route>\n  </Router>\n), document.getElementById('main'));\n```\n","readmeFilename":"README.md"}