# Customer data and newsletter

> Let logged-in customers see and change their own data, and collect newsletter sign-ups from any visitor. Covers the name form, customer metafields shown and edited, the email subscription, store credit and the newsletter form.

Status: Ready (Smootify 2.0)  
URL: https://www.smootify.io/docs/astro/build/customer-data  
Updated: 2026-10-21

Beyond orders and addresses, an account can hold the customer’s own data: their name, preferences you store in customer metafields, their email subscription and their store credit. This page builds the forms that show and change them. It ends with a newsletter form that works for any visitor, logged in or not.

> [!NOTE]
> Customer accounts must be set up first: see [Customer accounts](https://www.smootify.io/docs/astro/build/account). The newsletter form and file fields also need the Server plan.

## 1. The customer’s name

Add a `customer-user-update` element, with a `<form>` inside it. The form needs two `input` fields whose `name` is `firstName` and `lastName`, and a submit button. Without both fields, the element removes itself.

Smootify fills the fields with the customer’s current name. When the customer saves, `form-done` shows, every `[customer]` value on the page updates without a reload, and after 5 seconds the form comes back with the new values. `customer-condition="no-names"` can show a reminder to customers who have not given both names yet.

## 2. Show customer metafields

Customer metafields hold the data you add to a customer in Shopify: a shoe size, a loyalty level, a birthday. `customer-metafield="shoe_size"` on a text element shows the metafield `custom.shoe_size` of the logged-in customer, anywhere on any page.

**Shopify set-up.** Create the definition under **Settings › Custom data › Customers**, and set its **Customer accounts** access to **Read**, or to **Read and write** if customers edit it (step 3):

In the Shopify admin, under Settings › Custom data › Customers:

- **Shown on the page.** A definition such as Loyalty level, `custom.loyalty_level`, Single line text, with **Customer accounts access** set to **Read**. `customer-metafield="loyalty_level"` shows its value, such as Gold.
- **Edited by the customer.** A definition such as Shoe size, `custom.shoe_size`, Integer, with **Customer accounts access** set to **Read and write**. A field named `shoe_size` in `customer-metafields-editor` shows and saves it, such as 38.

Without customer accounts access the value stays empty, and the editor saves only with Read and write.

- **Namespace.** Add `namespace="…"` when the namespace is not `custom`.
- **Types.** Every type renders as on the product page: text, numbers, dates, files, lists, references. See [Metafields on the page](https://www.smootify.io/docs/astro/build/metafields) and [metafield types](https://www.smootify.io/docs/astro/reference/metafield-types).
- **Show or hide.** `if-customer-metafield="…"` shows an element only when the metafield is set (for a number, above 0; for a true-or-false, true). `unless-customer-metafield="…"` shows it only when the metafield is not set. Add `data-check-value="…"` to compare with a value instead. See [customer metafield conditions](https://www.smootify.io/docs/astro/reference/conditions/customer-metafield).
- **B2B.** `company-metafield="…"` and its `if-` and `unless-` forms read the metafields of the customer’s company.
- **Logged out.** These elements are taken out of the page for a visitor who is not logged in.

The attributes are in [customer metafields](https://www.smootify.io/docs/astro/reference/attributes/customer-metafield).

## 3. Let customers edit their metafields

Add a `customer-metafields-editor` element, with a `<form>` inside it. Add one field per metafield. The field’s `name` is the key of the metafield, as Shopify shows it, such as `shoe_size`, or the same words with spaces, such as `Shoe size`: Smootify turns the name into the key. The editor saves in the namespace `custom`.

```html
<customer-metafields-editor>
  <form>
    <input name="shoe_size">
    <select name="favourite_colour"><option value="Red">Red</option><option value="Blue">Blue</option></select>
    <button type="submit"><span data-state="default">Save</span><span data-state="loading">Saving…</span></button>
  </form>
  <div form-done hidden>Saved</div>
  <div form-fail hidden>Something went wrong</div>
</customer-metafields-editor>
```

- **Fields.** Text inputs, textareas, selects, radio buttons and checkboxes work. For a select or radio buttons, the option’s `value` is what is saved. A checkbox alone, for a true-or-false metafield, saves true when ticked and false when not.
- **Prefilled.** Smootify fills each field with the value saved in Shopify, and picks the matching option.
- **Every field needs a definition.** A field whose `name` matches no customer metafield definition makes the save fail. Its definition needs **Read and write** access for customer accounts.
- **Fields that are not saved.** A field whose `name` starts with `_`, such as `_accepted`, is never saved. Use it for a field the form needs but Shopify does not, such as a checkbox to accept your terms, with the `required` attribute.
- **Emptying a field deletes the value** in Shopify. A field hidden by a condition is left as it is.
- **After saving**, `form-done` shows, and after 5 seconds the form comes back with the new values. With a `data-redirect` (or `redirect`) on the `<form>`, Smootify goes to that address instead.
- **Errors.** When Shopify refuses a value, for example text in a number metafield, its message shows in the form’s `form-fail`.

**Files.** With the Server plan, a [`file-input`](https://www.smootify.io/docs/astro/reference/elements/file-input) in the editor uploads a file to Shopify and saves it in a File metafield. Its `name` is the metafield’s key, and `data-multiple` allows several files for a list of files. The files the customer saved before show in it, with their name, and with their preview when the item template has `upload="preview"`. Only images get a preview: a saved PDF or another file shows its name alone. Removing the last one empties the metafield. See [File uploads](https://www.smootify.io/docs/astro/features/file-uploads).

## 4. Email subscription

Two forms let a logged-in customer change their email marketing subscription, with the email of their account. To collect new subscribers from any visitor, use the newsletter form of step 6:

- **Change a customer’s subscription**: `customer-subscribe-email` and `customer-unsubscribe-email`. For logged-in customers, with the email of their account. Wrap each form in its condition: `customer-condition="email-not-subscribed"` around the subscribe form, `customer-condition="email-subscribed"` around the unsubscribe form.
- **Collect new subscribers**: `newsletter-subscribe` (step 6). For any visitor, with the email they type. Needs the Server plan, Newsletter Subscription turned on in the Smootify dashboard, and an `input` with `type="email"`.

Each of the two account forms is an element with a `<form>` and a submit button inside it. Wrap each one in an element with the matching condition, so the customer sees only the form that applies. The conditions follow at once when the customer saves.

```html
<div customer-condition="email-not-subscribed">
  <customer-subscribe-email>
    <form><button type="submit">Subscribe to our emails</button></form>
    <div form-done hidden>You are subscribed</div>
    <div form-fail hidden>Something went wrong</div>
  </customer-subscribe-email>
</div>
<div customer-condition="email-subscribed">
  <customer-unsubscribe-email>
    <form><button type="submit">Unsubscribe</button></form>
    <div form-done hidden>You are unsubscribed</div>
    <div form-fail hidden>Something went wrong</div>
  </customer-unsubscribe-email>
</div>
```

## 5. Store credit

Shopify can give a customer store credit, which they spend at checkout. Add a `store-credit` element to show it. A customer with no store credit sees a balance of 0 and no movements, so the card can stay on the account page.

```html
<store-credit>
  <div>Your credit: <span store-credit="balance">$0.00</span></div>
  <store-credit-transaction>
    <div store-credit-transaction="createdAt">1/1/2026</div>
    <div store-credit-transaction="event">Order payment</div>
    <div store-credit-transaction="amount">$0.00</div>
  </store-credit-transaction>
</store-credit>
```

- **Balance.** `store-credit="balance"` shows the balance. `store-credit="expirableBalance"` shows the part of it that expires. Wrap it in an element with `if-credit="expires"`, which is removed when no credit expires.
- **Transactions.** `store-credit-transaction` is the template of one movement, repeated for each. Inside it: `amount`, `balanceAfterTransaction`, `event` (what happened, such as an order payment, a subscription payment or a refund), `createdAt` and `expiresAt`. An element with `if-credit-transaction="expires"` is removed from the movements that do not expire.
- **No credit yet.** An element with `customer-condition="no-store-credit"` shows only while the customer has no balance and no movements, such as “No credit yet. A refund or a credit from us shows here.” Put the movements in an element with `customer-condition="has-store-credit"`. To hide the whole card instead, give `store-credit` itself `customer-condition="has-store-credit"`.
- **Your own words.** The `event` texts are in English. The `SmootifyStoreCreditEventsLabel` script changes them, built like the status labels in [Orders and buy again](https://www.smootify.io/docs/astro/build/orders), with Shopify’s codes such as `ORDER_PAYMENT` as keys.

See [`store-credit`](https://www.smootify.io/docs/astro/reference/elements/store-credit) and [store credit values](https://www.smootify.io/docs/astro/reference/attributes/store-credit). To give credit on its own, the Flow library has [Store credit on a paid order](https://www.smootify.io/flows/store-credit): Shopify Flow credits a share of every paid order above an amount you choose. To show in the cart what an order will earn, a short script does it: see [the store credit a cart earns](https://www.smootify.io/docs/astro/developers/events#example-the-store-credit-a-cart-earns).

## 6. Newsletter form for any visitor

`newsletter-subscribe` turns a `<form>` into a newsletter sign-up. The visitor does not need an account: Smootify adds the email to your Shopify customers, subscribed to email marketing. It needs the Server plan, and **Newsletter Subscription** turned on in the Smootify dashboard.

1. Add a `newsletter-subscribe` element, and put a `<form>` inside it.
2. In the form, add an `<input type="email">`, then a submit button.
3. Optional: add `tags="newsletter, footer"` to `newsletter-subscribe` to tag the new customers in Shopify, for example to know which form they used.

```html
<newsletter-subscribe tags="newsletter">
  <form>
    <input type="email" name="email">
    <button type="submit"><span data-state="default">Subscribe</span><span data-state="loading">Please wait…</span></button>
  </form>
  <div form-done hidden>Thanks for subscribing</div>
  <div form-fail hidden>Something went wrong</div>
</newsletter-subscribe>
```

After the submit, `form-done` shows. With a `data-redirect` (or `redirect`) on the `<form>`, Smootify then goes to that address. The subscribers are in Shopify, under **Customers**:

In Shopify, under Customers, for a form with `tags="newsletter, footer"`:

- **A new email**, such as nora@example.com: a new customer with that email, subscribed to email marketing, with the tags newsletter and footer.
- **An email Shopify knows**, such as Anna Rossi's anna@example.com: the customer is marked as subscribed; the tags are not added, so Anna keeps only her own tags.

## Before you publish

> [!STUCK]
> - **The name form disappears.** It has no `input` fields named `firstName` and `lastName`.
> - **The metafields editor does not save.** A field's `name` matches no customer metafield definition, or the definition's customer accounts access is not **Read and write**.
> - **A customer metafield stays empty.** Its definition's customer accounts access is off.
> - **The newsletter form does nothing.** The site is not on the Server plan, or Newsletter Subscription is not turned on.
> - **A newsletter form disappears.** Its `<form>` has no `input` with `type="email"`.
> - **Tags are missing on some subscribers.** They were already customers: the tags go only on new customers.
