Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server side rendering causes the layout to shift when loading #85

Closed
cristianpjensen opened this issue Jan 17, 2023 · 10 comments · Fixed by #90
Closed

Server side rendering causes the layout to shift when loading #85

cristianpjensen opened this issue Jan 17, 2023 · 10 comments · Fixed by #90

Comments

@cristianpjensen
Copy link

cristianpjensen commented Jan 17, 2023

I am using NextJS and at the start (after a refresh), the panels start in their default configuration (so not whatever the user had before). Then it quickly shifts to the user's intended position (within a couple ms).

It looks like this:

2023-01-17 16 52 40

I feel like the panel should be client side rendered, but I do not want the content of the panels to be client side rendered. Is there anything that can be done against this? I do not have a lot of experience with NextJS, so there is probably an easy solution I am not seeing.

@cristianpjensen cristianpjensen changed the title Server side rendering causes the layout to shift at when loading Server side rendering causes the layout to shift when loading Jan 17, 2023
@papahigh
Copy link
Contributor

papahigh commented Jan 17, 2023

Hi @cristianpjensen! You could try to wrap your component with 'next/dynamic'
https://nextjs.org/docs/advanced-features/dynamic-import

it should be a safe way to get it working without flickering

@bvaughn
Copy link
Owner

bvaughn commented Jan 17, 2023

Good question.

Maybe if you stored the group layout somewhere that was accessible to both the client and server, then used those sizes to pre-load the server-rendered content...this could work, although it would still require a change to PanelGroup to not initially render the panel with flex-grow: 1

To be honest, server-rendering is not a use case I have, so I'd require your help on figuring that one out.

@cristianpjensen
Copy link
Author

Hi @cristianpjensen! You could try to wrap your component with 'next/dynamic' https://nextjs.org/docs/advanced-features/dynamic-import

it should be a safe way to get it working without flickering

This works! (for others reading this that have the same problem, you should set the ssr option to false). The downside of this is that now it only starts rendering the content of the panels on the client side. So, the entire PanelGroup will not be there for a second while the header is there. This could probably be fixed with a spinner or something, but it would be great if the settings could be stored on the server as well as on the client. Then, it won't require a spinner or other loading animation. But, I do not know whether this is even possible with NextJS.

I also think it is important for SEO that the content is loadable on the server.

Good question.

Maybe if you stored the group layout somewhere that was accessible to both the client and server, then used those sizes to pre-load the server-rendered content...this could work, although it would still require a change to PanelGroup to not initially render the panel with flex-grow: 1

To be honest, server-rendering is not a use case I have, so I'd require your help on figuring that one out.

Something like this would be perfect, but I do not know whether such a storage exists in NextJS. Maybe cookies?

@cristianpjensen
Copy link
Author

Yes, cookies are accessible on the server via getInitialProps() in NextJS and accessible in the client via document.cookies. Maybe it would be cool if it was possible for a user to choose where to store the information.

An even better idea is if a user could provide getter and setter functions for these values. Zustand also provides such an option. This would give users a lot more customizability and it could just default to using local storage.

@bvaughn
Copy link
Owner

bvaughn commented Jan 17, 2023

I like the storage prop option. Let me think about that.

@bvaughn
Copy link
Owner

bvaughn commented Jan 17, 2023

Okay, I think that's a nice simplifying suggestion for external persistence. I've added an optional storage prop to PanelGroup in PR #90.

@bvaughn
Copy link
Owner

bvaughn commented Jan 17, 2023

@bchilcott
Copy link

I'm using this with the new NextJS app directory in a client component and it does seem to fix the layout issue, although I get an error on the SSR step as localStorage is not defined - which is to be expected:

- error src\components\Panels.tsx (46:48) @ localStorage
- error ReferenceError: localStorage is not defined

The panel group is set up like this:

<PanelGroup direction="horizontal" storage={localStorage}>

I'd rather not dynamically import the whole group with SSR disabled, so do you know of a way around this? The lack of localStorage on the server doesn't seem to actually cause a problem, at least not an obvious one. Only the error which I'd rather not have.

I'm also not that experienced with NextJS so this could just be a me problem.

@bvaughn
Copy link
Owner

bvaughn commented May 13, 2023

@bchilcott I’m out at the moment, but would you file a new issue about this? I can probably wrap the typeof check in a try/catch to prevent this.

@bchilcott
Copy link

Opened #144 - I'll add a repro if I get a chance later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants