Emotion + Gatsby Serve: theme does not load except after refresh

Viewed 259

My problem seems isolated to components that combine css and withTheme from @emotion/react and styled from @emotion/styled. Initially many components load unstyled, but styles pop-in after browser refresh.

Each component looks like

components
|- AppBar
  |- AppBar.jsx // exports UnstyledAppBar functional React component
  |- styles.js // exports styles() which uses props.theme and returns css`...`
  |- index.js // exports withTheme(styled(UnstyledAppBar)`${styles}`), i.e. a styled component with theme injected

Further, the styles that fail to work on first load are the styles derived from the theme prop.

In other words

// styles.js
const styles = (props) => {
  const { theme } = props;

  return css`
    margin-left: 24px;
    margin-right: ${spacingSizeMedium}; // evaluates to 24px
  `;
}

The margin-left style renders immediately but margin-right requires refresh.

This issue does not appear in Gatsby development mode, but occurs in Gatsby builds.

Relevant packages

"@emotion/react": "^11.1.5",
"@emotion/styled": "^11.1.5",
"gatsby-plugin-emotion": "^6.0.0",
1 Answers

To me, it seems that you need to add some SSR (Server-Side Rendering) to @emotion. Have you tried something like:

import { cache } from '@emotion/css'; 
import { CacheProvider } from '@emotion/react';

export const wrapRootElement = ({ element }) => {
  return <CacheProvider value={cache}>{element}</CacheProvider>;
};

Source: https://ntsim.uk/posts/how-to-add-vanilla-emotion-ssr-to-gatsby

Related