How to Inject a Global with Web Extensions in Manifest V3

By  on  

For those of you not familiar with the world of web extension development, a storm is brewing with Chrome. Google will stop support for manifest version 2, which is what the vast majority of web extensions use. Manifest version 3 sees many changes but the largest change is moving from persistent background scripts to service workers. This...is...a...massive...change.

Changes from manifest version 2 to version 3 include:

  • Going from persistent background script to a service worker that can die after 5 minutes
  • No use of <iframe> elements or other DOM APIs from the service worker
  • All APIs have become Promise-based
  • Restrictions on content from a CSP perspective

One function that web extensions often employ is executing scripts upon each new page load. For a web extension like MetaMask, we need to provide a global window.ethereum for dApps to use. So how do we do that with manifest version 3?

As of Chrome v102, developers can define a world property with a value of isolated or main (in the page) for content scripts. While developers should define content_scripts in the extension's manifest.json file, the main value really only works (due to a Chrome bug) when you programmatically define it from the service worker:

await chrome.scripting.registerContentScripts([
  {
    id: 'inpage',
    matches: ['http://*/*', 'https://*/*'],
    js: ['in-page.js'],
    runAt: 'document_start',
    world: 'MAIN',
  },
]);

In the example above, in-page.js is injected and executed within the main content tab every time a new page is loaded. This in-page.js file sets window.ethereum for all dApps to use. If the world is undefined or isolated, the script would still execute but would do so in an isolated environment.

Manifest version 3 work is quite the slog so please hug your closest extension developer. There are many huge structural changes and navigating those changes is a brutal push!

Recent Features

  • By
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

  • By
    Regular Expressions for the Rest of Us

    Sooner or later you'll run across a regular expression. With their cryptic syntax, confusing documentation and massive learning curve, most developers settle for copying and pasting them from StackOverflow and hoping they work. But what if you could decode regular expressions and harness their power? In...

Incredible Demos

  • By
    CSS Background Animations

    Background animations are an awesome touch when used correctly.  In the past, I used MooTools to animate a background position.  Luckily these days CSS animations are widely supported enough to rely on them to take over JavaScript-based animation tasks.  The following simple CSS snippet animates...

  • By
    Reverse Element Order with CSS Flexbox

    CSS is becoming more and more powerful these days, almost to the point where the order of HTML elements output to the page no longer matters from a display standpoint -- CSS lets you do so much that almost any layout, large or small, is possible.  Semantics...

Discussion

    Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!