Skip to content

Astro

Send emails using Astro and the MailChannels Node.js SDK.

Prerequisites

1. Install

Add the mailchannels-sdk package dependency to your Astro project.

sh
npm i mailchannels-sdk
sh
yarn add mailchannels-sdk
sh
pnpm add mailchannels-sdk
sh
bun add mailchannels-sdk
sh
deno add npm:mailchannels-sdk

2. Install SSR adapter

Enable server-side rendering (SSR) in your Astro project by installing an SSR adapter.

3. Configure your API key

Add your MailChannels API key to your .env file.

.env
sh
MAILCHANNELS_API_KEY=your-api-key

4. Send email using HTML

Export the server Actions in src/actions/index.ts.

src/actions/index.ts
ts
import emailsSend from "./emails/send"

export const server = {
  emails: {
    send: emailsSend
  }
}

Define the send action in src/actions/emails/send.ts.

Use the html property to send an email with HTML content.

src/actions/emails/send.ts
ts
import { ActionError, defineAction } from 'astro:actions'
import { MailChannels } from 'mailchannels-sdk'

const mailchannels = new MailChannels(import.meta.env.MAILCHANNELS_API_KEY)

export default defineAction({
  accept: 'json',
  handler: async () => {
    const { data, error } = await mailchannels.emails.send({
      from: 'Name <from@example.com>',
      to: 'to@example.com',
      subject: 'Test email',
      html: '<p>Hello World</p>'
    })

    if (error) {
      throw new ActionError({
        code: 'INTERNAL_SERVER_ERROR',
        message: error.message
      })
    }

    return data
  }
})

5. Call the action

Call the send action from an Astro page. Use a native HTML form with Astro.getActionResult() for server-side handling, or intercept the form submission in a <script> tag for client-side updates without a page reload.

astro
---
---

<Layout>
  <h1>Send a predefined email</h1>

  <form id="send-form" class="form">
    <button type="submit" id="submit-btn">Send Email</button>
  </form>

  <pre id="result" hidden></pre>
</Layout>

<script>
import { actions } from 'astro:actions'

const form = document.getElementById('send-form') as HTMLFormElement
const submitBtn = document.getElementById('submit-btn') as HTMLButtonElement
const result = document.getElementById('result') as HTMLPreElement

form.addEventListener('submit', async (e) => {
  e.preventDefault()
  submitBtn.disabled = true
  submitBtn.textContent = 'Sending...'
  result.hidden = true
  result.textContent = ''

  const { data, error } = await actions.emails.send()

  submitBtn.disabled = false
  submitBtn.textContent = 'Send Email'
  result.hidden = false
  result.textContent = JSON.stringify(error || data, null, 2)
})
</script>
astro
---
import { actions } from 'astro:actions'

const result = Astro.getActionResult(actions.emails.send)
---

<form method='POST' action={actions.emails.send}>
  <button type='submit'>Send Email</button>
</form>

{result?.error && <p>Error: {result.error.message}</p>}
{result && !result.error && <p>Email sent successfully!</p>}

Examples

Released under the MIT License.