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.