Next.js: Client Side Rendering using Layouts without Reloading the entire page?

Created on 31 Jul 2019  Â·  17Comments  Â·  Source: vercel/next.js

Client side rendering without reinitializing entire nextJS page

Typical Client Side Routers like React Router have the ability to route subsections of the app. For example, you can have the below...

<App>
   <Header/>
   <Page>
   <Footer/>
</App>

And using a router, you can change what Page is rendered on the client. With this, the Header and Footer are not re-rendered and keep their state and are not re-painted onto the page. Only the Page changes`


Using NextJS's Client Side Routing capabilities, it is possible to route from the client and not go to the server. However, this is technically just routing between pages. Routing between pages re-renders the entire page including _app file.

I am looking for a way to route client side without re-initializing the entire NextJS process (running _document, getInitialProps, _app, then page).

feature request

Most helpful comment

@Timer @timneutkens any updates on this? I didn’t realize next js doesn’t do this already

All 17 comments

Would love this, especially with static export there's more cases of not re-rendering whole page, We have a mobile menu tabs in footer for example and change the active button on that menu, and re-rendering of whole page when page changes with next router blocks rendering of new active menu button, which just doesn't look really snappy

any progress or answer about it ?

@Timer @timneutkens any updates on this? I didn’t realize next js doesn’t do this already

Unfortunately, NextJS doesn't support persistent layouts yet but there is a nice article about how you can implement SPA user experience with NextJS.

https://adamwathan.me/2019/10/17/persistent-layout-patterns-in-nextjs/

I like the Remix and UmiJs strategy to solve this problem.

https://blog.remix.run/p/remix-preview

https://v2.umijs.org/guide/router.html#nested-routing

I have a demo for this issue here
As you click link to switch between pokemon, only a part of a page is re-rendered.
Wanna see such example with Next.js, too. (I'm using react-router) for the demo.

I've only used Next js router for basic page routing. How do I achieve client side component based (lazy-load?) routing? I can't imagine writing an app without it. How would you?

revskill10: link in https://github.com/zeit/next.js/issues/8193#issuecomment-623194233 is a 404.

The solution i came across is to use dynamic app layouts with React.memo method wrapped around <NavBar/> and </Footer>components which caused my NavBar and Footer render only one time during url changings

For example when i navigate through:

mysite.com/ 
mysite.com/me 
mysite.com/questions

and so on, clicking <Link> component from 'next/link' ,

the only time my NavBar and Footer did render is first time - mysite.com/

So, doing this i achieved the same thing like if we use React Router's switch method

Alt Text

What about having a layout page(which doesnt render more than once) that connects to a socket server?

I tried this connection in useEffect hook for _app.js, but on routing to another page, the _app.js gets re-rendered causing to establish a new socket connection!

Does anyone have an effective way to tackle this issue?

Update: The issue was with routing to a dynamic route(/stats/[id].jsx), what I did to fix the issue was to replace the dynamic route with a static route with passing id as query param within the Link

Can't wait for the solution 🥰

second UmiJS's solution, it makes sense as nextJS is already using conventional routes (based on the file/folder names):

+ pages/
  - _layout.js
  - index.js
  + users
    - index.js
    + [id]
      - _layout.js
      - posts.js
      - orders.js
  - about.js

It also makes permission control fairly easy, you just need to put the permission check logic in a certain level layout file then all the children pages will inherit the check.

I might be wrong, but I thought react takes care of this.

Yes, surely react will "calculate" the whole _app, but in the end, it is only updating the parts of the dom that have changed, so from the user point of view, there only is re-rendered the page, not the header or the footer.

Am I right?

I might be wrong, but I thought react takes care of this.

Yes, surely react will "calculate" the whole _app, but in the end, it is only updating the parts of the dom that have changed, so from the user point of view, there only is re-rendered the page, not the header or the footer.

Am I right?

Not for Nextjs where each page is almost like a separate app

I might be wrong, but I thought react takes care of this.

You can try it yourself. Btw “each page is almost like a separate app” from a comment above sounds fair enough. Though, there’s already an answer of how to hack it so no rerendering will happen:

https://github.com/vercel/next.js/issues/8193#issuecomment-590654825

It works in modern versions of Next even though I heard that this should stop working at some newer versions of react (and next) because of "fast refresh" feature... But fast refresh has come out, and this "layouting through page properties" seems to be working, still (so I would even close the issue, since it’s not an issue if you do it properly).

Was this page helpful?
0 / 5 - 0 ratings