Search code examples
angularpolyfillsangular14

Angular14: What is the official way to support older browsers?


What is the "Angular way" of supporting old browsers?

By default an Angular 14 app (built with angular-cli) supports only 20% of the browsers (browsersl.ist). Despite reading the relevant documentation, it is not clear to me how to enable support for older browsers too.

Changed .browserslistrc:

By default angular-cli (v14) generates this config:

last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR

I have modified this to the below. The coverage coverage should go from 20% goes up to 90%. However, still older devices are showing the "white screen of death".

> 0.2%, not dead

Some other related files:

tsConfig.json

Here angular cli (v14) puts these by default:

...
    "target": "es2020",
    "module": "es2020",
    "lib": [
      "es2020",
      "dom"
    ],
...

So, am I supposed to modify this? I've seen approaches that use separate tsConfig.json, for providing es6support too.

polyfills.js:

This file is supposed to provide "fills" for older browsers. However, from what I've read, here we should append only stuff unrelated to Angular, as anything that is angular-related will be automatically appended by the framework. Is my understanding correct?

Which is why the auto-generated polyfills.ts has the below section empty, without any inclussions)

// .... other stuff
/***************************************************************************************************
 * BROWSER POLYFILLS
 */

// ... stuff after polyfills

Solution

  • TLDR: 'scripts' optimization was the culprit!

    Narrowing down the issue:

    I was having some issues on ios12 browsers (iphone 6S device), which is quite old, but I couldn't get it to work despite enabling everything in .browserslistrc:

    last 20 iOS major versions
    

    --configuration=development was working:

    I noticed that the local version would work just fine on the old browser, but once deployed it would not. (I could not test that easily before).

    So after building for development mode, the deployed version also worked.

    --optimization=false was also working:

    Then, I noticed that building for production, but disabling optimizations also worked. So then I started looking for the specific flag that was causing the issue.



    Solution:

    After digging into the optimization flags, it turns out that scripts optimization was the problem. So doing the below works:

    'package.json':

    "optimization": {
      "scripts": false, <- DISABLED
      "styles": {
        "minify": true,
        "inlineCritical": true
        },
       "fonts": true
    },
    
    

    Notifying unsupported browsers:

    In any case, if a browser is not supported, is good to show some relevant message. The below will do just that, when angular has failed to bootstrap.

    <html>
    <!-- other stuff ... -->
    <script>
      function handleUnsupportedBrowsers() {
        var appRoot = document.getElementsByTagName('app-root')[0];
        if (appRoot && appRoot.innerHTML === '') {
          appRoot.innerHTML = '<h1>Unsupported Browser (too old)</h1>' + 
            '<p>Please use a modern browser!</p>';
        }
      }
    </script>
    <body onload="handleUnsupportedBrowsers()">
      <app-root></app-root>
    </body>
    </html>