In IE11 our custom scripts/polyfills.js sometimes do not work.
Here's contents of scripts/polyfills.js:
import 'core-js';
import 'react-app-polyfill/ie9';
console.log('MY POLYFILL!');
Here's contents of next.config.js:
const withTM = require('next-transpile-modules');
const withPlugins = require('next-compose-plugins');
const withBundleAnalyzer = require('@next/bundle-analyzer');
const withSourceMaps = require('@zeit/next-source-maps');
const nextConfiguration = {
experimental: {
granularChunks: true,
modern: false
},
useFileSystemPublicRoutes: false,
poweredByHeader: false,
webpack: (config, { defaultLoaders }) => {
const originalEntry = config.entry;
config.entry = async () => {
const entries = await originalEntry();
if (
entries['main.js'] &&
!entries['main.js'].includes('./scripts/polyfills.js')
) {
entries['main.js'].unshift('./scripts/polyfills.js');
}
return entries;
};
config.module.rules.push({
test: /\.svg$/,
use: [
defaultLoaders.babel,
{
loader: 'react-svg-loader'
}
]
});
return config;
}
};
module.exports = withPlugins(
[
[withTM, { transpileModules: ['ui-lib'] }],
[withSourceMaps(), { devtool: 'source-map' }],
[withBundleAnalyzer, { enabled: process.env.ANALYZE === 'true' }]
],
nextConfiguration
);
Error example -

Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20ref%2C%20props%2C%20_owner%7D&args[]=
Scripts in html look like this -

Our custom polyfill is part of main.js which is loaded after frameworks.js bundle (the place where React is). If you can see both scripts are async meaning that sporadically frameworks.js loads first which ends in error.
If we include <script src="https://cdn.polyfill.io/v2/polyfill.min.js" /> in the head of the page error disappears.
Question - what's the new way to use custom polyfills with Next.js 9.2.2 and granular chunks built-in?
Thanks in advance!
Is this still up to date - https://github.com/zeit/next.js/tree/canary/examples/with-polyfills ?
the workaround that worked for us -
webpack: (config) => {
const originalEntry = config.entry;
config.entry = async () => {
const entries = await originalEntry();
// add custom polyfills into specific next.js bundle
// https://github.com/zeit/next.js/issues/10794
const nextPolyfillPath = 'static/runtime/polyfills.js';
const nextPolyfills = entries[nextPolyfillPath];
if (nextPolyfills) {
entries[nextPolyfillPath] = [nextPolyfills, './scripts/polyfills.js'];
}
return entries;
};
}
FWIW the polyfills you're showing:
import 'core-js';
import 'react-app-polyfill/ie9 ';
Will not be needed when 9.3 is out (or if you use next@canary currently). As all needed polyfills are included.
Also, you're relying on a internal Next.js implementation detail that may change at any time鈥攖his is not covered by semver:
// This is reserved for Next.js use only
const nextPolyfillPath = 'static/runtime/polyfills.js';
Also, you're relying on a internal Next.js implementation detail that may change at any time鈥攖his is not covered by semver
@Timer, yes it's not the best way but unfortunately we couldn't find a better one. Is it possible to introduce a custom webpack entry in next.config.js?
FWIW the polyfills you're showing:
Will not be needed when 9.3 is out (or if you use next@canary currently). As all needed polyfills are included.
@timneutkens that's good but we actually encountered another issue. You're forcing polyfills to be always noModule https://github.com/zeit/next.js/blob/master/packages/next/pages/_document.tsx#L637.
It means that if we put our own polyfills inside Next.js polyfill (e.g. IntersectionObserver polyfill) it will not load in browser that support noModule but doesn't support the feature (e.g. Safari 11 - https://caniuse.com/#search=nomodule).
This leads to very ugly solutions like extending the NextScript and overwriting getPolyfillScripts function 馃槵
You're forcing polyfills to be always noModule
This is because you're using a private Next.js API and not the suggested method that the with-polyfills example showcases.
To clarify my previous comment, do not edit the static/runtime/polyfills.js entrypoint.
It will break.
Next.js 9.3 will mostly solve this, and the default recommendation for polyfill inclusion will be to import in the top of pages/_app.js.
Can you try upgrading to next@canary?
This is because you're using a private Next.js API and not the suggested method that the with-polyfills example showcases.
@Timer I've explained the problem with with-polyfills example in the initial comment - https://github.com/zeit/next.js/issues/10794#issue-574184762
in short - when custom polyfill is part of main.js bundle it is sometimes loaded after frameworks.js bundle and produces React error -
Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20ref%2C%20props%2C%20_owner%7D&args[]=
Yup, the recommendation is still to use the with-polyfills example.
Figuring out why the Frameworks bundle being evaluated before the Main bundle having an effect is what needs investigated (this is speculation, right?).
Rendering should still be suspended until main.js loads, so I'm not sure why React would complain in this case (unless something reads globals once during module initialization).
We have multiple production integration tests that ensures Next.js works in IE11.
Can you please provide a fully reproducible demo so we can help debug this?
Can you please provide a fully reproducible demo so we can help debug this?
I will prepare something
just a note that this problem - https://github.com/zeit/next.js/issues/10794#issuecomment-594023086 was not the case in Next.js v9.0.5
just a note that this problem - #10794 (comment) was not the case in Next.js
v9.0.5
To second this, I had issues polyfilling for IE11 with the with-polyfills example in a completely fresh project. Here's an example: https://github.com/mattclough1/next-ie11-polyfill-test
I also attempted to upgrade to next@canary, which had the same result, but it seems like the polyfilling approach may be different for that version.
I was able to make it work by downgrading to v9.0.8
None of the polyfills outlined here: https://github.com/mattclough1/next-ie11-polyfill-test/blob/master/client/polyfills.js
are needed if you upgrade to next@canary, Next.js will correctly provide them (and every other polyfill needed for IE11).
@timneutkens Hey Tim, I just updated the example by removing next config and polyfills script, and updating to next@canary and I'm getting the same result in IE11.
@timneutkens, I also tried @mattclough1's repo with v9.3.0 and got the same result.
@mattclough1 same here. with-polyfills example approach isn't working anymore. Tested on v9.4. (we're using client/polyfills.js not only for IE11, but also for critical-css https://github.com/dotsunited/load-css-polyfill)
Closing this issue as it's no longer relevant for a Next.js 9.3+ world and our docs now explain how to polyfill with a warning for this added to with-polyfills.
Most helpful comment
@mattclough1 same here.
with-polyfills exampleapproach isn't working anymore. Tested on v9.4. (we're usingclient/polyfills.jsnot only for IE11, but also for critical-css https://github.com/dotsunited/load-css-polyfill)