Newsletter with Mailchimp and NextJS

Back to Blogs
Newsletter with Mailchimp and NextJS

Today we will learn how to gather emails from a form in NextJS and save them in Mailchimp.

First we will need to have a Mailchimp account. If you don’t have an account go Mailchimp Sign Up page and register for free.

Then sign in and go to Audience > Signup forms. Then choose Embedded forms on the right. Then click on the button Generate Embed Code and find this code:

<form action="https://yourname.us20.list-manage.com/subscribe/post?u=7ac9bf22e7a6f47&amp;id=98f33953"

Then add Env variable in next.js application .env file for Mailchimp URL and paste the URL taken from form action above.

NEXT_PUBLIC_MAILCHIMP_URL=https://yourname.us20.list-manage.com/subscribe/post?u=7ac9bf22e7a6f47&amp;id=98f33953

Then install the React Mailchimp subscribe package

npm i react-mailchimp-subscribe html-entities

Create a React Component in NextJS called NewsletterForm
Notice we have added NewsletterForm component which we will add shortly.

import React, { Component } from 'react';
import MailchimpSubscribe from 'react-mailchimp-subscribe';
import NewsletterForm from './NewsletterForm';

const Newsletter = () => {
    const MAILCHIMP_URL = process.env.NEXT_PUBLIC_MAILCHIMP_URL;
        return (
            <MailchimpSubscribe
            url={ MAILCHIMP_URL }
            render={ ( props ) => {
              const { subscribe, status, message } = props || {};
              return (
                <NewsletterForm
                  status={ status }
                  message={ message }
                  onValidated={ formData => subscribe( formData ) }
                />
              );
            } }
          />
        );
    
}

export default Newsletter;

Create another component called NewsletterForm

import { useState } from "react";
import { decode } from "html-entities";

const NewsletterForm = ({ status, message, onValidated }) => {
  const [error, setError] = useState(null);
  const [email, setEmail] = useState(null);

  const handleFormSubmit = () => {
    setError(null);
    if (!email) {
      setError("Please enter a valid email address");
      return null;
    }
    const isFormValidated = onValidated({ EMAIL: email });
    return email && email.indexOf("@") > -1 && isFormValidated;
  };

  const handleInputKeyEvent = (event) => {
    setError(null);
    if (event.keyCode === 13) {
      event.preventDefault();
      handleFormSubmit();
    }
  };

  const getMessage = (message) => {
    if (!message) {
      return null;
    }
    const result = message?.split("-") ?? null;
    if ("0" !== result?.[0]?.trim()) {
      return decode(message);
    }
    const formattedMessage = result?.[1]?.trim() ?? null;
    return formattedMessage ? decode(formattedMessage) : null;
  };

  return (
    <>
      <section className="newsletter-area">
        <div className="container">
          <div className="newsletter-inner-area">
            <div className="newsletter-content">
              <span className="sub-title">Get Started Instantly!</span>
              <h2>Get only the new updates</h2>

              <div className="newsletter-form">
                <input
                  onChange={(event) => setEmail(event?.target?.value ?? "")}
                  onKeyUp={(event) => handleInputKeyEvent(event)}
                  type="email"
                  className="form-control"
                  placeholder="Enter your email"
                  name="email"
                  required
                />
                <button type="submit" onClick={handleFormSubmit}>
                  Subscribe!
                </button>
              </div>
              <div className="newsletter-form-info">
                {status === "sending" && <div>Sending...</div>}
                {status === "error" || error ? (
                  <div
                    className="newsletter-form-error"
                    dangerouslySetInnerHTML={{
                      __html: error || getMessage(message),
                    }}
                  />
                ) : null}
                {status === "success" && status !== "error" && !error && (
                  <div dangerouslySetInnerHTML={{ __html: decode(message) }} />
                )}
              </div>
            </div>
          </div>
        </div>
      </section>
    </>
  );
};
export default NewsletterForm;

Now you can try it.

  • Category:
  • JavaScript