menu

Gatsby.js

Fast in every way that matters. Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps.

Channels
# All channels
view-forward
# General
view-forward
# I Made This
view-forward
# Meta
view-forward
# Themes
view-forward
Team

Responsive Media Queries and JS

February 23, 2020 at 10:12am

Responsive Media Queries and JS

February 23, 2020 at 10:12am (Edited 1 month ago)
Hi there,
I've been building a site with Gatsby/Netlify and I'm having issues understanding how to get around the issue of Gatsby not being aware of window sizing during the static site build. It's hard to troubleshoot because the issue only occurs once pushed to Netlify. It works as expected when running netlify dev/gatsby develop
I have been using the plugin react-responsive which works great once a user starts navigating the site but the initial page load doesn't utilise it correctly.
Here's a cutdown example of the code I want to use:
const isTabletOrMobile = useMediaQuery({ query: '(max-width: 1023px)' });
return (
<Layout>
...
<div className={`column is-centered is-paddingless ${isTabletOrMobile ? '' : 'is-three-fifths'}`} style={{height: 'calc(100vh - 181px'}}>
<Story width='95' data={data} />
</div>
...
</Layout>
)
Here I'm trying to include a class in the className list if the display is a tablet or mobile size. There are other scenarios where I am passing a prop depending on display size. How else can I achieve this to work with Gatsby?

February 23, 2020 at 3:27pm
Did you try using state and componentDidMount to set this.state.isTabletOrMobile?
  • reply
  • like
Did you try using state and componentDidMount to set this.state.isTabletOrMobile?
Thanks for the reply, I'm using functional components so I tried useEffect instead but I get an error saying useMediaQuery cannot be used inside a callback.
  • reply
  • like
Just an FYI, gatsby develop doesn't do SSR, which is why it would work there and not on Netlify. It's probably always a good idea to test SSR before pushing to production by doing gatsby build && gatsby serve -o
Defining effects based on media queries calculated in javascript won't really work to well when using Gatsby. You could probably shim the Window object, but the real problem is not getting that hook to work. The real problem is the fact that your design will be rendered a certain way during SSR, so it will be the first thing that shows up, no matter the size of the window of whomever hits your site. Then, when React hydrates, they will see the design change, because it has just then run your media query calculation. If you decided to go with a mobile first design, somebody on a larger monitor would first see it in mobile, then it would jump to fit their screen.... and vice versa, if you don't do mobile first.
A better way to design that would be to just use classic css. The browser can then determine the best way to render the static html when it does the layout for the first time.
like-fill
2
  • reply
  • like
Really helpful, thanks! I've started to opt for classic CSS when I can now, there are certain situations where it's a pain this JS querying can't work though.
  • reply
  • like
It would work how you would expect in a client-only route. You lose the benefits of static rendering with those, though. If class/style composition might make it easier, you could do scss. css-in-js like emotion works, too, but you’d still have to define all of your media queries ahead of time, so that they are included on the static render; just makes it easier to reuse styles across classes
like-fill
1
  • reply
  • like