Web Monetization Plugin for Gridsome
Tags: gftwhackathon, vue, webmonetization
Published: 2020-06-02 20:13:31

#### **UPDATE: This plugin is now featured on the [homepage of the WICG's Web Monetization website](https://webmonetization.org/) under "Web Monetization Tools". So excited! 😄**

<hr>

Here's my entry for the [Grant For The Web x DEV Community hackathon](https://dev.to/devteam/announcing-the-grant-for-the-web-hackathon-on-dev-3kd1). I hope you find it useful!

*[Link to repository](https://github.com/Sergix/gridsome-plugin-monetization)*
*[NPM](https://www.npmjs.com/package/gridsome-plugin-monetization)*

<hr>

## What I built

A web monetization plugin for the [Gridsome](https://www.gridsome.org/) static site generator.

### Submission Category: 

**Foundational Technology**

Plugins and integrations initiate acceptance for new web technologies. This plugin helps developers using the Vue-based Gridsome static site generator to avoid interacting directly with the DOM and easily attach events, modify monetization tags, and get monetization state with just a few lines.

## Demo (CodeSandbox)

> Open the demo in a separate tab. [Monetization is disabled in `<iframe>` by default.](https://webmonetization.org/docs/api#iframes)

{% codesandbox gridsome-plugin-monetization-3nf3w %}

## Link to Code

{% github https://github.com/Sergix/gridsome-plugin-monetization %}

## How I built it 

Gridsome plugins are fairly simple to write. For client plugins (such as this), all you have to do is make a `gridsome.client.js`, and you export a function such as the following:

```javascript
export default function (Vue, options, context) {
  const $monetization = {}

  // server code
  // ...

  if (!process.isClient) return

  // client-only code
  // ...

  Vue.prototype.$monetization = $monetization
}
```

Then, you link your plugin to a Gridsome project via `npm link gridsome-plugin-monetization` for plugin development and testing.

I used the `context` to interact with Gridsome's build step when the `global` option in the plugin configuration is enabled.

I attempted to keep the code as composable and clean as possible, but when interacting with the DOM it can be a challenge. :laughing:

## Example/Usage

*[Full setup instructions and documentation are in the repository's README](https://github.com/Sergix/gridsome-plugin-monetization/blob/master/README.md).*

Install via `npm` or `yarn` —

```bash
yarn add gridsome-plugin-monetization # or npm install gridsome-plugin-monetization
```

Add the plugin to Gridsome, and set your `paymentPointer` —

```javascript
// gridsome.config.js

module.exports = {
  // ...
  plugins: [
    {
      use: "gridsome-plugin-monetization",
      options: {
        paymentPointer: "$wallet.example.com/alice",
        global: false, // enabled on every page (default: true)
      },
    },
  ],
}
```

Use in your components, pages, and layouts by accessing `Vue.prototype.$monetization` —

```javascript
// component.vue

export default {
  methods: {
    enableExtraContent() {
      // ...
    }
  },
  mounted() {
    this.$monetization.enable()
    this.$monetization.onStart(() => this.enableExtraContent)
  }
}
```

## Additional Resources/Info 

Due to the nature of server-side rendering and static sites, and the state of the monetization API (as well as Gridsome's plugin API), the plugin's methods are only accessible via the client and cannot be used in a component's `data`, `computed`, and `<template>`.

For now, the best way to use the API is to declare defaults within your component's `data` and add event hooks within your component's `mounted()` hook. This way, the DOM has time to load before attempting to access the monetization API.

## Thank you for reading! God bless!

<hr>

You can find me at [sergix.dev](https://www.sergix.dev/).
Reach out at [hello@sergix.dev](https://sergix.dev) for anything that's on your mind!