Christopher Pitt

Adding Mailchimp to Next.js

I was chatting to my friend about putting a newsletter sign-up form on the blog he's busy making. Then it occurred to me that I didn't have one on my blog, and that I didn't even know how I was going to embed a Mailchimp sign-up form in a Next.js site.

Creating the embed form

The first step is creating a new subscriber list and embeddable sign-up form, through Mailchimp. Forgive me if you're coming back to this, months later, and their UI has changed somewhat. This is what it looked like, for me:

After creating the list, the "Create" button should give you the option of creating a new "Sign-up form". You can select your audience from that list of subscriber lists.

I disabled all by the single required "email" field. I am unaware of what GDPR things I need, at this stage, so I will be doing some research as to what's required. The beauty of the approach I'm showing you is that you can customise these forms after creating them; so you can always add or subtract from the displayed and required fields.

Keep that tab open a while. We'll need a URL from it before too long...

Embedding in Next.js

As I assumed there would be, I was able to find a React.js library for subscribing to Mailchimp lists. I installed it with:

npm i react-mailchimp-subscribe

You can use the built-in subscription form, if you'd like an easy setup:

import MailchimpSubscribe from "react-mailchimp-subscribe"

// you can get this url from the embed code form action
const url = "https://assertchris.us12.list-manage.com/subscribe/post?..."

const Newsletter = () => <MailchimpSubscribe url={url} />

export { Newsletter }

Of course, you probably want a bit more control over how the form is displayed and indicates various states. I went with a more advanced setup, using a reader prop:

import React, { createRef } from "react"
import MailchimpSubscribe from "react-mailchimp-subscribe"

const url = "https://assertchris.us12.list-manage.com/subscribe/post?..."

const Newsletter = () => {
    const emailRef = createRef(undefined)

    return (
        <div>
            <h2>Would you like me to keep you in the loop?</h2>
            <p>...</p>
            <MailchimpSubscribe
                url={url}
                render={({ subscribe, status, message }) => {
                    switch (status) {
                        case "sending":
                            return <div>Sending...</div>
                        case "success":
                            return <div>Subscribed.</div>
                        case "error":
                            return <div dangerouslySetInnerHTML={{ __html: message }} />
                        default:
                            return (
                                <form
                                    onSubmit={() => {
                                        event.preventDefault()

                                        subscribe({
                                            EMAIL: emailRef.current.value,
                                        })
                                    }}
                                >
                                    <input type="email" ref={emailRef} />
                                    <input type="submit" value="subscribe" />
                                </form>
                            )
                    }
                }}
            />
        </div>
    )
}

export { Newsletter }

I've removed all styling, but the rest of the markup is pretty descriptive. I like this use of switch, because so much of what's displayed hinges on that single status variable. At this point, you could use a utility framework, or Styled Components (though you'd have to set that up to work with Next.js).

This works wonderfully!

Would you like me to keep you in the loop?

I write about all sorts of interesting code things, and I'd love to share them with you. I will only send you updates from the blog, and will not share your email address with anyone.