{"id":24355196,"url":"https://github.com/moxystudio/next-router-scroll","last_synced_at":"2025-04-10T01:09:16.309Z","repository":{"id":38425393,"uuid":"265211133","full_name":"moxystudio/next-router-scroll","owner":"moxystudio","description":"Take control of when scroll is updated and restored in your Next.js projects.","archived":false,"fork":false,"pushed_at":"2023-03-06T20:47:39.000Z","size":3871,"stargazers_count":104,"open_issues_count":11,"forks_count":11,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-10T01:08:52.802Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moxystudio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-05-19T10:02:19.000Z","updated_at":"2025-03-28T18:54:46.000Z","dependencies_parsed_at":"2023-07-18T03:16:18.065Z","dependency_job_id":null,"html_url":"https://github.com/moxystudio/next-router-scroll","commit_stats":{"total_commits":32,"total_committers":6,"mean_commits":5.333333333333333,"dds":0.1875,"last_synced_commit":"6a3d3355145d29c2ae4dfda7d831713a43438dec"},"previous_names":["moxystudio/next-scroll-behavior"],"tags_count":10,"template":false,"template_full_name":"moxystudio/react-lib-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnext-router-scroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnext-router-scroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnext-router-scroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnext-router-scroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moxystudio","download_url":"https://codeload.github.com/moxystudio/next-router-scroll/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137886,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-18T17:29:31.072Z","updated_at":"2025-04-10T01:09:16.282Z","avatar_url":"https://github.com/moxystudio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# next-router-scroll\n\n[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][build-status-image]][build-status-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url]\n\n[npm-url]:https://npmjs.org/package/@moxy/next-router-scroll\n[downloads-image]:https://img.shields.io/npm/dm/@moxy/next-router-scroll.svg\n[npm-image]:https://img.shields.io/npm/v/@moxy/next-router-scroll.svg\n[build-status-url]:https://github.com/moxystudio/next-router-scroll/actions\n[build-status-image]:https://img.shields.io/github/workflow/status/moxystudio/next-router-scroll/Node%20CI/master\n[codecov-url]:https://codecov.io/gh/moxystudio/next-router-scroll\n[codecov-image]:https://img.shields.io/codecov/c/github/moxystudio/next-router-scroll/master.svg\n[david-dm-url]:https://david-dm.org/moxystudio/next-router-scroll\n[david-dm-image]:https://img.shields.io/david/moxystudio/next-router-scroll.svg\n[david-dm-dev-url]:https://david-dm.org/moxystudio/next-router-scroll?type=dev\n[david-dm-dev-image]:https://img.shields.io/david/dev/moxystudio/next-router-scroll.svg\n\nTake control of when scroll is updated and restored in your Next.js projects.\n\n## Installation\n\n```sh\n$ npm install @moxy/next-router-scroll\n```\n\nThis library is written in modern JavaScript and is published in both CommonJS and ES module transpiled variants. If you target older browsers please make sure to transpile accordingly.\n\n## Motivation\n\nThere are some cases where you need to take control on how your application scroll is handled; namely, you may want to restore scroll when user is navigating within your application pages, but you need to do extra work before or after the page has changed, either by using some sort of page transition or any other feature.\n\n`@moxy/next-router-scroll` makes it easy to update the window scroll position just like a browser would, but programmatically.\n\nThis package is built on top of [scroll-behavior](https://www.npmjs.com/package/scroll-behavior) and it's meant to be used in [Next.js](https://nextjs.org/) applications. It actively listens to Next.js router events, writing the scroll values associated with the current `location` in the `Session Storage` and reading these values whenever `updateScroll()` is called.\n\n## Usage\n\nFirst install the provider in your app:\n\n```js\n// pages/_app.js\nimport { RouterScrollProvider } from '@moxy/next-router-scroll';\n\nconst App = ({ Component, pageProps }) =\u003e (\n    \u003cRouterScrollProvider\u003e\n        \u003cComponent { ...pageProps } /\u003e\n    \u003c/RouterScrollProvider\u003e\n);\n\nexport default App;\n```\n\nThen use the hook or HOC to update the scroll whenever you see fit.\n\n```js\n// pages/index.js\nimport { useRouterScroll } from '@moxy/next-router-scroll';\n\nconst Home = () =\u003e {\n    const { updateScroll } = useRouterScroll();\n\n    useEffect(() =\u003e {\n        updateScroll();\n    }, []);\n};\n\nexport default Home;\n```\n\n\u003e ⚠️ By default, `\u003cRouterScrollProvider /\u003e` monkey patches Next.js `\u003cLink /\u003e` component, changing the `scroll` prop default value to `false`. You can disable this behavior by setting the `disableNextLinkScroll` prop to `false`.\n\n## API\n\n### \u0026lt;RouterScrollProvider /\u0026gt;\n\nA provider that should be used in your app component.\n\n#### shouldUpdateScroll?\n\nType: `function`\n\nA function to determine if scroll should be updated or not.\n\n```js\n// pages/_app.js\nimport { RouterScrollProvider } from '@moxy/next-router-scroll';\n\nconst App = ({ Component, pageProps }) =\u003e {\n    const shouldUpdateScroll = useMemo((prevContext, context) =\u003e {\n        // Both arguments have the following shape:\n        // {\n        //     location,\n        //     router: { pathname, asPath, query }\n        // }\n    }, []);\n\n    return (\n        \u003cRouterScrollProvider shouldUpdateScroll={ shouldUpdateScroll }\u003e\n            \u003cComponent { ...pageProps } /\u003e\n        \u003c/RouterScrollProvider\u003e\n    );\n};\n\nexport default App;\n```\n\nCheck [custom scroll behavior](https://github.com/taion/scroll-behavior#custom-scroll-behavior) for more information.\n\n\u003e ⚠️ Please note that `prevContext` might be null on the first run.\n\n#### disableNextLinkScroll?\n\nType: `boolean`   \nDefault: true\n\nTrue to set Next.js Link default `scroll` property to `false`, false otherwise. Since the goal of this package is to manually control the scroll, you don't want Next.js default behavior of scrolling to top when clicking links.\n\n#### children\n\nType: `ReactNode`\n\nAny React node to render.\n\n### useRouterScroll()\n\nA hook that returns an object with the following shape:\n\n```js\n{\n    updateScroll(prevContext?, context?),\n    registerElement(key, element, shouldUpdateScroll?, context?),\n    unregisterElement(key)\n}\n```\n\n#### updateScroll(prevContext?, context?)\n\nCall `updateScroll` function whenever you want to update the scroll. You may optionally pass `prevContext` and `context` objects which will be available inside [`shouldUpdateScroll`](#shouldupdatescroll).\n\nPlease note that `prevContext` and `context` have default values and any values you pass will be mixed with the default ones.\n\n**Use With Async Rendering**:\n\nIf you're asyncronously loading DOM elements and need to wait for an element you can utilize [React's approach for measuring DOM nodes](https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node). Here is an example of what that could look like:\n\n```js\nconst MyComponent = () =\u003e {\n    const { updateScroll } = useRouterScroll();\n    const divRef = useCallback((node) =\u003e {\n        if (node) {\n            updateScroll();\n        }\n    }, [updateScroll]);\n\n\n    return someCondition ? \u003cdiv ref={ divRef }\u003ehi\u003c/div\u003e : null;\n};\n```\n\n#### registerElement(key, element, shouldUpdateScroll?, context?)\n\nCall `registerElement` method to register an element other than window to have managed scroll behavior. Each of these elements needs to be given a unique key at registration time, and can be given an optional `shouldUpdateScroll` callback that behaves as above. This method can optionally be called with the current context if applicable, to set up the element's initial scroll position.\n\n#### unregisterElement(key)\n\nCall `unregisterElement` to unregister a previously registered element, identified by `key`.\n\n### withRouterScroll(Component)\n\nA HOC that injects a `routerScroll` prop, with the same value as the hook variant.\n\n```js\nimport { withRouterScroll } from '@moxy/next-router-scroll';\n\nconst MyComponent = ({ routerScroll }) =\u003e {\n    // ...\n};\n\nexport default withRouterScroll(MyComponent);\n```\n\n## Tests\n\n```sh\n$ npm test\n$ npm test -- --watch # during development\n```\n\n## Demo\n\nA demo project is available in the [`/demo`](./demo) folder so you can try out this component.\n\nFirst, build the `next-router-scroll` project with:\n\n```sh\n$ npm run build\n```\n\n*Note: Every time a change is made to the package a rebuild is required to reflect those changes on the demo. While developing, it may be a good idea to run the `dev` script, so you won't need to manually run the build after every change*\n\n```sh\n$ npm run dev\n```\n\nTo run the demo, do the following inside the demo's folder:\n\n```sh\n$ npm i\n$ npm run dev\n```\n\n## License\n\nReleased under the [MIT License](https://www.opensource.org/licenses/mit-license.php).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxystudio%2Fnext-router-scroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoxystudio%2Fnext-router-scroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxystudio%2Fnext-router-scroll/lists"}