Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gatsby Dynamic styling not working in production build

Tags:

I am new in Gatsby and I am using tailwind css with postcss. Some of the color configurations I defined in theme object of tailwind.config.js is working in dev environment but not in production. I have tried cleaning cache and deleting public folder and re-building it. That did not solve the problem. My theme object in tailwind.config.js is like this:

theme: {
    colors: {
      transparent: 'transparent',
      current: 'currentColor',
      primary: {
        DEFAULT: '#4F9C3A',
        900: '#25441c',
      },
      secondary: {
        0: '#ff9563',
        DEFAULT: '#E66437',
        9: '#ae3409',
      },
      footer: {
        light: '#e66437',
        DEFAULT: '#383e42',
        dark: '#26292c',
      },
      neutral: {
        0: '#ffffff',
        DEFAULT: '#ffffff',
        1: '#fafafa',
        9: '#000000',
      },
      accent: {
        1: '#388ac5',
        DEFAULT: '#293842',
      },
      brown: {
        DEFAULT: '#C9AC75',
        2: '#44261c',
      },
      black: '#000000',
    }
}

UPDATE: I have been able to pinpoint source of the problem. I am fetching which class names to apply from a json file using gatsby-transformer-json. I have something like the following code segment to set background color which is working in development environment but not in production.

<div className={`bg-${color}>
The development build shows proper background color for this segment but production build does not. 
</div>
like image 899
Minhaz Ahmed Avatar asked Jan 29 '21 19:01

Minhaz Ahmed


1 Answers

TLDR: Don't use string concatenation in your class names when you use the purge option in tailwind.config.js. Instead, provide full class names.

Source: https://tailwindcss.com/docs/optimizing-for-production


UPDATE March 1st, 2021

Thanks @robotu for bringing another great option to the table: you can add a safelist option to your tailwind.config.js file, like this:

module.exports = {
  // ...
  purge: {
    content: ['./src/**/*.html'],
    safelist: ['bg-primary', 'bg-secondary']
  }
}



Original OP Code/Intent

You've done this: <div className={`bg-${color}`>

But TailwindCSS prefers something like this: <div className={ color === "red" ? "bg-red" : "bg-blue" }>

My guess is that you could probably use a function/hook that returns the full class name in the case that you have many possible colors, but I haven't tested that yet.




The longer version:

You aren't showing us your full tailwind.config.js file, but I'll assume you're using the purge option somewhere in there.

Continuing with Ferran's answer: I'd say the real issue is how PurgeCSS, which Tailwind uses under the hood during the build process when you include the purge option in your config, determines what classes to purge during the build process.

It finds any strings that match the regular expression:

/[^<>"'`\s]*[^<>"'`\s:]/g

Which will naively find almost everything, only stopping at specific syntax symbols. It will then try to preserve every match, and purge the rest. So it will find bg- and color, preserve them, but will purge bg-color as that was not found by PurgeCSS's regex.

From TailwindCSS docs:

That means that it is important to avoid dynamically creating class strings in your templates with string concatenation, otherwise PurgeCSS won't know to preserve those classes.

like image 189
Angus Ryer Avatar answered Sep 30 '22 19:09

Angus Ryer