DEV Community

Oxford Harrison
Oxford Harrison

Posted on

Reflex-Based Web Monetization API - Hackathon Submission

The Web Monetization API has seen a lot of integration patterns that are tuned to many of the current frontend frameworks and developer tools. With each pattern serving only a specific community, I decided to explore a vanilla-level technology for Web Monetization for the rest of the web.

What I built

A Reflex-based Web Monetization API that is consumable as a plain, but reactive JavaScript object instead of an EventTarget interface. This is a new API that promises new foundational possibilities! Here is my introductory DEV post to this project, where I explained key problems solved and a few use cases.

To highlight, the goal of this project is to provide a minimalist API that lets us implement web monetization with zero boiler plate.

// You initialize a WebMonetization instance with a payment pointer
let monetization = WebMonetization.init('$ilp.example.com/me');

That instance object will now be a joy to consume! For example, instead of the mental stress of maintaining the relationship between the standard document.monetization.state property and its three state-change events (monetizationpending, monetizationstart, monetizationstop), we would simply observe this object's .state property directly.

// Observe the state property live
Reflex.observe(monetization, 'state', newState => {
    console.log(newState); // pending, started, stopped
});

If we were to need dynamic start and stop of the payment stream, we wouldn't have to worry about dynamically creating and removing the appropriate <meta> tag. The monetization.start() and monetization.stop() methods automatically take care of that.

And what about tracking progress and deriving totals? The monetization.progress would come into play.

// Observe the progress property live
Reflex.observe(monetization, 'progress', progressDetails => {
    console.log(progressDetails.currentTotal); // Totals since calling the instance's start() method
    console.log(progressDetails.sessionTotal); // Totals since initializing the instance
});

An observable object just gives us only properties to think about - in reading their values both statically and dynamically.

// The totals at any given point in time
console.log(monetization.progress.currentTotal);

// The totals on the fly
Reflex.observe(monetization, 'progress', progressDetails => {
    console.log(monetization.progress.currentTotal);
});

Now, what's even more interesting is that in real life, we can do without observing anything! Observable objects like this are the perfect subjects for the ScopedJS technology! We can simply bind any elements to properties of these object to achieve any UI behaviour. ScopedJS's automatic observability will do the heavy-lifting of keeping everything in sync.

First we would make the WebMonetization instance available to scoped scripts.

let ENV = window.WebNative.ScopedJS.ENV;
ENV.globals.monetization = monetization

And we could simply orchestrate behaviour in the document on the fly!

Here is an example taken from the introductory post where we toggle the visibility of an exclusive section on the page by simply referencing the monetization.state property.

<body>
    <div id="exclusive">
        This is exclusive content!
        <script type="text/scoped-js">
          // This statement will run as a reflex action
          // to each change in monetization.state
          this.classList.toggle('hidden', monetization.state !== 'started');
        </script>
    </div>
</body>

And as other examples in there show, we could go to weave-in more monetization logic as part of our UI's presentational logic.

Submission Category:

Foundational Technology

Demo

The project support banner at web-native.dev featuring Web Monetization was implemented using the Reflex-based Web Monetization API.

Link to Code

This API is currently primarily documented in the introductory post. An official documentation will be arriving soon for the entire list of Reflex-based components at Web-Native.

Repository:

Reflex Components

Application components and client-side APIs implemented as objects with observable properties.

Documentation

The Reflex Components Official Guide

Issues

To report bugs or request features, please submit an issue to this repository.

License

MIT.

)

How I built it

I am creating this project as part of the Web-Native project - a larger mission to make certain modern UI development techniques possible at platform level. With the Reflex-based monetization API now part of the Web-Native suite, we now have an all-native way to designing the UI.

  • Write in Vanilla. - Leave your markup in vanilla HTML - not even a template syntax is required. And yes! none of a framework code (<IfWebMonetized>...</IfWebMonetized>) that would look simple on the eyes but incur unnecessary tooling and engineering, and the inevitable compile step. And, probably one of the most important advantages with a markup-level technology, this implementation makes code more universal! It lets us integrate seamlessly with other wonderful tools that read and write HTML. So, instead of the lock-in with an all-JS stack, a PHP backend that spits out HTML could be everything.
  • Write your Logic. - The Reflex-based monetization API is not some <custom-element /> that would encapsulate only a predetermined behaviour. It works along with the ScopedJS foundational technology that provides platform-level capabilities for creating anything, offering more flexibility and control.
  • Maintain the Modern UI Development Pattern. - We simply cannot remember a time without componentization and reactivity anymore! Bringing the Web Monetization API to vanilla HTML does not trade these patterns either. What we get instead is Web Monetization plus componentization plus reactivity - all out of the realm of JavaScript files! (You may want to check out CHTML for the rest of the news.)

Additional Resources/Info

The overall theme of this project is provided by the Web-Native project.

Top comments (0)