Skip to content

Customer accounts

Signal ships seven account sections and the seven JSON templates that use them. They share one visual system — a narrow panel for the forms, a wide panel for the tables — and one stylesheet, so the account area reads as part of the store rather than as Shopify’s default furniture.

SectionTemplateServes
main-logintemplates/customers/login.json/account/login
main-registertemplates/customers/register.json/account/register
main-accounttemplates/customers/account.json/account
main-addressestemplates/customers/addresses.json/account/addresses
main-ordertemplates/customers/order.jsonA single order
main-activate-accounttemplates/customers/activate_account.jsonThe invite-activation link
main-reset-passwordtemplates/customers/reset_password.jsonThe password-reset link

All seven templates are present and wired — each one references its section and nothing else. They are not dead code.

Only two of the seven have any settings. Everything else is driven by Shopify’s own objects and the theme’s translations.

SettingTypeDefaultWhat it does
HeadingTextLog inThe page heading
SubtextText—An optional line under it
SettingTypeDefaultWhat it does
HeadingTextCreate an accountThe page heading
SubtextTextOrder history, saved addresses, and the drop list first.A line under it

main-account, main-addresses, main-order, main-activate-account and main-reset-password have no settings — their copy all comes from locales/en.default.json under customers.*, so it is translatable rather than per-theme-instance.

Two panels in one section, switched by the #recover / #login fragment: the login form and the password-recovery form. Both are Shopify’s native forms (customer_login and recover_customer_password) and report Shopify’s own errors through default_errors.

Also rendered:

  • a Forgot password link into the recovery panel, and a cancel link back
  • a Create account link to the register page
  • guest checkout login, but only when shop.checkout.guest_login is true — Shopify’s guest_login form, submitted as a plain link-styled button

Shopify’s create_customer form: first name, last name, email and password, with correct autocomplete attributes throughout and the email and password required. Field values are re-populated from the form object after a validation failure, so a rejected submission does not clear what was typed.

The signed-in home: a welcome line with the customer’s email, a log-out link, and two panels.

Orders is a real table — order number (linking to the order), date, payment status, fulfilment status and total — paginated at 12 per page with the theme’s standard pager. paid and fulfilled statuses are given the accent treatment so the common case is scannable. With no orders, an empty state offers a link to the all-products collection.

Details shows the default address through format_address (so it is formatted correctly per country) plus a link to the address book carrying the address count.

A grid of cards, paginated at 6. The first card is always the add new form; each existing address renders its formatted address plus an Edit <details> containing a pre-filled form.

The fields themselves come from one shared set of address fields used by both forms: first and last name, company, two address lines, city, postal code, country, province, phone, and a “set as default” checkbox. The snippet takes a uid parameter — the address id when editing, New when adding — so two forms on one page never collide on element ids.

Province is populated from Shopify’s own country data by the theme’s shared country/province wiring, and the whole field is hidden for countries that have no provinces. The same code drives the cart page’s shipping estimator.

Delete uses a confirm dialog, then builds and submits a form with _method=delete — rather than Shopify’s legacy inline-onclick helper, which no longer belongs in a modern theme.

A full order view: title and date, a cancellation notice with its reason when the order was cancelled, then a line-item table.

Each line shows the title (linked when the product still exists), the selling plan name on a subscription line, unit pricing when applicable, and tracking — the tracking number, as a link when the carrier supplied a URL.

The table’s footer builds the real total: subtotal, each cart-level discount, each shipping method with its price, each tax line with its rate, and the order total. Below it, the shipping and billing addresses through format_address, plus the payment and fulfilment status labels.

Shopify’s activate_customer_password form — a password and its confirmation — plus a Decline submit, which is what Shopify expects to let an invited customer refuse the invitation.

Shopify’s reset_customer_password form: a new password and its confirmation. Reached only from the link in Shopify’s reset email.

  • Every field has a real <label>, visible in the account area rather than hidden, and the correct autocomplete value so password managers behave.
  • Errors use form.errors | default_errors, so the messages are Shopify’s own and already translated.
  • Tables are wrapped in a horizontal scroll container, so an order with long product names does not break the layout on a phone.
  • Pagination reuses the theme’s s-pgn pager, so it looks identical to the collection and blog pagers.