How to make your Vite web application compatible with older browsers?

How to make your Vite web application compatible with older browsers?

Published on: November 9, 2024

Ensuring compatibility with older web browsers is crucial in website development. Without this support, visitors using outdated browsers may choose to leave your site.

Vite is a modern build tool and development server designed for fast web development. It was created by Evan You, the creator of Vue.js. Vite leverages native ES modules in the browser for development, allowing for instant module hot reloading and a significantly faster development experience compared to traditional bundlers.

In this post, you will configure few settings in your Vite web application to support older browsers.

About browser compatibility

Browser compatibility is crucial for web applications, as it ensures they function correctly and consistently across various web browsers and their versions. This involves maintaining the application's layout, functionality, and performance regardless of the browser used. Achieving browser compatibility requires addressing the differences in how browsers interpret and render HTML, CSS, and JavaScript.

In the context of Vite, browser compatibility means ensuring seamless functionality on both modern and older browsers. This requires careful consideration of the features and technologies used, as well as thorough testing to identify and fix any issues.

Supporting older browsers is essential for several reasons:

  • Accessibility: Not all users have access to the latest browsers or devices. By supporting older browsers, you ensure your application is accessible to a wider range of users, including those in areas with limited internet access or using older devices.
  • Market Share: Although older browser usage has declined, there are still significant numbers of users who rely on them. For example, Internet Explorer 11 still had a global market share of around 1% in 2021.
  • Enterprise Users: Many businesses and organizations, particularly in industries like finance, healthcare, and government, still use older browsers due to legacy systems or security policies. Failing to support these browsers could limit your application's adoption in these sectors.
  • User Experience: Providing a consistent and functional user experience across all browsers helps build trust and satisfaction among users. A user who encounters a broken or poorly functioning application on an older browser may be less likely to return or recommend your application.
  • Inclusive Design: Supporting older browsers is part of a broader commitment to inclusive design, which aims to create products that are accessible and usable by as many people as possible, regardless of their abilities or circumstances.

Setting up Vite project

To create a Vite project, run this command:

npm create vite@latest

During the creation process, you will be asked for a project name, a framework, and a variant (JavaScript or TypeScript, SWC or Babel; or Remix). The configuration in the blog post will work regardless of a chosen framework.

Vite legacy plugin

Vite legacy plugin allows applications built with Vite to support older browsers by automatically generating and serving legacy chunks for modern code. This plugin is useful for projects that need to support older browsers that do not support modern JavaScript features or syntax.

To set up Vite legacy plugin, install the plugin with this command:

npm install @vitejs/plugin-legacy --save-dev

After installing the plugin, modify the vite.config.js file to enable the Vite legacy plugin. The modified vite.config.js file would look like this (assumed that React with SWC is used):

import { defineConfig } from 'vite';

import react from '@vitejs/plugin-react-swc';
import legacy from '@vitejs/plugin-legacy';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    legacy({
      targets: ['firefox >= 52', 'chrome >= 49', 'safari >= 11', 'edge >= 12']
    })
  ]
});

You can read the documentation for Vite legacy plugin to learn more about how to configure the Vite legacy plugin.

Transpilation

Transpilation is the process of converting source code from one high-level programming language to another. In the context of browser compatibility, this typically involves converting newer ECMAScript (JavaScript) versions to older versions, allowing the code to run on older browsers.

In case of Vite web applications, Vite legacy plugin handles the transpilation process.

Polyfills

A polyfill is a piece of code that adds new functionality to an environment where it's not natively supported, often enabling older browsers to utilize features typically found in newer browsers.

In case of Vite web applications, Vite legacy plugin automatically injects some polyfills based on the target browser list. You can however add additional polyfills via Vite legacy plugin configuration. Here is example vite.config.js file with Vite legacy plugin and additional polyfills configured:

import { defineConfig } from 'vite';

import react from '@vitejs/plugin-react-swc';
import legacy from '@vitejs/plugin-legacy';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    legacy({
      targets: ['firefox >= 52', 'chrome >= 49', 'safari >= 11', 'edge >= 12'],
      additionalLegacyPolyfills: ["unfetch/polyfill", "abortcontroller-polyfill/dist/polyfill-patch-fetch"]
    })
  ]
});

The configuration above will make Vite legacy plugin include unfetch and abortcontroller-polyfill as additional polyfills for browsers that don't support ES modules.

Popular polyfill libraries include:

  • core-js – one of the most comprehensive polyfills libraries available; it provides polyfills for a wide range of ECMAScript features.
  • regenerator-runtime – a companion library to core-js that provides runtime support for generator functions and async/await.
  • unfetch – a minimal polyfill for the Fetch API.
  • whatwg-fetch – a polyfill for the Fetch API.
  • promise-polyfill – it provides support for the Promise API.
  • IntersectionObserver Polyfill – it provides support for the Intersection Observer API, which is useful for lazy loading and other performance optimizations.
  • Custom Event Polyfill – it provides support for the CustomEvent API, which is not available in some older browsers.
  • MutationObserver Polyfill – it provides support for the MutationObserver API, which is useful for detecting changes in the DOM.
  • URL Polyfill – it provides support for the URL API, which is not available in some older browsers.

CSS compatibility

To ensure CSS compatibility in your Vite web application, you can enable Autoprefixer, a PostCSS plugin that automatically adds vendor prefixes to CSS rules, allowing for better support in older browsers. PostCSS is a tool that transforms CSS using a JavaScript-based plugin system.

To enable Autoprefixer, install it with this command:

npm install postcss autoprefixer --save-dev

After installing Autoprefixer, enable it by creating or modifying the PostCSS configuration file (for example postcss.config.js). The modified configuration file looks like this:

export default {
  plugins: {
    autoprefixer: {}
  },
};

After configuring PostCSS to enable Autoprefixer, you can add the supported browser list for PostCSS to use in browserslist property in the package.json file. The package.json file would look like this after adding the browser list:

{
  "name": "example-vite-app",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@eslint/js": "^9.13.0",
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-legacy": "^5.4.3",
    "@vitejs/plugin-react-swc": "^3.5.0",
    "autoprefixer": "^10.4.20",
    "eslint": "^9.13.0",
    "eslint-plugin-react": "^7.37.2",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.14",
    "globals": "^15.11.0",
    "postcss": "^8.4.47",
    "vite": "^5.4.10"
  },
  "browserslist": [
    "chrome 49",
    "firefox 52",
    "safari 11",
    "edge 12"
  ]
}

You can also enable the PostCSS CSS variables plugin to transform CSS variables into a static representation. To enable the plugin, install it with this command:

npm install postcss-css-variables --save-dev

After installing the PostCSS CSS variables plugin, enable it by creating or modifying the PostCSS configuration file (for example postcss.config.js). The modified configuration file looks like this:

export default {
  plugins: {
    autoprefixer: {},
    "postcss-css-variables": {
      preserve: true
    }
  },
};

This configuration ensures that CSS variables are kept, and the fallback values are present in case of no CSS variable support.

Testing for browser compatibility

Ensuring that your Vite application works seamlessly across different browsers and their various versions is crucial for a smooth user experience. Here are some strategies and tools to help you effectively test browser compatibility:

Testing Strategies

  • Cross-Browser Testing: Test your application on multiple browsers, including modern browsers like Chrome, Firefox, Safari, and Edge, as well as older browsers like Internet Explorer 11. Ensure that your application's layout, functionality, and performance are consistent across all browsers.
  • Responsive Design Testing: Test your application on different screen sizes and devices to ensure that it is responsive and looks good on all devices. Use tools like Chrome DevTools to simulate different screen sizes and devices.
  • Automated Testing: Use automated testing tools to run tests across multiple browsers and devices simultaneously. Write tests for critical functionality and ensure that they pass on all supported browsers.
  • Manual Testing: Perform manual testing to catch issues that automated tests might miss. Test common user flows and edge cases to ensure that your application works as expected.
  • Performance Testing: Test your application's performance on different browsers and devices. Use tools like Lighthouse to measure performance metrics and identify areas for improvement.
  • Accessibility Testing: Ensure that your application is accessible to users with disabilities. Use tools like the WAVE Web Accessibility Evaluation Tool to identify and fix accessibility issues.

Testing Tools

  • BrowserStack: A popular cloud-based testing platform that allows you to test your application on a wide range of browsers and devices. Features include live interactive testing, automated testing, and visual regression testing.
  • Sauce Labs: A cloud-based testing platform that provides access to a large number of browsers and devices for testing. Features include automated testing, live interactive testing, and visual testing.
  • LambdaTest: A cloud-based testing platform that offers cross-browser testing, automated testing, and real-time testing. Features include live interactive testing, automated screenshot testing, and responsive testing.

Best Practices

  • Define Your Supported Browsers: Clearly define the browsers and versions that you will support. Prioritize testing based on your target audience and analytics data.
  • Use a Testing Matrix: Create a testing matrix that lists all the browsers, versions, and devices you need to test. Track the status of each test case and ensure that all critical functionality is covered.
  • Automate Where Possible: Automate repetitive tests to save time and ensure consistency. Use tools like Selenium, Cypress, or Puppeteer to write automated tests.
  • Test Early and Often: Incorporate browser compatibility testing into your development workflow. Test early in the development process to catch issues before they become more difficult to fix.
  • Document and Report Issues: Document any issues you find during testing and report them to your development team. Use a bug tracking system to track and prioritize issues.
  • Continuous Integration: Integrate browser compatibility testing into your continuous integration (CI) pipeline. Automatically run tests on every commit to catch issues early.

Conclusion

Ensuring browser compatibility is not just an option but a necessity in today's diverse digital landscape. By configuring your Vite web application to support older browsers, you can significantly enhance the accessibility and user experience of your site. The Vite legacy plugin, along with tools like Autoprefixer and various polyfills, provides a robust framework to achieve seamless functionality across a wide range of browsers.

Implementing these strategies not only broadens your audience reach but also fosters trust and satisfaction among users who might otherwise be left behind. Regular testing, using both automated and manual methods, is crucial to identify and fix any compatibility issues early in the development process.

By following the best practices outlined in this post, you can create a more inclusive and user-friendly web application that performs consistently across different browsers and devices. This commitment to compatibility will ultimately contribute to the success and longevity of your web project.

Happy coding, and may your Vite applications be compatible and accessible to all!