emotion-js/emotion · error · Error

You seem to be using a value for 'content' without quotes, t

Error message

You seem to be using a value for 'content' without quotes, try replacing it with `content: '"${value}"'`

What it means

Emotion's serializer validates `content` property values at development time. CSS requires content values to be quoted strings or recognized keywords/URLs; an unquoted bare word like content: hello would silently produce invalid CSS, so emotion throws with the corrected form. The check runs when the value is a non-string-safe, non-quoted, non-keyword value.

Source

Thrown at packages/serialize/src/index.ts:146

  let contentValues = ['normal', 'none', 'initial', 'inherit', 'unset']

  let oldProcessStyleValue = processStyleValue

  let msPattern = /^-ms-/
  let hyphenPattern = /-(.)/g

  let hyphenatedCache: Record<string, boolean | undefined> = {}

  processStyleValue = (key: string, value: string | number) => {
    if (key === 'content') {
      if (
        typeof value !== 'string' ||
        (contentValues.indexOf(value) === -1 &&
          !contentValuePattern.test(value) &&
          (value.charAt(0) !== value.charAt(value.length - 1) ||
            (value.charAt(0) !== '"' && value.charAt(0) !== "'")))
      ) {
        throw new Error(
          `You seem to be using a value for 'content' without quotes, try replacing it with \`content: '"${value}"'\``
        )
      }
    }

    const processed = oldProcessStyleValue(key, value)

    if (
      processed !== '' &&
      !isCustomProperty(key) &&
      key.indexOf('-') !== -1 &&
      hyphenatedCache[key] === undefined
    ) {
      hyphenatedCache[key] = true
      console.error(
        `Using kebab-case for css properties in objects is not supported. Did you mean ${key
          .replace(msPattern, 'ms-')
          .replace(hyphenPattern, (str, char) => char.toUpperCase())}?`

View on GitHub (pinned to b882bcba85)

Solutions

  1. Quote the value: content: '"hello"' or content: '"' + value + '"'
  2. Use CSS.escape-style quoting or JSON.stringify(value) when interpolating dynamic strings
  3. If the value is a keyword (counter, attr(...), open-quote), keep it unquoted — the checker allows it
  4. Check that an interpolated variable doesn't strip quotes added in the template

Example fix

// before
css`
  &::before { content: ${text}; }
`

// after
css`
  &::before { content: '"${text}"'; }
`
Defensive patterns

Strategy: validation

Validate before calling

function safeContent(value) {
  return /^(['\"]).*\1$/.test(value) || /^(counter|attr|open-quote|close-quote|url)\b/.test(value)
    ? value
    : `"${value}"`
}

Type guard

function isQuoted(s) {
  return typeof s === 'string' && s.length >= 2 &&
    ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'")))
}

Prevention

When it happens

Trigger: Writing styles like { content: hello } or { content: someVariable } where the value is not quoted, not in contentValues (counter, attr, open-quote, etc.), and does not match the allowed patterns (url(...), counter functions, or quoted strings).

Common situations: Forgetting quotes around a literal string in a css`` template; interpolating a variable containing unquoted text into content:; migrating from another CSS-in-JS lib that silently accepted unquoted values.

Related errors


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