Custom Shopify Contact Form Not Sending Emails? Here’s How to Debug It Like a Pro
Ever built a custom contact form on your Shopify store, hit submit, saw that glorious "success" message, and then… crickets? No email in your inbox. It’s a frustrating mystery, especially when your store’s default contact form works perfectly fine. We recently saw a fantastic discussion in the Shopify community about this exact issue, and the insights shared are pure gold for any store owner or developer.
Our community member, wearboco, kicked off the thread with a classic scenario: a custom, multi-step contact form on a modified Dawn theme, using Shopify’s native {% form 'contact' %} tag. The form seemed to work flawlessly – redirecting, displaying success, and form.posted_successfully? returning true. Yet, no notification email. They'd already checked all the usual suspects: sender emails, spam folders, and confirmed the default form worked. What gives?
The Critical First Check: Where is Your Form Actually Sending Data?
Before diving deep into code, ThemeMend, a keen-eyed community member, spotted a crucial detail that often trips people up. wearboco had linked to their live form, and upon inspection, it turned out the form was actually posting to Formspree (https://formspree.io/f/maeybedp) with fields like email, name, message – not Shopify's expected contact[email] and contact[body]. If your form is pointing to an external service like Formspree, Shopify never even sees the submission!
How to Check Your Form's Action
This is super easy to confirm:
- Open your page with the custom form in your browser.
- Right-click on the form and select "Inspect" (or "Inspect Element").
- Look for the
tag and specifically itsaction="..."attribute.
If it says formspree.io (or any other external service), your email problem is entirely with that service, not Shopify. For Formspree, the usual culprits are:
- Unconfirmed Form: New forms on Formspree's free plan require you to click a confirmation link sent to your email after the very first submission. Until then, submissions are accepted, but no emails go out. This is a #1 cause!
- Unverified Destination Email: Make sure the email address Formspree is sending to is verified.
- Free Plan Limits: You might have hit the 50 emails/month limit.
- Check Formspree Dashboard: Log in and check the "Submissions" log. Entries are stored there even if emails didn't send.
If you discover you are using an external service but want Shopify to handle it natively, ThemeMend pointed out that it's a clean swap. You'd just need to ensure your form markup uses Shopify's {% form 'contact' %} and the correct contact[...] field names.
When It's Definitely Shopify: Debugging the Native Form
Okay, so you've confirmed your form's action points to Shopify (e.g., /contact#ContactForm). Great! Now we can dig into why Shopify isn't sending that notification.
"Success" Doesn't Always Mean Email Delivery
One of wearboco's key questions was: "Can Shopify return form.posted_successfully? = true without creating or sending the notification email?" The answer, according to Ecom_swift_LLC, is a resounding yes. Shopify runs every /contact submission through its own spam filter *after* the redirect. So, your form can show a success state, but the notification email might be silently dropped. There's also no log of contact-form submissions in the Shopify Admin, which makes debugging tougher (another one of wearboco's questions answered).
The Hidden Field Honeypot Dilemma
wearboco's custom form used a for contact[body] with a native HTML hidden attribute, which JavaScript then filled before submission. This was flagged as a major suspect by M.Rahman and Ecom_swift_LLC. While cuongnm_trooix correctly noted that a hidden attribute shouldn't stop a field from being submitted (unlike disabled), Ecom_swift_LLC suggested that a field that's empty until JS fills it, especially if it's hidden, looks a lot like an "inverted honeypot" – a common pattern anti-spam filters watch for.
The Fix: Use CSS for Hiding
Instead of the native HTML hidden attribute, it's safer to hide fields using CSS. M.Rahman provided a clear example:
Actionable Step: Change your hidden attribute to style="display: none;" on any fields that are visually hidden but dynamically populated.
Spam Filters & Payload Nuances
Beyond the hidden field, other aspects of your custom form's payload can trigger spam filters. Ecom_swift_LLC mentioned that stripping the form down to just contact[email] and contact[body] is unusual enough to push borderline submissions into the spam bucket. Adding back contact[name] (even if visually hidden via CSS) can help.
While Shopify's documentation (as pointed out by cuongnm_trooix) states that spam submissions are typically emailed with [SPAM] in the subject, there can still be situations where messages are silently dropped due to backend processing or unusual payload patterns. wearboco asked about maximum body length or undocumented limitations; cuongnm_trooix couldn't find any documented limits, suggesting this isn't a common issue.
Don't Forget the Notification Template!
Ecom_swift_LLC also reminded us that Shopify shows a success page even if the notification template itself fails to render. A broken or edited Liquid snippet under Settings > Notifications > “Contact form” can silently swallow the email. It's always worth opening that template and ensuring it saves without an error.
When All Else Fails: Controlled Testing & Shopify Support
If you've tried all the above and your custom form still isn't sending emails, cuongnm_trooix laid out a methodical comparison strategy:
- Controlled Comparison: Submit the same email address and a short, plain-text body through both your working default form and your custom form.
- Compare POST Bodies: Use your browser's developer tools (Network tab) to compare the actual POST payloads, including
form_type,contact[email], andcontact[body]. Are they identical? - Static Text Test: Temporarily test your custom form with a standard, visible
containing static text, instead of constructing the body with JavaScript. If this works, add your assembled content back in small pieces to identify the culprit. - Contact Shopify Support: If the requests are effectively identical but delivery still differs, provide Shopify Support with the exact UTC timestamps of your test submissions. They might be able to trace what happened on their end.
Debugging custom forms can feel like chasing ghosts, but as this community discussion shows, a systematic approach, starting with the most basic checks (like verifying your form's action!), can save you a ton of headache. Pay close attention to how your fields are hidden and populated, and remember that Shopify's spam filters are always on the lookout for anything that looks a little out of the ordinary. Keep testing, keep comparing, and you'll get those contact form emails flowing!