I need some advice for SSR. Here is the situation
I have created a small utility FlexBox component using styled-components for layouting using CSS flex specifications. This component accepts gap prop to set gap between children according to the specifications.
If browser supports FlexBox gap then CSS rule for gap will be added. If not supported, then component fallbacks to adding margin property.
For this behavior we need to detect whether browser supports Flex gap feature.
Everything works fine in CSR apps.
In order to detect flex gap feature, it needs to access document property of window. This won't work while server rendering.
One way to fix this issue is by rendering FlexBox Component only in browser as advised in Debugging HTML Builds section of gatsby docs.
But the problems here are :
So I need some advice on what to do in situations where we need to access browser APIs in the very beginning of the component rendering hierarchy.
Thanks in advance.
You could use @supports to check if the browser supports it. Something along the lines of:
const Container = styled.div`
@supports (display: block) {
background-color: seagreen;
}
`;
The example here. Checks for display: block Is supported. If it does. Make the background-color: seagreen
You can read more about how @supports works here: https://developer.mozilla.org/en-US/docs/Web/CSS/@supports
@dhhdev thanks for the answer.
gap CSS property can also be used for CSS grid layout as well as mentioned here: https://developer.mozilla.org/en-US/docs/Web/CSS/gapPlease let me know if I am missing something.
Is my above understanding correct ? Please do comment if you have better suggestions.
@ppiyush13, I have never heard of a flex box specific gap (gutter) attribute. So I am not entirely sure as to how you would even implement that. (To my knowledge, flex-box doesn't have this. They usually use margins for making empty space between "cells".) The CSS specificiation you are linking to, is for the grid layout specification: https://www.w3.org/TR/css-grid-1/#change-2016-grid-gap
If you could give us a snippet of the code, that makes the component. That would be a big help to find something that might work.
@dhhdev, the link which i quoted is for gap property which is applicable to grid, flex and multi-column layouts.
Here is the formal specification explaining same : https://www.w3.org/TR/css-align-3/#gaps
Go on this page: https://developer.mozilla.org/en-US/docs/Web/CSS/gap
Look into examples section. Very first example is for gap with flex layout.
If opened in chrome you wont notice any gap. Open in FF(> 63) you can see the difference.
Some additional resources:
So thats why I am using flex gap feature detection via JS which is working perfectly fine.
So my question
- So my understanding is if we have to use some browser APIs in the very beginning of component rendering hierarchy then we might not get SSR benefits as most part of component hierarchy will be rendered on client.
Is my above understanding correct ? Please do comment if you have better suggestions.
Is this correct ?
Thank you for opening this!
So my understanding is if we have to use some browser APIs in the very beginning of component rendering hierarchy then we might not get SSR benefits as most part of component hierarchy will be rendered on client.
Is my above understanding correct ? Please do comment if you have better suggestions.
If you're referencing browser APIs or window and guard against that (so that during the build Node.js doesn't complain), then yes it'll only be rendered on the client and won't be in the HTML.
However, I personally think your Flexbox component isn't ideal and you should use @supports and/or CSS features that are more supported. Or use CSS Grid.
We're marking this issue as answered and closing it for now (as it's not really related to Gatsby) but please feel free to reopen this and comment if you would like to continue this discussion. We hope we managed to help and thank you for using Gatsby!
Most helpful comment
You could use @supports to check if the browser supports it. Something along the lines of:
The example here. Checks for
display: blockIs supported. If it does. Make thebackground-color: seagreenYou can read more about how
@supportsworks here: https://developer.mozilla.org/en-US/docs/Web/CSS/@supports