Newsletter API
The newsletter endpoint handles email subscription requests.
Endpoint
Section titled “Endpoint”POST /api/newsletterRequest
Section titled “Request”Content-Type
Section titled “Content-Type”multipart/form-data (FormData)
Fields
Section titled “Fields”| Field | Type | Required |
|---|---|---|
email | string | Yes |
Example Request
Section titled “Example Request”const response = await fetch('/api/newsletter', { method: 'POST', body: new FormData(form),});
const result = await response.json();Response
Section titled “Response”Success (200)
Section titled “Success (200)”{ "success": true}Validation Error (400)
Section titled “Validation Error (400)”{ "success": false, "error": "Please enter a valid email address"}Implementation
Section titled “Implementation”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 } );};Integration Examples
Section titled “Integration Examples”Mailchimp
Section titled “Mailchimp”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'); }}ConvertKit
Section titled “ConvertKit”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'); }}Resend
Section titled “Resend”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, });}Client-Side Handling
Section titled “Client-Side Handling”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'; }});