I made a form that sends the input data to the Mailchimp audience list with their API. The issue I'm having is that my form takes two inputs, a user's firstname, and email, and upon submission of the form only the email input gets sent to Mailchimp and saved twice under email_address and firstName fields in their audience list thing. I want the email to go to the email field and the name to the firstName field. I can't see why this doesn't work per Mailchimp docs the firstName is to be prompted by a merge_fields object. However, their docs have 0 examples.
I made this subscribeUser file to handle the API request:
import fetch from "isomorphic-unfetch";
export default async (req, res) => {
const { firstName, email } = req.body;
console.log({ firstName });
console.log({ email });
if (!firstName && !email) {
return res.status(400).json({ error: "Email and name is required" });
}
try {
const AUDIENCE_ID = process.env.MAILCHIMP_AUDIENCE_ID;
const API_KEY = process.env.MAILCHIMP_API_KEY;
const DATACENTER = process.env.MAILCHIMP_API_SERVER;
const data = {
email_address: email,
merge_fields: {
FNAME: firstName,
},
status: "subscribed",
};
const response = await fetch(
`https://${DATACENTER}.api.mailchimp.com/3.0/lists/${AUDIENCE_ID}/members`,
{
body: JSON.stringify(data),
headers: {
Authorization: `apikey ${API_KEY}`,
"Content-Type": "application/json",
},
method: "POST",
}
);
if (response.status >= 400) {
return res.status(400).json({
error: `There was an error subscribing to the newsletter.
Please try again later.`,
});
}
return res.status(201).json({ error: "" });
} catch (error) {
return res.status(500).json({ error: error.message || error.toString() });
}
};
I made this Subscribe form to handle the input data:
import { motion } from "framer-motion";
import { useMemo, useRef } from "react";
import getScrollAnimation from "../utils/getScrollAnimation";
import ScrollAnimationWrapper from "./Layouts/ScrollAnimationWrapper";
const Subscribe = () => {
// scroll animation
const scrollAnimation = useMemo(() => getScrollAnimation(), []);
const inputRef = useRef(null);
const subscribeUser = async (e) => {
e.preventDefault();
// this is where the mailchimp request is made
const res = await fetch("/api/subscribeUser", {
body: JSON.stringify({
firstName: inputRef.current.value,
email: inputRef.current.value,
}),
headers: {
"Content-Type": "application/json",
},
method: "POST",
});
};
return (
<div>
<ScrollAnimationWrapper className="relative w-full mt-16">
<motion.div variants={scrollAnimation} custom={{ duration: 3 }}>
<div className="absolute rounded-xl py-8 sm:py-14 px-6 sm:px-12 lg:px-16 w-full flex flex-col sm:flex-row justify-between items-center z-10 bg-white-500">
<div className="flex flex-col text-left w-10/12 sm:w-7/12 lg:w-5/12 mb-6 sm:mb-0">
<h5 className="text-black-600 text-xl sm:text-2xl lg:text-3xl leading-relaxed font-medium">
Subscribe to my newsletter
<br />{" "}
</h5>
<p>I look foward to ocnnecting with you soon</p>
</div>
<div className="flex flex-col w-10/12 sm:w-5/12 lg:w-7/12">
<form onSubmit={subscribeUser}>
<div className="flex flex-row">
<label
htmlFor="name-input"
className="mb-3 text-sm leading-none text-gray-800"
>
First name
</label>
<input
type="name"
id="name"
name="name"
tabIndex={0}
ref={inputRef}
required
aria-label="Enter first name"
className="w-54 bg-gray-100 text-sm font-medium leading-none text-gray-800 p-3 border rounded border-gray-200"
defaultValue="name"
/>
</div>
<div className="flex flex-row">
<label
htmlFor="email-input"
className="mb-3 text-sm leading-none text-gray-800"
>
Email Address
</label>
<input
type="email"
id="email"
name="email"
ref={inputRef}
required
tabIndex={0}
aria-label="Enter email Address"
className="w-54 bg-gray-100 text-sm font-medium leading-none text-gray-800 p-3 border rounded border-gray-200"
defaultValue="email@gmail.com"
/>
</div>
<button type="submit" value="" name="subscribe">
Send
</button>
</form>
</div>
</div>
</motion.div>
</ScrollAnimationWrapper>
</div>
);
};
export default Subscribe;