Create NuxtJS component for Newsletter subscription with Wordpress.
Tags: nuxt, vue, wordpress, rest
Published: 2020-07-28 09:45:40

---
title: Create NuxtJS component for Newsletter subscription with Wordpress.
published: true
description: This tutorial gonna guide you to create a component for NuxtJS and deal with WP REST API for newsletter subscription.
tags: nuxt,vueJS,wordpress,REST
---

I was wondering if it's possible to create a component for NuxtJS that allows subscribing to the costumers' newsletter
A component like this one:
![Amazing newsletter](https://dev-to-uploads.s3.amazonaws.com/i/y2ifmmp7h29g6h3q8tzu.png)

So I started to surf the internet and surprisely I found a [great WP plugin](https://www.thenewsletterplugin.com) which can deal with REST API.

## Requirements
1. [Create an account.](https://www.thenewsletterplugin.com/account)
2. [Getting Started by installing base plugin.](https://www.thenewsletterplugin.com/documentation/developers/dev-newsletter-api/)
3. Paste your *GLOBAL LICENSE CODE* on your Wordpress » Newsletter » Settings » License Key field.
4. By default the 2^ step is not enough if you want to add subscribers via REST API. So you have also to install the free Newsletter API addon (find it on Newsletter addons panel in your blog or get it on your account page - 1^ step).
This last step is going to add an *"API"* item under *Newsletter* inside WP sidebar.

Now we're ready to create our component.
I'm gonna assume that you already have a project with NuxtJS installed.

## Let's code

Template:
```HTML
<div>
  <h3 class="has-text-centered">Subscribe to our newsletter</h3>
  <div class="control has-icons-left has-icons-right has-text-centered">
    <VZSpinnerPlaceholders
      class="justify-center"
      v-if="isLoading"
      :contrast="true" />
    <div v-else class="input-container is-relative">
      <input
        v-model.trim="email"
        class="input is-large"
        type="email"
        placeholder="Email">
      <span class="add pointer" @click="addSubscription" v-if="isValidEmail"></span>

      <div v-if="result.show" class="result">
        <p> {{ result.message }} </p>
      </div>
    </div>
  </div>
</div>
```
`<VZSpinnerPlaceholders />` it's just a simple component that I created to show a funny spinner.
Since I'm using [Bulma's module with NuxtJS](https://www.npmjs.com/package/@nuxtjs/bulma) you can see the component's output [here (Loading)](https://bulma.io/documentation/elements/button/#states).

Logic:
```javascript
import newsletterManager from "@/mixins/newsletterManager";
...
mixins: [newsletterManager],
data: () => ({
  email: null,
  isLoading: false,
  result: { show: false, message: null }
}),
computed: {
  isValidEmail() {
    const rule = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
    return Boolean(this.email && rule.test(this.email))
  },
  payload() {
    return {
      email: this.email,
      name: 'Client from nuxt',
      gender:'--'
    }
  }
},
methods: {
  async addSubscription() {
    if(!this.isValidEmail) return

    this.isLoading = true
    const subscriptionResponse = await this.MX_NL_addSubscriber(this.payload)
    this.responseHandler(subscriptionResponse)
  },
  responseHandler({ response, isAxiosError }) {
    const isString = s => (typeof s === 'string' || s instanceof String)
    let message

    if(isAxiosError) {
      const text = isString(response.data) ? response.data : response.data.message
      message = `${ text } ❌`
    } else {
      message = 'Subscription completed! ✅'
    }

    this.isLoading = false
    this.result = { show: true, message }
    this.email = null // Flush email
  }
}
...
```

As you can see, I like using [mixins](https://vuejs.org/v2/guide/mixins.html) to separate the logic like making the POST to add a subscriber.
This is where `MX_NL_addSubscriber` comes in:
```javascript
// mixins/newsletterManager.js
import ENVs from "@/constants/environments";

export default {
  methods: {
    async MX_NL_addSubscriber(payload) {
      try {
        const response = await this.$axios.$post(
          `${ ENVs.getDomainPath() }/wp-json/newsletter/v1/subscribe`,
          payload
        )

        return response
      } catch(error) { // Let's handle it.
        return error
      }
    }
  }
}

```
I'm not using any secret key for the API since the documentation is quite clear:
> Subscribe
When called as REST API it can be invoked without the secret key: in this case more strict contraints are applied to the parameters (like for subscriptions coming from a public subscription form).

So, as you can see in the documentation, it's just a simple CURL:
```bash
$ curl -X POST -H "Content-Type: application/json" http://<your-site>/wp-json/newsletter/v1/subscribe
-d '{"email":"test@example.com", "name":"My name", "gender":"f"}'
```
So `this.payload` is just an object with those keys.

## Result
{% vimeo 442173302 %}
And this is my wordpress-back office side:
![Wp back-office](https://dev-to-uploads.s3.amazonaws.com/i/ogh6hhkskwwdr5r7lrp9.png)

## Credits
Once again thank you guys ♥️
{% twitter 1050813729951092739 %}