emotion-js/emotion · error · Error

css can only be used during render

Error message

css can only be used during render

What it means

Inside the ClassNames component, the css() callback may only be invoked while the component is rendering. After render completes (hasRendered = true), calling css() in development throws, because the generated class would never be attached to the output. Deferred calls (in event handlers, effects, timeouts, async callbacks) are invalid.

Source

Thrown at packages/react/src/class-names.tsx:146

export interface ClassNamesContent {
  css(template: TemplateStringsArray, ...args: Array<CSSInterpolation>): string
  css(...args: Array<CSSInterpolation>): string
  cx(...args: Array<ClassNamesArg>): string
  theme: Theme
}

export interface ClassNamesProps {
  children(content: ClassNamesContent): React.ReactNode
}

export const ClassNames = /* #__PURE__ */ withEmotionCache<ClassNamesProps>(
  (props, cache) => {
    let hasRendered = false
    let serializedArr: SerializedStyles[] = []

    let css: ClassNamesContent['css'] = (...args) => {
      if (hasRendered && isDevelopment) {
        throw new Error('css can only be used during render')
      }

      let serialized = serializeStyles(args, cache.registered)
      serializedArr.push(serialized)
      // registration has to happen here as the result of this might get consumed by `cx`
      registerStyles(cache, serialized, false)
      return `${cache.key}-${serialized.name}`
    }
    let cx = (...args: Array<ClassNamesArg>) => {
      if (hasRendered && isDevelopment) {
        throw new Error('cx can only be used during render')
      }
      return merge(cache.registered, css, classnames(args))
    }
    let content = {
      css,
      cx,
      theme: React.useContext(ThemeContext)

View on GitHub (pinned to b882bcba85)

Solutions

  1. Call css() only within the ClassNames render-prop body during render
  2. Precompute the serialized class during render, store the returned class string, and use that string in callbacks
  3. If styles depend on later state, trigger a re-render and compute classes in the render body
  4. Use the css prop or a styled component for dynamic post-render styling needs

Example fix

// before
<ClassNames>{({ css }) => {
  useEffect(() => { el.className = css({ color: 'red' }) }, [])
  return <div />
}}</ClassNames>

// after
<ClassNames>{({ css, cx }) => {
  const cls = css({ color: 'red' })
  useEffect(() => { el.className = cls }, [cls])
  return <div />
}}</ClassNames>
Defensive patterns

Strategy: validation

Validate before calling

// ensure css() is invoked during render
let rendering = true
function guardCss(fn) { return (...a) => { if (!rendering) throw new Error('css called outside render'); return fn(...a) } }

Try / catch

try {
  const cls = cssFn(styles)
} catch (e) {
  if (e.message === 'css can only be used during render') {
    // recompute during render or fall back to static class
  } else throw e
}

Prevention

When it happens

Trigger: Calling the css function from the ClassNames render prop inside useEffect, setTimeout, event handlers, or promises; memoizing and calling the css callback after the first render.

Common situations: Building class names in a click handler; generating styles asynchronously after data loads; storing the css function and reusing it after mount.

Related errors


AI-assisted analysis of emotion-js/emotion@b882bcba85 (2026-09-02). Data as JSON: /api/errors/bafee3512cbd2e62. Report an issue: GitHub.