Client side navigation without additional requests
Unanswered
Round sardinella posted this in #help-forum
Round sardinellaOP
Hi I'm using Next.js with the App router and RSC. Is there any way to do client side navigation without making additional requests to the server, not even ?rsc requests? The use-case is that we have a route /foo with tabs so you can go to /foo/bar, /foo/baz et.c., and we want that to be instant and work even if your internet is down. All the data needed is fetched already on /foo, so it shouldn't need to go to the server, but we can't figure out how to make it work. I've tried just using router.push but that still tries to make a request.
Thanks
Thanks
19 Replies
Good question, I'll try to look for some docs, the keywords for this would be "offline app" or PWA
you could have a service worker to intercept and handle the requests
I am not sure this is a super documented use case though, offline first is not Next.js specialty
Round sardinellaOP
Thank you. I've looked around and haven't found anything. If there's some way to completely deactivate RSC that would be good for us as well I think, but haven't found that either... we're happy with a 100% client side app
I would take a look at Next.js alternative too in this case, like Vite for instance
not that it's impossible in Next but not necessarily where it shines
Round sardinellaOP
Ok, thank you, so something like Vite + React Router could maybe be better than Next.js for us then?
I would at least investigate it yes
Serbian Hound
I'm not sure if it would work for your project structure, but I have done something similar to be able to have a carousel as my main navigation between "pages" ( they're not actually separate routes, but looks like it for the user).
Basically what I did was set up one page.tsx that has my carousel, and inside of it I put my components, each one rendering a different page.
I fetch all the data in the page.tsx and pass down to each component as needed. As the slide changes, it updates the URL using window.history.pushState(), so it looks like the user is going to a different page.
In order to handle if a user wants to go to a specific "page" (which is just a slide in the carousel), I use middleware to rewrite it to my page.tsx route ("/"), attach the requested route as a header, and then read that header in my page.tsx, pass down the value to my carousel, and then set the active slide to show the one related to the requested route.
So for example if someone goes to myapp.com/page2 it rewrites to myapp.com/ and then sets the initial slide to show my page2 component.
After initial fetch I can freely go between slides, even without an internet connection.
Basically what I did was set up one page.tsx that has my carousel, and inside of it I put my components, each one rendering a different page.
I fetch all the data in the page.tsx and pass down to each component as needed. As the slide changes, it updates the URL using window.history.pushState(), so it looks like the user is going to a different page.
In order to handle if a user wants to go to a specific "page" (which is just a slide in the carousel), I use middleware to rewrite it to my page.tsx route ("/"), attach the requested route as a header, and then read that header in my page.tsx, pass down the value to my carousel, and then set the active slide to show the one related to the requested route.
So for example if someone goes to myapp.com/page2 it rewrites to myapp.com/ and then sets the initial slide to show my page2 component.
After initial fetch I can freely go between slides, even without an internet connection.
Round sardinellaOP
Thank you, that sounds like a feasible approach. I'm a bit concerned that we'll end up building some messy home-made client-side router though 😅
Serbian Hound
Haha yeah I get what you mean, it took me a while to get something stable working, and I haven't put it through any rigorous tests so might end up with a nasty bug somewhere.
You're honestly probably better off using a different framework like Eric suggested.
I just really want to use Next because I have lots of other stuff that benefits from it 😄
You're honestly probably better off using a different framework like Eric suggested.
I just really want to use Next because I have lots of other stuff that benefits from it 😄
@Eric Burel I would take a look at Next.js alternative too in this case, like Vite for instance
Palomino
In regards to this post, I believe you can solve the sections
browser history needs a DOM and hydration failed using the line export const dynamic = 'force-dynamic' to prevent static site generation.So the only config is the section from
404 page not found and using react router instead of Next.js routingthe issue mentioned in these section is about client-only code not dynamic rendering
I would find it surprising to dynamically render the index page in an SPA where the point is to have a basic index.html + client-side navigation via client-side JS
Round sardinellaOP
React Router seems to work very well so far with https://colinhacks.com/essays/building-a-spa-with-nextjs, thanks a lot Eric!
Oriental Scops-Owl
According to nextjs docs you should be able to. But this doesn't budge for me
https://nextjs.org/learn-pages-router/basics/navigate-between-pages/client-side
https://nextjs.org/learn-pages-router/basics/navigate-between-pages/client-side