The primary objectives for this milestone were to decide whether to use the
<link> tag and then implement the same in Gecko (Firefox's browser engine). I'm happy to inform you that both of these goals have been successfully accomplished!
Spoiler alert: using
<link> is my recommended way forward for the Web Monetization community. More details below.
The objectives under the current milestone were:
- Study relevant specifications and Gecko infrastructure.
- Discuss and decide whether to use the
- Integrate the said element's behavior in Gecko.
Following a discussion outlining various pros and cons of each tag, and a deep dive into various specifications and Gecko infrastructure, we decided to go with the
<link> tag. This means the browser should support:
<link rel="monetization" href="URL" />`
<meta name="monetization" content="$paymentPointer" />
This is a breaking change to the specification, and, because of the impact of the change, a difficult decision for the WM community to adopt. We would essentially be abandoning "payment pointers" — which are well-known in the Web Monetization community — with something that better aligns with the web platform: using regular URLs. I won't get into the technical details here, but you can read the summary of my research in the GitHub issue.
Once the WM community reached consensus to to go with the
<link>, I proceeded to implement this declarative API in a fork of Firefox at GitHub. Note that the present implementation only handles the fetching and processing of the monetization endpoint (payment pointer), and not the actual monetization.
You can download the current implementation from GitHub. At the time of writing, it supports:
- Getting monetization details from the first valid
<link>element at any time. That is, if you add or remove or modify the link elements, the monetization info is updated. This way, dynamic monetization tags support revenue sharing and single-page applications (SPA) use cases.
- Monetizing only the currently visible tab in the browser (no background tabs).
- Fetching the payment info with proper HTTP headers, while respecting CORS policy and cache-control behavior, as defined by the SPSP protocol.
- To preserve user's privacy, no referrer information (i.e., the URL of current website) or cookies are sent to the monetization receiver (e.g. Uphold).
- Allowing only legitimate payment pointers through the use of a Content Security Policy (CSP). By using the
monetization-src <source>;CSP directive, we can enforce monetizing only certain payment pointers so that malicious actors cannot steal your money.
- Logging error messages and other information to the browser console.
The implementation presently does not support monetization of embedded content like iframes. That needs more discussion from the security and performance perspective, and also requires specification of various edge cases. Nevertheless, those cases have been captured in a GitHub issue.
Note: This section contains some technical details and my journey.
I started with going through with various specifications, specifically HTML, DOM, Fetch, InterLedger Protocol, Payment Pointers, Web Monetization, W3C Tag Design Principles, RFC8288 (Web Linking) and RFC2718 (Guidelines for new URL Schemes), to get a better understanding of the platform as a whole.
After familiarizing myself with the specs, I went through Firefox code-base and documentation to analyze how the existing Gecko infrastructure can be used to support
<link> monetization tags.
After studying for a few weeks and various discussions with Marcos Cáceres, I started to summarize my notes into a write-up that can be used by the Web Monetization community to settle the debate whether we should move forward with
As of today, we've settled on using the
Now as we can't just implement a specification that is not presently on standards track into a browser, I created my own fork of Firefox on GitHub. This allowed me to prototype quickly, without the hassle of integrating a particular feature flag for Web Monetization (generally, something that can be time consuming to add).
Aside: One thing I found interesting is that GitHub doesn't let you push a large repository (4GB in this case) in one go. I had to write a script to split the repository into smaller batches of commits and push them instead (that took a while).
I'll write more on temporarily maintaining a fork of a project as large as Firefox, and my Firefox development workflow some other day on my website.
The easiest part was to support the
HTMLLinkElement.relList.supports() API. I just had to add a new string literal for
rel="monetization". This can be easily used to detect whether a browser supports Web Monetization. Feels good to see some quick progress - git commit!
During the earlier prototyping, I decided to implement the
The JSM approach required a change in thinking — from low level hyper-optimized stuff to high level design. Though, it felt weird to not have any type-checking/hinting support in the editor — I had to jump into WebIDL definitions to understand what JSM can do. Fast forward a few days, I had a working implementation of what's mentioned above (except CSP, which required a lot more fiddling across 18 files).
Satisfied with the current implementation, I created a Firefox Nightly release for you to try! You can find the download links in the wiki.
After extracting the downloaded archives, you need to run it from command line as:
--jsconsole flag opens Firefox with a "multi process browser console" window, which will display various Web Monetization metadata, logs and error messages.
Next, I'll work towards bringing the actual Web Monetization support in Firefox. For this, we'll first need to specify the role of WM agent (browser extension) and the communication between the WM agent, browser, and the website. Once that's done, we'll hopefully have a working native implementation of Web Monetization. While we discuss and decide above, we'll try to formalize the specification based on the things we've learned so far.
We're already discussing the role of WM agent over GitHub. Feel free to join!
I'm curious to understand how we should go with the monetization of iframes and other embedded content like images and videos. Say, you're the page owner, how do you think we should monetize third party content embedded in your site? Conversely, how would you like your content to be monetized if it's embedded in some other website? One idea that comes to mind is to only allow the visible content to be monetized as the user scrolls through the site, but it adds quite a lot of complexity to the browser and has many edge cases. Is this something you would love to see in the first version of the Web Monetization standard, or it can be deferred for later? Let us know what you think in comments below or at GitHub.
Thanks to the Grant for the Web for supporting my workstation purchase. I can't emphasize enough what a difference this has made to my development flow: I'm able to compile Gecko in record time - nearly 7 minutes, compared to 80 minutes on my previous laptop. This enabled me to quickly prototype various implementation strategies without wasting hours waiting for Gecko to compile!