Customer accounts, forms and cart

This page covers the parts of a theme that interact with visitors: account pages, forms, predictive search and the cart. All paths are relative to the store's own domain.

The form tag

The form tag opens an HTML form, writes method and action itself and adds two hidden inputs: utf8 and form_type. The form object is available inside the body. Form types known to the engine and the targets it writes:

Form typeTarget
customer_login/account/login
customer_register/account
recover_customer_password/account/recover
reset_customer_password/account/reset
customer_address/account/addresses
contact/contact#contact_form
product/cart/add
cart/cart
Zone
{% form 'customer_login' %}
  <input type="email" name="email" autocomplete="email">
  <input type="password" name="password" autocomplete="current-password">
  <button type="submit">{{ 'hesap.giris' | t }}</button>
{% endform %}

Account operations

Login, registration, password and address operations are JSON requests: the theme script intercepts the form and posts a JSON body to the paths below. The session is kept in a cookie that page scripts cannot read; no token is returned in the response. On failure, the detail field of the response body can be shown.

DescriptionEndpointBody / fields
LoginPOST /api/sf-auth/loginemail, password
RegisterPOST /api/sf-auth/registerfull_name, email, password, phone, uyelik_sozlesmesi_kabul, kvkk_aydinlatma_okundu, ticari_ileti_izni
Password recovery requestPOST /api/sf-auth/password-reset/requestemail
Password reset (token is the ?token= value in the URL)POST /api/sf-auth/password-reset/confirmtoken, new_password
Add addressPOST /api/sf-auth/addressestitle, first_name, last_name, phone, line1, line2, district, city, postal_code, country, is_default_shipping, is_default_billing
Update / delete addressPATCH | DELETE /api/sf-auth/addresses/{id}—

Login, registration and password recovery requests send the reCAPTCHA token in the X-Recaptcha-Token header.

Registration consent fields

Two consents are mandatory in a registration request and must be sent as true; if either is missing registration is rejected with 422. The third is optional.

FieldDescription
uyelik_sozlesmesi_kabulAcceptance of the membership agreement. Required.
kvkk_aydinlatma_okunduConfirmation that the personal data notice was read. Required.
ticari_ileti_izniMarketing consent. Optional; when true a consent record is opened for e-mail and SMS.
JavaScript
fetch("/api/sf-auth/register", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Recaptcha-Token": recaptchaToken,
  },
  body: JSON.stringify({
    full_name: "Ada Yılmaz",
    email: "[email protected]",
    password: "en-az-8-karakter",
    uyelik_sozlesmesi_kabul: true,
    kvkk_aydinlatma_okundu: true,
    ticari_ileti_izni: false,
  }),
});

Contact form

The contact form is POSTed to /contact (form body). Fields read: contact[email], contact[body], contact[name], contact[phone], contact[subject]. After submission the visitor returns to the originating page with contact_posted=true or false. The recipient address is never taken from the form.

Predictive search

As the visitor types, /search/suggest?q=... (or /arama/oneri) is called. The response is an HTML fragment: the theme's sections/arama-onerileri section rendered with the predictive_search object. If the theme does not ship that section the response comes back with an empty body; your script should close the list on an empty response. With a term shorter than 2 characters predictive_search.performed is false; the term is truncated to 64 characters.

predictive_search fields: terms, performed, types and resources (products up to 6, collections up to 3, pages up to 2).

JavaScript
const yanit = await fetch("/search/suggest?q=" + encodeURIComponent(terim));
if (yanit.ok) {
  kutu.innerHTML = await yanit.text();
}

Cart

Cart forms accept POST only and return to /cart with a 303 afterwards. The cart is tracked by the sf_cart_token cookie. On failure an hata parameter is added to the URL.

EndpointBody / fields
POST /cart/addproduct_id (or id), variant_id, quantity (1-999)
POST /cart/changeid (line id), quantity (0 removes the line)
POST /cart/updateupdates[LINE_ID]=QUANTITY; processed in order
POST /cart/clearno fields
Zone
{% form 'product', product %}
  <input type="hidden" name="product_id" value="{{ product.id }}">
  <input type="hidden" name="variant_id" value="{{ product.selected_or_first_available_variant.id }}">
  <input type="number" name="quantity" value="1" min="1">
  <button type="submit">{{ 'urun.sepete_ekle' | t }}</button>
{% endform %}

hata values:

ValueMeaning
gecersizThe request could not be read.
oturumNo cart cookie.
stokInsufficient stock.
yokProduct or line not found.
hataOther errors.

To work without reloading the page the same operations are available as JSON; the full list is on the Storefront API page.

The platform emits no custom DOM events to Zone themes; handle cart changes in your own script.

Section rendering API

The engine can render a single section on its own: the section_id parameter returns that section's HTML, and the sections parameter (comma-separated, up to 5 ids) returns a JSON object mapping id to HTML. Today this is active only in the theme editor preview; on live store URLs these parameters are not applied yet and the full page is returned. To refresh fragments on a live store, use the JSON endpoints of the Storefront API.