Next-plugins: postcss autoprefixer not working

Created on 10 Apr 2018  ·  36Comments  ·  Source: vercel/next-plugins

I have the postcss.config.js file in the root of my project:

module.exports = {
    plugins: {
        'autoprefixer': {}
    }
}

And next.config.js:

const withPlugins = require('next-compose-plugins')
const withCSS = require('@zeit/next-css')
const withSass = require('@zeit/next-sass')
const withImages = require('next-images')

const nextConfig = {
    useFileSystemPublicRoutes: false,
    webpack: (config) => {
        config.node = {
            fs: 'empty',
            modules: false
        }

        return config
    }
}

module.exports = withPlugins([
    withCSS,
    withSass,
    withImages
], nextConfig)

I've installed the required modules, but the autoprefixer doesn't work. When I inspect the entities in Chrome, they don't have the proper complementary prefixes eg -ms-flexbox- along flex.

Most helpful comment

This works for me:

  1. Create postcss.config.js in project root.
  2. Add autoprefixer to package.json (yarn add --dev autoprefixer)
  3. Add the following to postcss.config.js:
const autoprefixer = require('autoprefixer');

module.exports = {
  plugins: [
    autoprefixer({
      browsers: ['> 1%', 'last 4 versions'],
    }),
  ],
};

All 36 comments

I also followed the example provided and was unable to get autoprefixer working. The syntax I ended up using to get it working was:
postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')({})
  ]
}
module.exports = () => ({
  plugins: {
    autoprefixer: {}
  }
})

Works for me (next 6.0.x)

@stephensauceda's workaround solved my problems using a few postcss plugins 👍

anything new with next 7?

Since next 7, this code in postcss.config.js doesn't work anymore:

module.exports = {
    plugins: [require('autoprefixer')({})],
};

Also I get a bunch of warnings in the console when building pages in dev mode:
next

The warning message is You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.

I am running into the same issue, any update?

I'm using:

module.exports = (ctx) => {
  const plugins = {
    autoprefixer: {
      ...ctx.options.autoprefixer,
      flexbox: 'no-2009',
    },
  };

  return { plugins };
};

with success on 7@latest in my postcss.config.js

@kylemh so glad you got to this 4 days b4 I did :) Thx for posting that!

@kylemh Changes nothing for me.

I still have this stack effect in my console, and nothing gets autoprefixed:

capture

@nagman try to configure your browsers etc. So like

autoprefixer: {
   browsers: [
      // your supported browser config here.
  ],
  flexbox: true
}

@blujedis Nope. Nothing changed :/

Here's my postcss.config.js:

module.exports = _ => ({
    autoprefixer: {
        flexbox: true,
    },
});

And I still got the same two issues:

  1. My console goes freestyle
  2. No autoprefixing in the browser

@nagman the good news is, it's just your configuration. What I mean is it's for sure working here's a quick test I just did.

Here are two tests, flexbox and linear-gradient. Just ran it.

screen shot 2018-10-30 at 10 40 52 am

screen shot 2018-10-30 at 10 41 00 am

Here's my working next.config.js. (including this so you have everything).

const withBundleAnalyzer = require("@zeit/next-bundle-analyzer");
const withCss = require("@zeit/next-css");
const withTypescript = require("@zeit/next-typescript");
const withPlugins = require("next-compose-plugins");

module.exports = withPlugins(
  [
    withTypescript,
    withCss,
    [
      withBundleAnalyzer,
      {
        analyzeServer: ["server", "both"].includes(process.env.BUNDLE_ANALYZE),
        analyzeBrowser: ["browser", "both"].includes(
          process.env.BUNDLE_ANALYZE,
        ),
      },
    ],
  ],
  {
    distDir: "../dist",
  },
);

...and here's my postcss.config.js

module.exports = (ctx) => {
  const plugins = {
    autoprefixer: {
      ...ctx.options.autoprefixer,
      browsers: [
        '>1%',
        'last 4 versions',
        'Firefox ESR',
        'not ie < 9',
      ],
      flexbox: 'no-2009',
    }
  }
  plugins['postcss-nested'] = {};
  return { plugins };
};

Again you can adjust your browser settings as you wish the above I think are just the create-react-app defaults.

Maybe duplicate what I have here (without the Typescript) plugin unless you're using TS and then work from here.

Hope that helps!

@nagman you're returning an object with a key of autoprefixer, you need to return an object with a key of plugins that has an object with a key of autoprefixer.

You're supposed to be returning the entire postcss config - not just your autoprefixer options.

@kylemh Woops, you're right.
I've corrected it:

module.exports = _ => ({
    plugins: {
        autoprefixer: {
            browsers: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9'],
            flexbox: 'no-2009',
        },
    },
});

But still the two same issues...

try copying my config exactly first - context and all. Can you make a reproduction of the issue?

@nagman question are you importing into one of your app components NOT named _document.js or are your sheets in the /static directory?

If the later I don't believe they're getting processed. You'd likely have to modify your config for webpack and push the appropriate loaders/tests etc.

I could be wrong (a bit new to Next) but that's what I see.

Maybe @kylemh knows more.

@blujedis I'm importing all of my css in my app components, not in the pages.
And I use __modular CSS__ - maybe the reason of the issue?

@kylemh I don't have your config, you did not provide it.

Here's my next.config.js:

const withSass = require('@zeit/next-sass');
module.exports = withSass({
    cssModules: true,
    cssLoaderOptions: {
        importLoaders: 1,
        localIdentName: '[local]__[hash:base64:5]',
    },
    sassLoaderOptions: {
        includePaths: ['theme'],
        outputStyle: 'compressed',
    },
    postcssLoaderOptions: {
        autoprefixer: true,
    },
});

Delete your importLoaders line. You have 2 loaders at play.

https://github.com/webpack-contrib/css-loader#importloaders

NextCSS will automatically determine the number of loaders you're using (and is used by NextSass, if you missed that connection).

It'd be lovely if some details were changed at this spot of the NextSass README to prevent this situation going forward.


Also, delete postcss loader options - NextCSS will automatically use find-up to grab you postcss.config.js. (Even if you left it, you've got the same issue going on there which we referrerd to earlier with the incorrect keys).


Would love if you made a PR to change the NextSass README to save other people from going through this issue! I can see how you ended up in this situation.

@kylemh Thanks! But it only solved one of the two issues...

I've removed the importLoaders line, and now my console behaves normally (no errors spaming my screen).

But still nothing autoprefixed in my browser, yet 😢

And when I removed the postcssLoaderOptions, it showed me this error:

Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Loading PostCSS Plugin failed: Cannot find module 'autoprefixer'

Would I need to install this module separately?

@nagman yes you need to install autoprefixer, as well as any other plugins or whatever you're using.

For example I'm using postcss-nested which I had to install and then tell next about it.

Next doesn't ship with every plugin for obvious reasons.

There really is something strange with this. I've done everything you said, got no errors in my console, but still zero autoprefixing...

My next.config.js:

const withSass = require('@zeit/next-sass');
module.exports = withSass({
    cssModules: true,
    cssLoaderOptions: {
        localIdentName: '[local]__[hash:base64:5]',
    },
    sassLoaderOptions: {
        includePaths: ['theme'],
        outputStyle: 'compressed',
    },
});

My postcss.config.js:

module.exports = _ => ({
    plugins: {
        autoprefixer: {
            browsers: ['>1%'],
            flexbox: true,
        },
    },
});

And I've installed autoprefixer with: yarn add autoprefixer

Any chance of seeing a reproduction? I'd love to help resolve this for you.

Without seeing what else could be going wrong, I can only suspect that spreading potential context defaults could be the issue, but I don't think so. Can you change your postcss config to this:

module.exports = (ctx) => {
  const plugins = {
    autoprefixer: {
      ...ctx.options.autoprefixer,
      browsers: ['>1%'], // suggest you ditch this and use `.browserlistrc` instead
      // Flexbox is true by default
    },
  };

  return { plugins };
};

@kylemh Still doesn't work 😞

I need a reproduction to help you further. There's something else going on.

This works for me:

  1. Create postcss.config.js in project root.
  2. Add autoprefixer to package.json (yarn add --dev autoprefixer)
  3. Add the following to postcss.config.js:
const autoprefixer = require('autoprefixer');

module.exports = {
  plugins: [
    autoprefixer({
      browsers: ['> 1%', 'last 4 versions'],
    }),
  ],
};

@M7Dev Thanks a lot!!! It works, at last 🎉

@nagman glad you're up but this is pretty much what I indicated here https://github.com/zeit/next-plugins/issues/140#issuecomment-434402707 albeit with a more verbose config.

Sounds like the issue was how postcss config was outputting meaning you expected something the config you had was not supporting rather than anything to do with Next.

@nagman you can use package.json property browserlist
Eg:

  "browserslist": [
    ">= 0.5%",
    "chrome >= 42",
    "and_chr >= 42",
    "and_ff >= 38",
    "android >= 4.4",
    "edge >= 12",
    "firefox >= 38",
    "ie >= 11",
    "ios_saf >= 9",
    "safari >= 9",
    "node 10"
  ]

it is automatically used in autoprefixer but what is more important also into babel so you can enhance compatibility not just for styles, but also for scripts

FYI, @radeno's tip is the more suggested route. Using this config:

module.exports = {
  plugins: [
    require('autoprefixer')({
      browsers: ['defaults'],
    }),
    require('postcss-simple-vars'),
  ]
}

Results in:

  Replace Autoprefixer browsers option to Browserslist config.
  Use browserslist key in package.json or .browserslistrc file.

  Using browsers option cause some error. Browserslist config 
  can be used for Babel, Autoprefixer, postcss-normalize and other tools.

  If you really need to use option, rename it to overrideBrowserslist.

  Learn more at:
  https://github.com/browserslist/browserslist#readme
  https://twitter.com/browserslist

After going with the package.json option, I was able to use this config with success!

module.exports = {
  plugins: [
    require('autoprefixer'),
    require('postcss-simple-vars'),
  ]
}

Within postcss.config.js you should define

module.exports = {
  plugins: {
    autoprefixer: { browsers: ['last 2 versions', 'iOS >= 8'] }
  }
}

What's more ,there is a better way to fix

// in package.json, add this to bottom
 "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
// and in postcss.config.js just need
module.exports = {
  plugins: {
    autoprefixer: {}
  }
}

If you are experiencing issues regarding CSS Grid, make sure you add cssGrid: true to your postcss.config.js:

const autoprefixer = require('autoprefixer');

module.exports = {
  plugins: [
    autoprefixer({
      grid: true,
    }),
  ],
};

Has anybody tried autoprefixer with css-in-js. Pls share the config. I am using current version of Next js version 9 I tried all the config in this thread but none works in Nextjs 9.
I shared my issue on Spectrum.
https://spectrum.chat/next-js/general/trying-to-add-postcss-autoprefixer-for-css-in-js-styles~e6e2d396-c0d0-4360-9b64-de80b98ebb25

This works for me:

  1. Create postcss.config.js in project root.
  2. Add autoprefixer to package.json (yarn add --dev autoprefixer)
  3. Add the following to postcss.config.js:
const autoprefixer = require('autoprefixer');

module.exports = {
  plugins: [
    autoprefixer({
      browsers: ['> 1%', 'last 4 versions'],
    }),
  ],
};

大佬牛逼

In my case, I found out that if you set postcss-loader's plugins in webpack.config.js, it will overrides the plugins setting in postcss.config.js.
Just keep one of them.

Not sure if this will end up being the correct thread, but I'm having a very similar problem where I'm not getting any autoprefixes to work with my CSSModules. For some reason it won't process those css files. I've been over the docs, but I'm likely missing something. I've tried removing all of the postcss config to see if the default would pick up my Component.module.css files, but it does not prefix those automatically. I'm just using CSS, so I assume I'd need to use next/withCSS in some way, which I have not when it hasn't been picked up. However, the documentation is not clear on how to get those files to be autoprefixed.

My current (works in chrome without prefixes) config:

{
    "plugins": [
        "postcss-import",
        "postcss-color-mod-function",
        [
            "postcss-preset-env",
            {
                "autoprefixer": {
                    "flexbox": "no-2009"
                },
                "stage": 1,
                "features": {
                    "custom-properties": true,
                    "custom-media-queries": {
                        "importFrom": "./src/css/breakpoints.css"
                    },
                    "nesting-rules": true
                }
            }
        ],
        "postcss-calc"
    ]
}

Would it help to switch to sass instead? Perhaps then that loader would take care of the prefixing?
Any help here would be appreciated.

Hi, thanks for creating an issue. We currently recommend using https://nextjs.org/docs/basic-features/built-in-css-support as zeit/next-css and zeit/next-sass have been deprecated in favor of the built-in support.

Was this page helpful?
0 / 5 - 0 ratings