Skip to main content

Profile Pages

Profile pages are customer account pages in the webshop. Templates control their structure and visual design, while the built-in Vue behavior loads customer data and handles interactions.

The recommended split is:

  • Twig controls page structure, navigation, loading states, and styling.
  • Built-in Vue modules control customer data, forms, and interactive behavior.
  • Templates use Vue bindings to display the data supplied by those modules.

You do not need to create API requests or authentication logic for these pages.


Profile Page Files​

Profile pages are grouped in the pages/profile folder:

pages/
profile/
orders.twig
my-profile.twig
addresses.twig
help.twig
login.twig
register.twig
PageURLFileMount point
Orders/profilepages/profile/orders.twig#orders
Customer information/profile/my-profilepages/profile/my-profile.twig#user_info
Saved addresses/profile/saved-addressespages/profile/addresses.twig#addresses
Saved cards/profile/saved-cardspages/profile/cards.twig#cards
Help (customer service)/profile/helppages/profile/help.twig#help
Notifications/profile/notificationspages/profile/notifications.twig
My products/profile/my-productspages/profile/products.twig
Wishlist/profile/wishlistpages/profile/wishlist.twig
Login/loginpages/profile/login.twig#login
Registration/registerpages/profile/register.twig#register

Orders, customer information, saved addresses, saved cards, my products and notifications need a logged-in customer: a visitor is sent to the login. The help page and the wishlist are open to visitors. The URLs above are under the sale channel's prefix (/{language}/{slug}/profile); build the menu links of these pages with shop_url, as the short form is only forwarded by the platform.

Two pages are optional: My products and Wishlist exist only when the template has their file; without it the visit is forwarded to the orders page, so the menu should link to them only when the template has them.

The Help page is the customer service page: the customer's name, e-mail and phone, a subject and a message. When the sale channel's show_tickets setting is on (webshop.sale_channel.show_tickets) it also lists the customer's tickets. The order management dialog opens from the orders page, and a return that cannot start there continues on the help page (help_url), see Order management dialog.

The log out page (/profile/log-out) is the engine's own and has no template file.

---|---|---| | Orders | pages/profile/orders.twig | #orders | | Saved addresses | pages/profile/addresses.twig | #addresses | | Login | pages/profile/login.twig | #login | | Registration | pages/profile/register.twig | #register |

Other account pages may be added to the same folder as they become template-ready.


Orders Page​

The orders page must have a root element with the orders ID. The built-in orders module mounts automatically when this element exists:

<div id="orders" v-cloak>
<!-- orders page markup -->
</div>

Use v-cloak to prevent Vue expressions from appearing before the page finishes loading.

The template should provide loading, error, and content states:

<div v-if="orders === null && !ordersError">
<!-- loading or skeleton state -->
</div>

<p v-else-if="ordersError" v-text="ordersError"></p>

<div v-else>
<!-- order list -->
</div>

Order List Markup​

Orders are available through orders.data. The order card markup belongs directly in the Twig template and can be designed freely:

<template v-for="order in orders.data" :key="order.id">
<article class="order-card">
<h2 v-text="order.pretty_id"></h2>
<span v-text="order.status_label"></span>
<span v-text="order.product_name"></span>

<a :href="order.url">
View order
</a>
</article>
</template>

You can change the HTML structure, CSS classes, layout, buttons, spacing, and responsive behavior without changing the orders module.

Do not create a separate single-order component for this page. Keeping the order markup in the Twig file allows every template to use its own order-card design.


Order Values​

The orders module prepares common display values for the template:

ValueDescription
order.pretty_idCustomer-facing order number
order.created_atOrder date
order.status_labelLocalized order status
order.product_nameProduct name when the order contains one product
order.item_countNumber of ordered items
order.exchange_item_countNumber of exchanged items
order.price.amountOrder total
order.price.currencyCurrency code
order.productsProducts included in the order
product.main_imageMain image for a product
order.orderItemsOriginal order item data

Product images can be rendered like this:

<div v-for="product in order.products" :key="product.id">
<img
v-if="product.main_image"
:src="product.main_image"
alt=""
>
</div>

Prefer the prepared values such as status_label, product_name, and product.main_image instead of repeating data transformation logic in Twig.


Product Counts​

When an order has no single product name, display its item count in the template:

<span v-if="order.exchange_item_count > 0">
<span v-text="order.item_count"></span>
{{ 'profile.item'|trans }},
<span v-text="order.exchange_item_count"></span>
{{ 'profile.item_changed'|trans }}
</span>

<span v-else-if="order.product_name" v-text="order.product_name"></span>

<span v-else>
<span v-text="order.item_count"></span>
{{ 'profile.item'|trans }}
</span>

Twig owns the translated labels. Vue supplies only the dynamic numbers and product values.


Saved Addresses​

The saved addresses page uses the addresses mount point. Addresses are available through addresses and support the built-in edit and delete actions:

<div id="addresses" v-cloak>
<article v-for="address in addresses" :key="address.id">
<h2><span v-text="address.postalCode"></span> <span v-text="address.city"></span></h2>
<p><span v-text="address.street"></span> <span v-text="address.house"></span></p>

<button @click="loadModalModule('addressModal', address.id)">
Edit
</button>
<button @click="loadDialogModule('deleteDialog', address.id, address.userId)">
Delete
</button>
</article>

<button @click="loadModalModule('addressModal')">
Add address
</button>
</div>

The address editor and delete confirmation are provided by the built-in account behavior.

Login And Registration​

Login and registration pages use their own mount points:

<div id="login" v-cloak>
<!-- email and verification-code forms -->
</div>

<div id="register" v-cloak>
<!-- registration form -->
</div>

The login page has two states: email entry and verification-code entry. The registration page supports customer details, phone validation, terms acceptance, and captcha when required. Keep the form fields bound to the documented names used by the built-in behavior.

Account Mount Points​

Built-in account modules use mount points. A template only needs to provide the matching element when it wants to display a particular account feature:

FeatureMount point
Orders#orders
Customer information#user_info
Saved addresses#addresses
Saved cards#cards
Login#login
Registration#register
Help#help

The modules only activate on pages where their mount point is present.


Adding A Profile Page​

When a new profile page becomes available for templates:

  1. Add its Twig file under pages/profile/.
  2. Add the documented mount point.
  3. Build the complete page structure in Twig.
  4. Use the documented Vue values and bindings.
  5. Include loading, empty, error, and logged-out states.
  6. Add responsive styling for desktop and mobile layouts.

Keep API calls, authentication, validation, and interactive state in the built-in modules. Keep the page markup and visual presentation in the template.