How to Support IE11 Users as You Move to Angular 13
Mark Thompson
Posted on November 11, 2021
IE 11 won't be supported in Angular 13. You can support it in 12 while you migrate to 13, or drop support. Either way, you need to act.
Internet Explorer 11 is a legacy browser and support for it in Angular 13 is being dropped officially. Sticking with Angular 12 is not a viable long term option. Here are ways to support your users when upgrading your Angular version.
Table Of Contents
- Update tsconfig.json and populate polyfills
- Use Differential Loading
- How to Customize User Experience for IE 11
- How to Drop Support for IE 11 the Good Way
As an Angular developer, you want to provide support for as many browsers as you can, but in the case of Internet Explorer 11, this is becoming increasingly difficult, and soon will no longer be possible. Current market share is likely less than 1% and will drop even more as Microsoft retires IE 11 in June 2022.
Even more challenging is that Angular 12 doesn't offer support for IE 11 by default, and Angular 13, coming out next week, is completely dropping support.
Choose a Support Path
There are two ways you can support IE 11 with Angular 12 as you prepare to migrate to Angular 13:
Update
tsconfig.json
to use ES5 and update polyfills.ts for ES6/ES7Use Differential Loading
Or you could decide to drop support for IE 11. You should customize the user experience because if you don't, users will get a blank screen.
Update tsconfig.json and populate polyfills
By default, Angular compiles ES6 or ES7. IE 11 only supports ES5. You can update your tsconfig.json
to target ES5. You'll also need to populate your Angular project polyfills.
Advantages of updating tsconfig.json and including polyfills:
- Configuration prepares building and local development for IE 11 support
- Faster builds than using Differential Loading
Disadvantages:
- Imports a lot of polyfills and bloat bundle for legacy AND modern browsers
- This approach has been abandoned as a standard after Angular 7
Definitions
You'll change the target variable in tsconfig.json, and populate the polyfills file that came with the Angular project. If you're not familiar with these things, here's what they are.
target: JavaScript language version for emitted JavaScript.
Angular polyfills are fallbacks for missing JavaScript behavior. There are two types:
- Browser polyfills that are applied before loading ZoneJS.
- Application imports that are files imported after ZoneJS that should be loaded before your main file.
Polyfills are applied in this order: Browser polyfills → Import ZoneJS → Application imports. You will only need to focus on browser polyfills.
The Steps
- Open
tsconfig.json
and updatetarget
toes5
.
- Open
polyfills.js
found in the src directory and addimport 'core-js';
under browser polyfills.
NOTE: When serving the application, the build was at 505.3 kB. After adding the import of core-js, it's 1.2 MB. 😬
Use Differential Loading
Differential Loading is the more modern technique introduced in Angular 8. The approach here is to make two builds. One uses ES5 syntax and a more modern one that uses ES6 syntax. The ES6 build won't include as many polyfills and going to be much smaller. The ES5 build will have polyfills and be more bloated.
Considerations
Advantages of using differential loading:
- Smaller bundle sizes for modern browsers
- ES5 bundle includes all required polyfills for legacy browser support automatically
- Latest approach to supporting legacy browsers
Disadvantages:
- Creates two bundles so longer build times
- Extra configuration is required for local development for legacy browsers
The Steps
Find your browser's list file. Depending on the version of Angular, it will be
.browserslistrc
orbrowserslist
.Remove the word "not" from the IE 11 line.
Before I continue, I'll explain what just happened.
After you changed the browser's list file, when you look at your Angular project through Inspector, you'll see three additional scripts. Here's what it looked like before:
And after:
You will have two runtimes, two polyfills, and two mains. Modern browsers will only run the top script that is of type module
. Legacy browsers like IE 11 will run the second one, the nomodule
.
NOTE: The rest of these steps are only needed if you want to run the project locally in development mode if you only use differential loading.
Next up, you're going to create two new custom files in your application, a
polyfills.es5.js
in the src directory andtsconfig.es5.json
at the root of your project.Next steps are similar what you did for older
tsconfig.json
method above. Populate the polyfills file with your import. Then switch the tsconfig target to ES5 and to include your new polyfills file.
- Now you're going to update
angular.json
.
Add a new build configuration. You can see on line 72 that I've added development-es5
, where I copied all of the properties for development
, and added two extra ones:
"tsConfig": "tsconfig.es5.json",
"polyfills": "src/polyfills.es5.ts"
- To use this build when you serve locally, you need to add this new build configuration to the serve configurations.
As I did starting at line 94 above, use the same identifier, development-es5
, and set browserTarget
to "handling-ie:build:development-es5"
. Now you can serve your project for IE 11 using ng serve --configuration development-es5
.
Why You Shouldn't Just Drop Support
You could drop support for IE 11. If you do, here's what an IE 11 user will see:
Not a good user experience. Instead, we can change a few things to let our visitor know that they need a different browser.
How to Customize User Experience for IE 11
You don't want IE 11 users to see a white page. Instead, you can warn them about their browser or tell them to do something. Instead, you can use the same approach as you did with Differential Loading. Set a flag and take advantage of that flag to write specific code for legacy browsers.
So you can call a no-es6.js
script that will only run for legacy browsers by using the nomodule
attribute.
In this script, I set a property, nomodule
, to true on window
. Throughout my application, I can check for that value and I can see whether or not you are using IE.
Note that nomodule
is a custom property. That's not something that window
has. Create a window.d.ts
in the src directory and add that property to global
.
How to Drop Support for IE 11 the Good Way
Finally, there will probably come a time when you offer no support for IE 11 and you've turned off differential loading or whatever you were using. How do you still provide a good user experience?
You can update your browser's list to say not IE, but your users will see a blank page.
Instead, you can update the no-es6.js
script.
You can do all sorts of things here. In my example, I check for iIE. If I think you’re using IE, I’m going to try to use the microsoft-edge
handler and open Edge to navigate the site. On IE, I’ll navigate you to a Microsoft support page that explains that IE is dropping support soon. If you're not using IE, I navigate you to a generic "hey, your browser is bad"page.
What Will You Do?
To sum it all up, there are two main ways to support IE 11. You can update your tsconfig.json
, or you can use Differential Loading.
And you can provide a better user experience when you are dropping support and you can also provide a better user experience when you fully drop support. It's definitely time to decide what you'll do.
What do you think you'll do? Have these methods been helpful? Do you have other techniques for managing IE 11 and Angular 13? We'd love to know your thoughts. Drop us a note in the comments section below.
Resources
Posted on November 11, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.