Contacts
Get in touch

Add A Newsletter Subscription Form To Shopify Hydrogen Template

Create_a_Newsletter_That_Grows_Your_Business

In this tutorial, we’ll walk you through adding a newsletter subscription form to your Hydrogen template. Currently, Shopify does not offer a direct mutation or endpoint to add a newsletter user. Instead, we will create a new user with the acceptsMarketing: true value using the customerCreate mutation.

Step-by-Step Guide to Implement the Newsletter Subscription Form for Shopify

Step 1: Create the Subscription Form

First, you need to create a form in your template to collect email addresses from users. Then, use the fetch function to send the email address to your server. On the server side, you’ll have an endpoint to create a new user with acceptsMarketing: true value.

Step 2: Code Explanation

We will create the newsletter subscription form in our component using the following hooks:

  • useFetcher to send the email address to our server.
  • useParams to get the locale of the page.
  • useState to manage the email address, loading state, and server response.

When a user enters their email and clicks the subscribe button, the email address is sent to the server. If the email address is already in use, an error message is returned and displayed to the user. If the email address is not in use, a new user is created with acceptsMarketing: true.

Newsletter Subscription Component

import {useState,useEffect} from 'react';
import {useFetcher,useParams} from '@remix-run/react';

export default function NewsletterSubscription() {
    let [subscriptionEmail, setSubscriptionEmail] = useState('');
    let [subscriptionLoading, setSubscriptionLoading] = useState(false);
    let [subscriptionResponse, setSubscriptionResponse] = useState(null);
    const fetcher = useFetcher();
    const params = useParams();
    let newsletterSubscriptionHandlerM = (e) => {
        e.preventDefault();

        const handleAction = '/api/newsletter_subscribe';
        const localizedAction = params.locale
            ? `/${params.locale}${handleAction}`
            : handleAction;

        setSubscriptionLoading(true);
        fetcher.submit(
            {email: subscriptionEmail},
            {method:'POST', action: localizedAction},
        );
        return false;
    };
    useEffect(()=>{
        let message = fetcher.data?.customerCreate?.customerUserErrors[0]?.message;
        if(message){
            setSubscriptionLoading(false);
            setSubscriptionResponse(message);
        }
    },[fetcher]);

  return (
    <div className="container">
      <div className="subscribe-news-letter">
        <p>
          <strong>Subscribe newsletter</strong>
        </p>
        {subscriptionLoading && <p>Loading...</p>}
        {subscriptionResponse && <p>{subscriptionResponse}</p>}
        {subscriptionLoading == false && (
          <form onSubmit={newsletterSubscriptionHandlerM}>
            <input
              autoComplete="off"
              type="email"
              placeholder="Email address"
              value={subscriptionEmail}
              onChange={(e) => setSubscriptionEmail(e.target.value)}
            />
            <input type="submit" value="Subscribe" />
          </form>
        )}
      </div>
    </div>
  );
}

Server Endpoint Implementation

Place the following code in app/routes/($locale)/api/newsletter_subscribe.js:

import {json} from '@shopify/remix-oxygen';
export async function action({request, context,params}){
    let email = await getEmail(request)
    let result = await newsletterSubscriptionHandler(context,email);

    return json(result);
}

async function getEmail(request){
    let body;
  try {
    body = await request.formData();
    return body.get('email');
  } catch (error) {
  }
}
function generateRandomPassword(length){
    let result = '';
    let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let charactersLength = characters.length;
    for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
}

async function newsletterSubscriptionHandler(context, emailAddress){
        let mutation = context.storefront.mutate(`
mutation customerCreate($input: CustomerCreateInput!,
    $language: LanguageCode
)
@inContext(language: $language){
  customerCreate(input: $input) {
    customer {
      email
      acceptsMarketing
    }
    customerUserErrors {
      field
      message
      code
    }
  }
}
    `,{
        variables: {
            language: context.storefront.i18n.language,
            input: {
                email: emailAddress,
                password: generateRandomPassword(10),
                acceptsMarketing: true
            }
        }
    });
    return mutation;
    }

By following these steps, you can successfully integrate a newsletter subscription form into your Hydrogen template. This approach ensures that new users are created with the acceptsMarketing: true value, allowing you to grow your newsletter audience effectively.

Leave a Comment

Your email address will not be published. Required fields are marked *