DEV Community

Cover image for Sending Custom Form Data to Shopify Customer Notes Using API
Lucy
Lucy

Posted on

Sending Custom Form Data to Shopify Customer Notes Using API

Shopify’s default contact form is simple and easy to use, but it does not always meet the needs of growing businesses. For developers, theme customizers, and tech-savvy store owners, building a custom contact form offers more flexibility. One powerful enhancement is sending form submissions directly into the Shopify Customer Notes field, helping teams centralize important customer interactions inside the Shopify admin.

This approach is especially helpful when you want your support, sales, or onboarding team to see customer context without switching between tools.

This guide walks through how to build a custom contact form and programmatically store the submitted data into Shopify customer notes.

Why Save Contact From Data Into Customer Notes

Storing from data inside the customer profile gives you several benefit.

  • All customer messages stay inside Shopify.
  • Your sales and support teams get instant visibility.
  • No dependency on third-party CRMs
  • Easier customer history making

This works best when the customer is already identified by email. If the customer does not exist ,you can create a new one automatically before adding new note.

Step 1: Create a custom form in your Shopify theme using Liquid and HTML.
You can add this inside a page template or a custom section:

<form id="custom-contact-form">
  <input type="text" id="name" placeholder="Your Name" required />
  <input type="email" id="email" placeholder="Your Email" required />
  <textarea id="message" placeholder="Your Message" required></textarea>
  <button type="submit">Submit</button>
</form>

<div id="form-status"></div>
Enter fullscreen mode Exit fullscreen mode

This form captures basic information and is intentionally kept simple so it can be extended easily.

Step 2: Capture Form Data with JavaScript
Next, attach a JavaScript listener to handle form submission.

<script>
document.getElementById('custom-contact-form').addEventListener('submit', async function(e) {
  e.preventDefault();

  const name = document.getElementById('name').value;
  const email = document.getElementById('email').value;
  const message = document.getElementById('message').value;

  const response = await fetch('/apps/customer-note-handler', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name, email, message })
  });

  const status = await response.json();
  document.getElementById('form-status').innerText = status.message;
});
</script>
Enter fullscreen mode Exit fullscreen mode

The /apps/customer-note-handler route is a custom backend endpoint that we will handle in the next step.

Step 3: Create a backend Endpoint (Node.js Example)
Because Shopify's Admin API cannot be called securely from the frontend, you need a small backend application. Below is a simple Node.js + Express Example.

import express from 'express';
import fetch from 'node-fetch';

const app = express();
app.use(express.json());

const SHOP = 'your-store-name.myshopify.com';
const ACCESS_TOKEN = 'your-admin-api-access-token';

app.post('/apps/customer-note-handler', async (req, res) => {
  const { name, email, message } = req.body;

  try {
    const customerSearch = await fetch(
      `https://${SHOP}/admin/api/2024-01/customers/search.json?query=email:${email}`,
      {
        headers: {
          'X-Shopify-Access-Token': ACCESS_TOKEN
        }
      }
    );

    const searchResult = await customerSearch.json();
    let customerId;

    if (searchResult.customers.length > 0) {
      customerId = searchResult.customers[0].id;
    } else {
      const createCustomer = await fetch(
        `https://${SHOP}/admin/api/2024-01/customers.json`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-Shopify-Access-Token': ACCESS_TOKEN
          },
          body: JSON.stringify({
            customer: { first_name: name, email: email }
          })
        }
      );

      const created = await createCustomer.json();
      customerId = created.customer.id;
    }

    const noteText = `
Contact Form Submission:
Name: ${name}
Email: ${email}
Message: ${message}
    `;

    await fetch(
      `https://${SHOP}/admin/api/2024-01/customers/${customerId}.json`,
      {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
          'X-Shopify-Access-Token': ACCESS_TOKEN
        },
        body: JSON.stringify({
          customer: {
            id: customerId,
            note: noteText
          }
        })
      }
    );

    res.json({ message: 'Message saved to customer notes successfully.' });
  } catch (error) {
    res.status(500).json({ message: 'Something went wrong.' });
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));
Enter fullscreen mode Exit fullscreen mode

Step 4: Security and Best Practices
To make this production:

  • Never expose Admin API tokens in frontend code
  • Use Shopify App Auth instead of manual tokens
  • Add CAPTCHA or rate limiting to avoid spam
  • Always validate and sanitize inputs

When This Setup Is Most Useful

This solution is ideal when you are building customized customer journeys using modern Shopify themes and headless setups. Merchants working with dedicated Shopify developers often use this approach to build tailored experiences that standard forms cannot handle.

It is also commonly implemented by Shopify experts who want complete control over how customer communication is stored and tracked.

For large-scale stores working with Shopify plus agencies, this pattern gives much better visibility and workflow control inside Shopify admin.

Final Thoughts

A custom contact form that writes directly into Shopify customer notes gives you flexibility, better internal visibility, and tighter control over customer communication. For developers and theme customizers, this approach opens up a wide range of possibilities for building smarter, more connected storefront experiences.

Once implemented, your support and sales teams will never lose track of valuable customer conversations again.

Top comments (0)