Motivation and expected behaviour
I want to create a simple CRUD App which does two things once the user enters an item to a to-do list:
- save it to a table in a database (Supabase).
- send the item to a specific email address (Mailgun).
The tech stack is Next, Supabase, Mailgun. The basic idea is to combine two already existing quick start examples, see details here.
No obvious problem with API_KEY and DOMAIN in the file
I place this file under the ./components
directory.
import FormData from "form-data"
import Mailgun from "mailgun.js"
const API_KEY = "secret"
const DOMAIN = "secret.mailgun.org"
export async function sendEmail(email: any) {
console.log(API_KEY)
console.log(DOMAIN)
const mailgun = new Mailgun(FormData)
const client = mailgun.client({ username: "api", key: API_KEY })
const messageData = {
from: ` Contact <contact@${DOMAIN}>`,
// to: specified email
subject: "new item!",
text: `Hello! Here is the new item${item}.
`,
}
try {
const emailRes = await client.messages.create(DOMAIN, messageData)
console.log(emailRes)
} catch (err: any) {
console.log("an error")
console.log(err)
}
}
I then import and call sendEmail()
in a fellow component, TodoList.tsx
.
This console logs a {status: 200} message, and moments later my specified email receives the email.
.env changes the behaviour
But when I use a .env and .env.local instead, i.e. change the API_KEY and DOMAIN to:
require("dotenv").config()
// I understand I should not use "NEXT_PUBLIC_", but just for illustration purpose.
const API_KEY = process.env.NEXT_PUBLIC_MAILGUN_API_KEY as string
const DOMAIN = process.env.NEXT_PUBLIC_MAILGUN_DOMAIN as string
Mailgun gives me a {status: 401} error (unauthorised), even though:
- my console still correctly logs out the api key and domain.
- Nothing else has changed.
Why? Why would using a .env file change the behaviour of Mailgun.js?
Debugging attempts
-
I have thought about whether client/server components may be causing the issue. But the issue persists whether I add ‘use client’ or ‘use server’ right after the
export async function sendEmail(email: any) {
line. -
I have considered getting mailgun.js to return a more meaningful error message, but am unsuccessful.