Adding Mailchimp to Next.js

27th August 2019

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:

Creating an embed form

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!

Using the form

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.