next-batch-router v1.0.0
next-batch-router
An alternative to useRouter hook in next/router that batches push and replace calls.
It allows for multiple push without overwriting each other.
Why do I need it?
With next/router, the code below doesn't work.
We expect query string to result in ?a=1&b=2, but it results in ?a=1 or ?b=2
const router = useRouter();
const onClick = () => {
router.push({ query: { ...router.query, a: 1 } });
router.push({ query: { ...router.query, b: 2 } });
};❌ Results in ?a=1 or ?b=2
By using useBatchRouter, calls to push are queued and merged together.
const batchRouter = useBatchRouter();
const onClick = () => {
batchRouter.push({ query: { a: 1 } });
batchRouter.push({ query: { b: 2 } });
};✅ Results in ?a=1&b=2
Installation
$ yarn add next-batch-router
or
$ npm install next-batch-routerUsage
1. BatchRouterProvider
Set up <BatchRouterProvider/> at the top of the component tree, preferably inside pages/_app.js
import { BatchRouterProvider } from "next-batch-router";
const MyApp = ({ Component, pageProps }) => (
<BatchRouterProvider>
<Component {...pageProps} />
</BatchRouterProvider>
);2. useBatchRouter
Instead of using useRouter from next/router, use useBatchRouter instead.
import { useBatchRouter } from "next-batch-router";
const Component = () => {
const batchRouter = useBatchRouter();
const onClick = () => {
batchRouter.push({ query: { a: 1 } });
batchRouter.push({ query: { b: 2 } });
};
return (
<div>
<button onClick={onClick}>Click me!</button>
</div>
);
};Definition
batchRouter.push(url, as, options);
batchRouter.replace(url, as, options);url: { query?: SetQueryAction, hash?: string | null }
You cannot put
string. Onlyobjectwithqueryandhashproperty is allowed.queryis similar to the originalqueryparameter with some differences.- Original
pushcompletely replaced the query string with the given object, butbatchRouter.pushmerges the object by default. nullvalue removes the query parameter from the query string. CallingbatchRouter.push({query: {a: null}})on?a=1&b=2results in?b=2.undefinedvalue is ignored. CallingbatchRouter.push({query: {a: undefined}})on?a=1&b=2results in?a=1&b=2.- You can put a
functioninstead of anobjectas aqueryparameter, similar toReact.useState. However, the returned object is not merged automatically and must be merged manually within the function. Since merge is not automatically done, theundefinedvalue is handled asnulland is removed from the query string.
- Original
hashis the "hash" part from?param=foo#hashurl. It's similar to the originalhashparameter with some differences.- Originally,
hashwas not preserved unless provided in therouter.pushcall.batchRouter.pushpreserves the original hash if not supplied. nullvalue removes the hash.- When multiple
pushcalls have ahashparameter, the last one is applied. - There is a bug in which removing all query parameters doesn't work if there is a hash in the URL. Such as this:
batchRouter.push({ query: ()=>({}), hash:"hash" })
- Originally,
as?: { query?: SetQueryAction, hash?: string | null }
- Optional. Defines how the browser URL bar will look like. Can be used to set param in router.query but hide it from the URL. Check next/router documentation for more detail. Similar to
url.
options?: { scroll?: boolean, shallow?: boolean, locale?: string }
scroll: Scroll to the top of the page after navigation. Defaults totrue. When multiplepushandreplacecalls are merged, all must havescroll: falseto not scroll after navigation.shallow: Update the path of the current page without rerunninggetStaticProps,getServerSidePropsorgetInitialProps. Defaults tofalse. When merged, all must haveshallow: trueto do shallow routing.locale: Indicates locale of the new page. When merged, the last one will be applied.
Limitations
useBatchRouter is currently not designed to replace useRouter. It's to be used together and useBatchRouter should be used for changing only the query and hash part of the URL.
License
This project is licensed under the MIT License.