{ "manifest": { "name": "@remix-run/router", "version": "1.21.1", "description": "Nested/Data-driven/Framework-agnostic Routing", "keywords": [ "remix", "router", "location" ], "repository": { "type": "git", "url": "https://github.com/remix-run/react-router", "directory": "packages/router" }, "license": "MIT", "author": { "name": "Remix Software", "email": "hello@remix.run" }, "sideEffects": false, "main": "./dist/router.cjs.js", "unpkg": "./dist/router.umd.min.js", "module": "./dist/router.js", "types": "./dist/index.d.ts", "files": [ "dist/", "*.ts", "CHANGELOG.md" ], "engines": { "node": ">=14.0.0" }, "publishConfig": { "access": "public" }, "_registry": "npm", "_loc": "/home/josie/.cache/yarn/v6/npm-@remix-run-router-1.21.1-bf15274d3856c395402719fa6b1dc8cc5245aaf7-integrity/node_modules/@remix-run/router/package.json", "readmeFilename": "README.md", "readme": "# Remix Router\n\nThe `@remix-run/router` package is a framework-agnostic routing package (sometimes referred to as a browser-emulator) that serves as the heart of [React Router][react-router] and [Remix][remix] and provides all the core functionality for routing coupled with data loading and data mutations. It comes with built-in handling of errors, race-conditions, interruptions, cancellations, lazy-loading data, and much, much more.\n\nIf you're using React Router, you should never `import` anything directly from the `@remix-run/router` - you should have everything you need in `react-router-dom` (or `react-router`/`react-router-native` if you're not rendering in the browser). All of those packages should re-export everything you would otherwise need from `@remix-run/router`.\n\n> [!WARNING]\n>\n> This router is a low-level package intended to be consumed by UI layer routing libraries. You should very likely not be using this package directly unless you are authoring a routing library such as [`react-router-dom`][react-router-repo] or one of it's other [UI ports][remix-routers-repo].\n\n## API\n\nA Router instance can be created using `createRouter`:\n\n```js\n// Create and initialize a router. \"initialize\" contains all side effects\n// including history listeners and kicking off the initial data fetch\nlet router = createRouter({\n // Required properties\n routes: [{\n path: '/',\n loader: ({ request, params }) => { /* ... */ },\n children: [{\n path: 'home',\n loader: ({ request, params }) => { /* ... */ },\n }]\n },\n history: createBrowserHistory(),\n\n // Optional properties\n basename, // Base path\n mapRouteProperties, // Map framework-agnostic routes to framework-aware routes\n future, // Future flags\n hydrationData, // Hydration data if using server-side-rendering\n}).initialize();\n```\n\nInternally, the Router represents the state in an object of the following format, which is available through `router.state`. You can also register a subscriber of the signature `(state: RouterState) => void` to execute when the state updates via `router.subscribe()`;\n\n```ts\ninterface RouterState {\n // False during the initial data load, true once we have our initial data\n initialized: boolean;\n // The `history` action of the most recently completed navigation\n historyAction: Action;\n // The current location of the router. During a navigation this reflects\n // the \"old\" location and is updated upon completion of the navigation\n location: Location;\n // The current set of route matches\n matches: DataRouteMatch[];\n // The state of the current navigation\n navigation: Navigation;\n // The state of any in-progress router.revalidate() calls\n revalidation: RevalidationState;\n // Data from the loaders for the current matches\n loaderData: RouteData;\n // Data from the action for the current matches\n actionData: RouteData | null;\n // Errors thrown from loaders/actions for the current matches\n errors: RouteData | null;\n // Map of all active fetchers\n fetchers: Map;\n // Scroll position to restore to for the active Location, false if we\n // should not restore, or null if we don't have a saved position\n // Note: must be enabled via router.enableScrollRestoration()\n restoreScrollPosition: number | false | null;\n // Proxied `preventScrollReset` value passed to router.navigate()\n preventScrollReset: boolean;\n}\n```\n\n### Navigations\n\nAll navigations are done through the `router.navigate` API which is overloaded to support different types of navigations:\n\n```js\n// Link navigation (pushes onto the history stack by default)\nrouter.navigate(\"/page\");\n\n// Link navigation (replacing the history stack)\nrouter.navigate(\"/page\", { replace: true });\n\n// Pop navigation (moving backward/forward in the history stack)\nrouter.navigate(-1);\n\n// Form submission navigation\nlet formData = new FormData();\nformData.append(key, value);\nrouter.navigate(\"/page\", {\n formMethod: \"post\",\n formData,\n});\n\n// Relative routing from a source routeId\nrouter.navigate(\"../../somewhere\", {\n fromRouteId: \"active-route-id\",\n});\n```\n\n### Fetchers\n\nFetchers are a mechanism to call loaders/actions without triggering a navigation, and are done through the `router.fetch()` API. All fetch calls require a unique key to identify the fetcher.\n\n```js\n// Execute the loader for /page\nrouter.fetch(\"key\", \"/page\");\n\n// Submit to the action for /page\nlet formData = new FormData();\nformData.append(key, value);\nrouter.fetch(\"key\", \"/page\", {\n formMethod: \"post\",\n formData,\n});\n```\n\n### Revalidation\n\nBy default, active loaders will revalidate after any navigation or fetcher mutation. If you need to kick off a revalidation for other use-cases, you can use `router.revalidate()` to re-execute all active loaders.\n\n### Future Flags\n\nWe use _Future Flags_ in the router to help us introduce breaking changes in an opt-in fashion ahead of major releases. Please check out the [blog post][future-flags-post] and [React Router Docs][api-development-strategy] for more information on this process. The currently available future flags in `@remix-run/router` are:\n\n| Flag | Description |\n| ------------------------ | ------------------------------------------------------------------------- |\n| `v7_normalizeFormMethod` | Normalize `useNavigation().formMethod` to be an uppercase HTTP Method |\n| `v7_prependBasename` | Prepend the `basename` to incoming `router.navigate`/`router.fetch` paths |\n\n[react-router]: https://reactrouter.com\n[remix]: https://remix.run\n[react-router-repo]: https://github.com/remix-run/react-router\n[remix-routers-repo]: https://github.com/brophdawg11/remix-routers\n[api-development-strategy]: https://reactrouter.com/v6/guides/api-development-strategy\n[future-flags-post]: https://remix.run/blog/future-flags\n", "licenseText": "MIT License\n\nCopyright (c) React Training LLC 2015-2019\nCopyright (c) Remix Software Inc. 2020-2021\nCopyright (c) Shopify Inc. 2022-2023\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, "artifacts": [], "remote": { "resolved": "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.1.tgz#bf15274d3856c395402719fa6b1dc8cc5245aaf7", "type": "tarball", "reference": "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.1.tgz", "hash": "bf15274d3856c395402719fa6b1dc8cc5245aaf7", "integrity": "sha512-KeBYSwohb8g4/wCcnksvKTYlg69O62sQeLynn2YE+5z7JWEj95if27kclW9QqbrlsQ2DINI8fjbV3zyuKfwjKg==", "registry": "npm", "packageName": "@remix-run/router", "cacheIntegrity": "sha512-KeBYSwohb8g4/wCcnksvKTYlg69O62sQeLynn2YE+5z7JWEj95if27kclW9QqbrlsQ2DINI8fjbV3zyuKfwjKg== sha1-vxUnTThWw5VAJxn6ax3IzFJFqvc=" }, "registry": "npm", "hash": "bf15274d3856c395402719fa6b1dc8cc5245aaf7" }