Skip to content

Newsletter API

The newsletter endpoint handles email subscription requests.

POST /api/newsletter

multipart/form-data (FormData)

FieldTypeRequired
emailstringYes
const response = await fetch('/api/newsletter', {
method: 'POST',
body: new FormData(form),
});
const result = await response.json();
{
"success": true
}
{
"success": false,
"error": "Please enter a valid email address"
}

The endpoint is defined in src/pages/api/newsletter.ts:

import type { APIRoute } from 'astro';
import { z } from 'zod';
const emailSchema = z.string().email();
export const POST: APIRoute = async ({ request }) => {
const formData = await request.formData();
const email = formData.get('email');
const result = emailSchema.safeParse(email);
if (!result.success) {
return new Response(
JSON.stringify({
success: false,
error: 'Please enter a valid email address',
}),
{ status: 400 }
);
}
// Add to newsletter service
await addSubscriber(result.data);
return new Response(
JSON.stringify({ success: true }),
{ status: 200 }
);
};
async function addSubscriber(email: string) {
const response = await fetch(
`https://${DC}.api.mailchimp.com/3.0/lists/${LIST_ID}/members`,
{
method: 'POST',
headers: {
Authorization: `apikey ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
email_address: email,
status: 'subscribed',
}),
}
);
if (!response.ok) {
throw new Error('Failed to subscribe');
}
}
async function addSubscriber(email: string) {
const response = await fetch(
`https://api.convertkit.com/v3/forms/${FORM_ID}/subscribe`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
api_key: API_KEY,
email,
}),
}
);
if (!response.ok) {
throw new Error('Failed to subscribe');
}
}
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
async function addSubscriber(email: string) {
await resend.contacts.create({
email,
audienceId: AUDIENCE_ID,
});
}
form.addEventListener('submit', async (e) => {
e.preventDefault();
const button = form.querySelector('button');
button.disabled = true;
button.textContent = 'Subscribing...';
try {
const response = await fetch('/api/newsletter', {
method: 'POST',
body: new FormData(form),
});
const result = await response.json();
if (result.success) {
form.innerHTML = '<p>Thanks for subscribing!</p>';
} else {
showError(result.error);
}
} catch (error) {
showError('Something went wrong. Please try again.');
} finally {
button.disabled = false;
button.textContent = 'Subscribe';
}
});