How to Add a Custom Contact Form to Shopify Without an App
Add a custom contact or quote form to a Shopify store with the Custom Liquid section and a form backend: your own fields, spam filtering, email and Slack notifications, no app.
The ShipMyForm team
· 4 min read
You can put a custom form on any Shopify page without an app. Every Online
Store 2.0 theme ships a Custom Liquid section; paste a plain HTML form into it
whose action points at a form endpoint, and submissions are stored,
spam-filtered and routed to your email, Slack or a spreadsheet. Ten minutes,
no theme code edits, and it survives theme updates.
Full disclosure: ShipMyForm is our product and is the endpoint in the example. The Shopify side of this works with any endpoint that accepts a form POST.
When Shopify's own contact form is enough, and when it is not
Shopify's built-in contact form, the {% form 'contact' %} block most themes
render on the Contact page, sends a message to your store's customer email.
For a simple "get in touch" it is fine and you should use it.
It stops being enough when you want any of these:
- Your own fields. Order number, product, budget, preferred date, a dropdown of services. The built-in form has a fixed set.
- Attachments. A photo of the damaged item, a logo for a custom order.
- Routing. The enquiry in Slack for the team, or in a Google Sheet for the person who quotes, not only in one inbox.
- A stored inbox you can search, export, and mark as spam or not.
- Spam control that does not depend on Shopify's storefront reCAPTCHA setting, which is all-or-nothing across every storefront form.
The usual answer is a form app from the Shopify App Store, and there are good ones. The route below gets you the same result with nothing installed, which matters if you are watching app count, monthly fees, or theme performance.
Step 1: create a form endpoint
Sign up for a form backend and create a form. You get an endpoint URL like
https://shipmyform.com/f/YOUR_FORM_ID. Two settings to change straight away:
- Allowed domains: add your store domain, for example
yourstore.com, and the.myshopify.comdomain if you preview there. The endpoint then refuses posts from anywhere else. - Redirect URL: a page on your store, for example
https://yourstore.com/pages/thank-you. Create that page in Shopify under Online Store, Pages, if it does not exist. Visitors return to your store after submitting.
Set the notification email, and connect Slack or Google Sheets if you want the enquiry to land there too.
Step 2: add a Custom Liquid section to the page
In Shopify admin: Online Store, Themes, Customize. Use the page picker at the top to open the page you want the form on, a Contact page or a new "Request a quote" page. Click Add section, search for Custom Liquid, and add it. Themes that lack it in that position usually offer it as a block inside an existing section instead; either works.
Paste this into the Liquid box:
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST" class="smf-form">
<input type="hidden" name="_subject" value="New enquiry from {{ shop.name }}" />
<input type="hidden" name="page" value="{{ page.title | default: request.path }}" />
<label>
Name
<input type="text" name="name" autocomplete="name" required />
</label>
<label>
Email
<input type="email" name="email" autocomplete="email" required />
</label>
<label>
Order number <span class="smf-optional">(optional)</span>
<input type="text" name="order_number" inputmode="numeric" />
</label>
<label>
How can we help?
<textarea name="message" rows="5" required></textarea>
</label>
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
aria-hidden="true" style="position:absolute;left:-9999px" />
<button type="submit" class="button">Send</button>
</form>
<style>
.smf-form { display: grid; gap: 14px; max-width: 520px; }
.smf-form label { display: grid; gap: 6px; font-weight: 500; }
.smf-form input, .smf-form textarea {
font: inherit; padding: 10px 12px; border: 1px solid #d4d4d4; border-radius: 6px;
}
.smf-optional { font-weight: 400; opacity: .7; }
</style>Save. The form is live on that page.
Two lines deserve a look. {{ shop.name }} and {{ page.title }} are
Liquid, and Custom Liquid renders them, so the email subject carries your
store name and each submission records which page it came from. The button
class is the one most Shopify themes use for their primary button, so the
submit button matches your store without extra CSS.
Step 3: submit once, then check three places
Send a test from the live page. You should see the submission in your form's
inbox, receive the notification email with the visitor's address as
Reply-To, and land on your thank-you page. If Slack or a sheet is
connected, it appears there within seconds.
If the endpoint responds with an origin error, the store domain is not in allowed domains yet. If you land on the hosted thank-you page instead of your own, the redirect URL is missing or not on an allowed domain.
Putting the form on a product page
A request-a-quote or "ask about this product" form belongs under the product. Open a product template in the theme editor, add Custom Liquid as a block in the product information section, and paste the same form with one extra hidden field:
<input type="hidden" name="product" value="{{ product.title }} ({{ product.handle }})" />Every enquiry then says which product it is about, and the Slack message or sheet row is useful without a follow-up question.
Spam
Shopify's storefront reCAPTCHA covers Shopify's own forms, not this one. The custom form relies on three things instead: the honeypot field in the markup, which bots fill and people never see; rate limiting by IP at the endpoint; and server-side classification of the content. Together they stop most spam with no CAPTCHA in the visitor's way. If a particular store attracts a lot of it, add Cloudflare Turnstile to the form; it stays invisible for almost everyone. The full picture is its own guide.
What this cannot do
- Customer accounts. The form does not know who is logged in. If you want
the customer's email pre-filled, Liquid can do it: set the email input's
valueto{{ customer.email }}, which renders empty for guests. - Shopify Flow triggers. Submissions live in the form backend, not in Shopify's data, so Flow cannot react to them. A webhook connector or automation tool covers most of those cases.
- File uploads on free plans. Attachments work with
enctype="multipart/form-data"on paid plans.
Every ShipMyForm form can also be published as a hosted page with its own link, which you can add to your store's navigation or a QR code on packaging. Same inbox, same routing.
Next steps
- The markup, three ways: HTML contact form templates that email you
- Same idea on other builders: Webflow and Framer contact forms
- Send enquiries where the team works: form to Google Sheets
- Start free: 100 submissions a month, email and webhook routing, no card.
Frequently asked questions
- Can I add a custom form to Shopify without an app?
- Yes. Every Online Store 2.0 theme includes a Custom Liquid section. Add it to a page in the theme editor, paste a plain HTML form whose action points at a form endpoint, and submissions are stored, spam-filtered and routed to email, Slack or a spreadsheet. No app, no theme code changes.
- What is wrong with Shopify's built-in contact form?
- Nothing, if all you need is a message to one email address. It has fixed fields, no file uploads, no routing to other tools, no stored inbox, and spam handling that depends on Shopify's storefront reCAPTCHA setting. A form backend gives you your own fields and everything downstream.
- Where do submissions go?
- Wherever you connect: email to one or more addresses, Slack, Google Sheets, Notion, a webhook, or an automation tool like n8n or Zapier. They are also stored in an inbox you can search and export.
- Does the visitor leave my store after submitting?
- Briefly, then returns. Set the form's redirect URL to a page on your store, for example /pages/thank-you, and the visitor lands there after submitting. The domain has to be in the form's allowed-domains list.
- Will Shopify's reCAPTCHA protect this form?
- No. Shopify's storefront spam protection applies to its own forms. A custom form relies on the backend: a honeypot field in the markup plus server-side rate limiting and classification, which stops most spam with no CAPTCHA at all.
- Can I put the form on a product page?
- Yes. Custom Liquid can be added as a section or block on product templates as well as pages, so a request-a-quote form can sit under the add-to-cart button. Include a hidden field with the product title so you know which product the enquiry is about.
Related guides
Webflow & Framer Forms: Route Submissions Anywhere
Native Webflow and Framer forms are fine until the plan limits bite. One attribute (or one embed) routes your designed form through a real backend instead.
HTML Contact Form Template That Emails You (Copy and Paste)
Ready-to-use HTML email form code: a minimal form, a full contact form with honeypot and subject, and a file-upload version. Paste, set one attribute, and submissions land in your inbox.
How to Stop Contact Form Spam Without reCAPTCHA
Honeypots, rate limiting, and Turnstile — layered spam defenses that beat reCAPTCHA without the puzzles.