Sending Emails with Nuxt.js the Easy Way
Tags: nuxt, vue, javascript, node
Published: 2021-03-05 01:18:24

When I started to work with Nuxt.js, I frequently had the problem that I wanted so send emails via a contact form. While there are third party services to do that, I thought: Why not use the existing server infrastructure that comes with Nuxt.js?

That is why I wrote [nuxt-mail](https://github.com/dword-design/nuxt-mail), a Nuxt.js module that adds a `/mail/send` route to the server and injects a `$mail` variable that wraps the API call.

## Usage

You start by installing the module and [@nuxtjs/axios](https://github.com/axios/axios) via `npm install nuxt-mail @nuxtjs/axios` or `yarn add nuxt-mail @nuxtjs/axios`.

`@nuxtjs/axios` is important here because it allows the module to do the REST call.

Then you add `@nuxtjs/axios` and `nuxt-mail` to your `nuxt.config.js` file. We have to pass the SMPT settings that should internally be used by `nodemailer`. We also configure the recipients here for security reasons. This way, a client cannot send emails to arbitrary recipients from your SMTP server. You can actually preconfigure the messages here in case you always want to give them the same title, from address or something.

```js
export default {
  modules: [
    '@nuxtjs/axios',
    ['nuxt-mail', {
      message: {
        to: 'me@gmail.com',
      },
      smtp: {
        host: 'smtp.mailtrap.io',
        port: 2525,
        auth: {
          user: 'username',
          pass: 'password'
        },
      },
    }],
  ],
}
```
Note that you probably should pass the credentials or the whole config via environment variables (e.g. via [dotenv](https://github.com/motdotla/dotenv)). Also note that you cannot use this module for static sites (via `nuxt generate`), because the server middleware does not exist.

And there we go! Now we can implement ourselves a contact form page and send emails:

```html
<template>
  <form>
    <label for="email">Your email address:</label>
    <input id="email" type="email" v-model="email" />
    <label for="message">Message:</label>
    <textarea id="message" v-model="message" />
    <button type="submit" @click.prevent="send">
      Send email
    </button>
  </form>
</template>
```

In the `<script>` section we basically call `this.$mail.send()`:

```js
<script>
export default {
  data: () => ({
    email: '',
    message: '',
  }),
  methods: {
    send() {
      this.$mail.send({
        from: this.email,
        subject: 'Contact form message',
        text: this.message,
      })
    }
  }
}
</script>
```

When you hit the `Send` button now, you should receive an email into your inbox!

## Multiple message configs

It is also possible to provide multiple message configurations by changing the `message` config into an array.

```js
export default {
  modules: [
    '@nuxtjs/axios',
    ['nuxt-mail', {
      message: [
        { name: 'contact', to: 'contact@foo.de' },
        { name: 'support', to: 'support@foo.de' },
      ],
      ...
    }],
  ],
}
```

Then you can reference the config like this:

```js
this.$axios.$post('/mail/send', {
  config: 'support',
  from: 'John Doe',
  subject: 'Incredible',
  text: 'This is an incredible test message',
})
```

Or via index (in which case you do not need the `name` property):

```js
this.$axios.$post('/mail/send', {
  config: 1, // resolves to 'support'
  from: 'John Doe',
  subject: 'Incredible',
  text: 'This is an incredible test message',
})
```

That's basically it, I hope that this is of use for some of you.

## Conclusion

You can use the module to easily setup email sending capabilities. If you plan to build a bigger SaaS that sends a lot of emails, an async solution that does the sending via a cronjob or via server-side hooks is probably a better idea. But for a first-off solution, it should work fine.

***

Let me know what you think about the module and if there are any open questions. Also, since this is my first post, let me know what you think about the post in general.

You can find the module [here](https://github.com/dword-design/nuxt-mail).

**If you like what I'm doing, follow me on [Twitter](https://twitter.com/seblandwehr) or check out my [website](https://sebastianlandwehr.com). Also consider donating at [Buy Me a Coffee](https://www.buymeacoffee.com/dword), [PayPal](https://www.paypal.com/paypalme/SebastianLandwehr) or [Patreon](https://www.patreon.com/dworddesign). Thank you so much! ❤️**