Migrating Chrome Extensions to Manifest v3

Introduction

Migrating your Chrome extensions from Manifest V2 to V3 is a necessary step to ensure your extensions remain functional and secure as Google phases out support for Manifest V2. Manifest V3 introduces significant changes aimed at enhancing security, performance, and privacy for users.

Google's Chrome web browser recently forced all extensions to upgrade to the Manifest v3 version or risk being removed from the Chrome Web Store and be removed from all web browsers. There were quite a few known issues and community backlash, but Google ended up standing firm on many of the changes.

This article will give an overview of the key differences, preparation steps, and the actual migration process, providing detailed instructions and examples to help you smoothly transition your extensions to Manifest V3.

Key Differences between Manifest V2 and V3

Manifest V3 brings several notable changes that impact how Chrome extensions are developed and maintained:

  • Background Scripts: In Manifest V2, background pages allowed persistent background scripts. Manifest V3 replaces this with service workers, which are more efficient and only run when needed.

  • Permissions Handling: Manifest V3 introduces changes in how permissions are declared and granted, focusing on reducing the extension's access to sensitive data.

  • Content Security Policy (CSP): The CSP has been tightened in Manifest V3, restricting inline scripts and other potential security risks.

  • API Changes: Some APIs available in Manifest V2 have been deprecated or replaced in Manifest V3. This includes the removal of the chrome.webRequest API's ability to block requests, which is now replaced by declarativeNetRequest.

  • New Features: Manifest V3 includes new features such as declarativeNetRequest, allowing developers to define rules for network requests directly in the manifest file.

Preparing for Migration

Before starting the migration process, it's crucial to prepare your existing extension code and development environment:

  1. Review Existing Code: Analyze your current extension codebase to identify parts that need updating.

  2. Understand New Requirements: Familiarize yourself with the new requirements and restrictions introduced in Manifest V3.

  3. Backup and Version Control: Ensure you have a backup of your current extension and use version control systems like Git to manage changes.

  4. Test Environment Setup: Set up a testing environment to test the updated extension thoroughly before deploying it.

Updating the Manifest File

The manifest.json file is the core of any Chrome extension, and several changes are required to migrate from Manifest V2 to V3:

  1. Update Manifest Version: Change the "manifest_version" from 2 to 3.

     {
       "manifest_version": 3,
       // Other properties
     }
    
  2. Service Workers: Replace background scripts with service workers.

     {
       "background": {
         "service_worker": "background.js"
       }
     }
    
  3. Permissions: Update the permissions section to reflect new requirements and best practices.

     {
       "permissions": ["storage", "activeTab"]
     }
    
  4. Host Permissions: Separate host permissions from other permissions.

     {
       "host_permissions": ["https://example.com/*"]
     }
    
  5. CSP Changes: Update the CSP to comply with new restrictions.

     {
       "content_security_policy": {
         "extension_pages": "script-src 'self'; object-src 'self'"
       }
     }
    

Adapting Background Scripts

Manifest V3 requires using service workers instead of background pages. This change improves performance and efficiency but requires adapting your background scripts:

  1. Service Worker Setup: Define a service worker in your manifest file.

     {
       "background": {
         "service_worker": "background.js"
       }
     }
    
  2. Event Listeners: Update your background script to use event listeners suitable for service workers.

     // background.js
     chrome.runtime.onInstalled.addListener(() => {
       console.log("Extension installed");
     });
    
     chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
       // Handle messages
     });
    
  3. Handling State: Use IndexedDB or chrome.storage to manage persistent state, as service workers do not support long-lived state.

Adjusting API Usage

Manifest V3 deprecates some APIs and introduces new ones. Updating your extension involves replacing deprecated APIs and utilizing new ones where necessary:

  1. Declarative Net Request: Replace chrome.webRequest with chrome.declarativeNetRequest.

     {
       "declarative_net_request": {
         "rule_resources": [{
           "id": "ruleset_1",
           "enabled": true,
           "path": "rules.json"
         }]
       }
     }
    
  2. Runtime Messaging: Ensure your messaging API calls are compatible with service workers.

     // Sending a message from a content script
     chrome.runtime.sendMessage({ greeting: "hello" }, (response) => {
       console.log(response);
     });
    
     // Receiving a message in a service worker
     chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
       if (message.greeting === "hello") {
         sendResponse({ farewell: "goodbye" });
       }
     });
    

By following these guidelines and making the necessary updates, you can ensure your Chrome extension is compliant with Manifest V3, enhancing its security, performance, and user privacy.

Updating Permissions

Updating permissions in your manifest file is crucial to comply with Manifest V3's stricter security policies. Here are the steps to update your permissions:

  1. Simplified Permissions: Define only the permissions your extension absolutely needs. This minimizes the risk and increases user trust.

     {
       "permissions": ["storage", "activeTab"]
     }
    
  2. Host Permissions: Separate host permissions from other permissions.

     {
       "host_permissions": ["https://example.com/*"]
     }
    
  3. Optional Permissions: Use optional permissions for features that are not critical to the extension's core functionality.

     {
       "optional_permissions": ["tabs"]
     }
    

Content Security Policy Changes

Manifest V3 enforces a stricter Content Security Policy (CSP) to enhance security. Follow these steps to update your CSP:

  1. Define CSP in Manifest: Add or update the content_security_policy property in your manifest file.

     {
       "content_security_policy": {
         "extension_pages": "script-src 'self'; object-src 'self'"
       }
     }
    
  2. Inline Scripts: Remove inline scripts from your HTML files and move them to external JavaScript files.

     <!-- Before -->
     <script>
       console.log("Inline script");
     </script>
    
     <!-- After -->
     <script src="script.js"></script>
    
  3. Eval and New Function: Avoid using eval and new Function as they are not allowed in Manifest V3.

Testing the Updated Extension

Thorough testing ensures that your extension works correctly after migration. Follow these steps to test your extension:

  1. Load Unpacked Extension: In Chrome, go to chrome://extensions/, enable Developer mode, and load your unpacked extension.

  2. Test All Features: Verify that all features and functionalities of your extension work as expected.

  3. Check for Errors: Use the Chrome Developer Tools to check for any errors or warnings.

  4. Automated Testing: Consider setting up automated tests using tools like Selenium or Puppeteer to ensure consistent behavior.

Publishing the Updated Extension

Once you've tested your extension, you're ready to publish it on the Chrome Web Store. Follow these steps:

  1. Update Version Number: Increment the version number in your manifest file.

     {
       "version": "2.0.0"
     }
    
  2. Prepare Package: Zip your extension files, including the updated manifest file.

  3. Submit to Chrome Web Store: Go to the Chrome Web Store Developer Dashboard, upload your ZIP file, and submit it for review.

  4. Monitor Feedback: After publishing, monitor user feedback and address any issues that arise promptly.

Case Studies and Examples

One app that had to make this migration was Block Sender, which is an email management tool. Significant changes had to be made to get the extension to comply with Manifest V3 requirements. Here are some of the changes they had to make:

  1. Background Scripts: The background scripts had to be converted to service workers. While this seemed simple on the surface, it required many changes to not only the Block Sender codebase but also many of the libraries it was using.

  2. Permissions Handling: The permissions handling had to be updated to reflect the new requirements. This involved a thorough review of the permissions used by the extension and removing any unnecessary ones. Requests were being intercepted to add a new user agent header, which was no longer allowed in Manifest V3 and had to be removed.

  3. Service Worker Limitations: Service workers have limitations compared to background scripts, such as not being able to access some APIs directly. You also have to manage workers, for example, if they need to be "woke up" to handle a message. This added extra complexity to the listeners and message handling in the extension.

  4. Cross-Browser Compatibility: While the changes were made to comply with Chrome's new requirements, the team also had to ensure that the extension remained compatible with other browsers like Firefox. Firefox does not yet have full support for Manifest V3, so the team had to maintain two codebases for the time being.

Conclusion

Migrating your Chrome extension from Manifest V2 to V3 is essential for maintaining its functionality and security. By following the steps outlined in this guide, you can ensure a smooth transition. Remember to test thoroughly and monitor user feedback after publishing your updated extension. With these updates, your extension will benefit from enhanced security, better performance, and improved privacy controls.