react-socks icon indicating copy to clipboard operation
react-socks copied to clipboard

Server side rendering wrong css styles

Open simb4 opened this issue 6 years ago • 9 comments

I've got Header that renders different elements depending on viewport. When mobile page is loaded, some css styles from desktop viewport are stay on mobile viewport elements, which is strange:

<Breakpoint medium up>
  <div1 />
  <div2 className='a' />
  <div3 />
</Breakpoint>
<Breakpoint small down>
  <div4 />
  <div5 />
  <div6 />
</Breakpoint>

on mobile viewports results in:

...
  <div4 />
  <div5 className='a' />
  <div6 />
...

Where <divN> some component.

simb4 avatar Sep 15 '19 11:09 simb4

I have the same issue. To solve it I use Bootstrap's breakpoint classes instead. Not optimal considering there will be a lot of unnecessary rendering. Would appreciate if this issue can be solved.

mackan92 avatar Oct 18 '19 11:10 mackan92

This is because while rendering in server, React cannot identify the breakpoint as breakpoints exist only in browsers. That's why we default to desktop breakpoint in server. One solution is to extend the api in a way that users can identify useragent from request header and pass it in to the lib as default. It will take some time to get it done as the approach is not standard and we will have to unify the approach for all server frameworks (Next, Gatsby, vanilla).

flexdinesh avatar Oct 22 '19 04:10 flexdinesh

This is because while rendering in server, React cannot identify the breakpoint as breakpoints exist only in browsers. That's why we default to desktop breakpoint in server. One solution is to extend the api in a way that users can identify useragent from request header and pass it in to the lib as default. It will take some time to get it done as the approach is not standard and we will have to unify the approach for all server frameworks (Next, Gatsby, vanilla).

Yes, this is exactly what I figured out while trying to surpass this problem. But the problem is, that while rendered on client side (after hydrate) we don't see the correct elements, so I need to force update it to render properly. I have 2 solutions(ish, they are ugly) for now, you can either hide them on server side to show up only on client side(when you know dimensions), or you can force update after component mounted on client side.

Is there any approach to handle this without re-render (and without integrating with server side)?

simb4 avatar Oct 28 '19 06:10 simb4

Same issue here... :( Too bad this library could be very useful

cyril94440 avatar Mar 21 '20 11:03 cyril94440

Same Issue here. Anyone with a workaround to it yet?

dongepulango avatar Mar 31 '20 14:03 dongepulango

Same issue.

ghost avatar Aug 30 '20 22:08 ghost

This is because while rendering in server, React cannot identify the breakpoint as breakpoints exist only in browsers. That's why we default to desktop breakpoint in server.

I reckon the problem lies here on the function getWidthSafely() as it defaults to 9999.

It's probably a good idea to have an option to set that default value instead of having 9999, that would be easy to implement and would probably be already enough for most use-cases?

One solution is to extend the api in a way that users can identify useragent from request header and pass it in to the lib as default.

With https://www.npmjs.com/package/device ( which powers https://github.com/rguerreiro/express-device ) it should be very easy to implement that.

It will take some time to get it done as the approach is not standard and we will have to unify the approach for all server frameworks (Next, Gatsby, vanilla).

I believe with the option to set default width and the device package people should be able to sort implement themselves while we don't sort out out-of-the-box compatibility with Next and Gatsby?

hems avatar Sep 21 '20 08:09 hems

This is because while rendering in server, React cannot identify the breakpoint as breakpoints exist only in browsers. That's why we default to desktop breakpoint in server.

I reckon the problem lies here on the function getWidthSafely() as it defaults to 9999.

I have created a PR https://github.com/flexdinesh/react-socks/pull/40 which adds this option to the library, this way at least we can set default value to be the mobile breakpoint, so server-side would render mobile-first.

From that point on I believe workaround can be implemented by users on case-to-case basis?

I'm using Next.js myself, so i had to implement a quick fix, i was able to do it by installing https://www.npmjs.com/package/next-useragent and then calling the function setDefaultWidth based on the flag isMobile, and it seens to be working so far!

cc: @YJoris @dongepulango @cyril94440

hems avatar Sep 21 '20 09:09 hems

There is no magical fix for this but setDefaultWidth API published as part of v2.2.0 will help with this. This is a popular issue and I'm gonna keep it open for other folks who might run into similar problems.

flexdinesh avatar Apr 08 '21 23:04 flexdinesh