In my Next.js app, I want to render a mobile/desktop header based on the width of the device. In general, this is a simple task, i did many times in normal react, using hooks like useWindowDimensions, where I check the width of the window object and use this parameter for a simple condition. In Next.js however, I ran into the problem that my app is pre-rendert on the server, so of course there is no window object that I could use for the condition. Things I tried:
- dynamic import of the component; this means the component didn't get pre-rendert on the server but only on the client. This would work, but I didn't use the benefit of SSR, and for SEO reasons I want to pre-render "key-components" like the header.
- I just picked a condition for SSR, like render always the mobile- header, for example and on the CSR, I just render on the real condition. This would solve my issue with rendering always "key-components" on server side, so SEO is happy, but i run in an ugly warning about content mismatch between server and client because when I render the app on desktop device, my first render on client side, of course, would be the desktop-header. So this doesn't seem to be a good solution either.
- Next I tried to render a certain condition like before, so render always the mobile-header on server AND client side and use a useEffect hook only on mount,
useEffect({...}, [])
which then check the real condition and triggers a re-render with the correct condition. This would solve my SEO-thing and also the ugly content mismatch warning. BUT I run into a noticeable layout-shift, where the user sees the mobile-header first and after half a second the header changes to the desktop-header. ugly stuff..
- So I got my next idea, which was checking the user-agent or device type with getServersideProps and somehow using this info for a conditional rendering on server-side. This doesn't really work out to well, especially since I would want to use it in my _app.tsx so I don't have to write this stuff for every page again and again. In a discussion thread in the official Next.js repo, I found that getServersideProps doesn't work in _app.js yet, only getInitialProps, which is deprecated and shouldn't be used anymore...
So, to make things short, there has to be a good way to render components in Next.js without the above problems. I just couldn't figure out yet what is best practice for this kind of stuff.
I would appreciate any hints, tipsor advices in this topic ❤️