All resources
Static site forms

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.com domain 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:

html
<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:

html
<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 value to {{ 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.
No page to put it on?:

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

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