Pass Next.js router to an npm React component library (with Jotai) #3131
-
I’ve built a standalone React library that will be published as an npm package. The library is framework-agnostic (not tied to Next.js or React Router) and mainly provides UI + logic components. Some parts of the library need to perform navigation (e.g., router.push("/something")). Since the library doesn’t know which routing system the consuming app will use, I want to let the host app inject its router into the library at runtime. I’m using Jotai to manage this. Inside the library, I keep a routerAtom and export a hook to set it: export const router = atom<Router>({
push(url: string): void {
if (typeof window !== 'undefined') {
window.location.href = url
}
},
})
export const useSetRouter = () => {
const setRouter = useSetAtom(router)
return useCallback((router: Router) => setRouter(router), [setRouter])
} In the Next.js app, I grab the real Next.js router and set it into the library: const setDesignLibraryRouter = useSetRouter();
useEffect(() => {
setDesignLibraryRouter({
...router,
push: async (url) => {
await router.push(url);
},
})
}, [router, setDesignLibraryRouter]); What I’ve tried Using Jotai’s global store (without a Provider) → didn’t work My expectation Question |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
First I should remind you that you should use jotai-scope's createIsolation to prevent your library and your app from sharing the same store. As for your problem it revolves around syncing a "React value" into an atom that lives outside React.
I'd suggest |
Beta Was this translation helpful? Give feedback.
-
The issue got resolved when i use the useHydrateAtoms in my library and exported as hook to the next application. In the next application i used the hook when the router is initialized and passed the router to the hook. Note: Just want i don't want any state related variable to the apps and want to enclose everything in the library did this stuff. In other case if the store for the app and library is same you can directly use the useHydrateAtoms directly. Library Code NextJs App Code |
Beta Was this translation helpful? Give feedback.
The issue got resolved when i use the useHydrateAtoms in my library and exported as hook to the next application. In the next application i used the hook when the router is initialized and passed the router to the hook.
Note: Just want i don't want any state related variable to the apps and want to enclose everything in the library did this stuff. In other case if the store for the app and library is same you can directly use the useHydrateAtoms directly.
Library Code
export const useSetRouter = (initialRouter: Router) => { // useHydrateRouter(initialRouter) useHydrateAtoms([[routerAtom, initialRouter]]); }
NextJs App Code
const router = useRouter(); useSetRouter(router)