> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# $wsAccount - Account & address data

> Read and display account and address data of the logged-in customer in the frontend, including login state checks and personalized template output.

# \$wsAccount - Account & address data

With the `$wsAccount` module, you read the account and [address data](/en/glossar#adresse) of the currently logged-in customer and display them in the template.

This page is aimed at frontend developers who design customer account pages or personalized areas of the shop. It assumes that you are familiar with the structure of WEBSALE templates and the template syntax (`{{ ... }}`). If not, first read [Introduction to templates](/en/frontend/die-basics/template-engine), because the examples on this page use this syntax consistently.

This page is exclusively about **reading and displaying** existing account and address data. Everything that **changes** data (create, edit, or delete an address, change a password) is described under [Actions → Account](/en/frontend/referenz/aktionen/account), because the triggering actions and their parameters are documented there.

<Note>
  Most values of `$wsAccount` are only filled if the customer is logged in. Therefore, check with [`$wsAccount.isLoggedIn`](#wsaccount-isloggedin) whether a customer is logged in before accessing them – otherwise you will read empty values and unintentionally display empty fields.
</Note>

***

## Basic concept

Working with `$wsAccount` always follows the same flow: **check the login state → read data → react.**

Before you read customer data, you need to know whether a customer is logged in at all. Only the logged-in state fills the variables with values. Then you read the desired data (e.g. the display name or an address) and react to it, for example with a personal greeting or by displaying the address book.

**When the data is available:** If no customer is logged in, account variables return empty values. This is the reason why almost every example on this page starts with an `isLoggedIn` check – without it you would output empty or missing fields for non-logged-in visitors.

**Time of execution:** The [template code](/en/glossar#template-code) is executed during page build, not during a later user action. So `$wsAccount` contains the account state at the time the page is generated. If a customer just logs in, their data is only available on the next page request.

### Address model (applies to all address accesses)

A customer usually has more than one address. So that you can read out the correct address for the correct purpose, `$wsAccount` distinguishes several access paths:

* [`addresses`](#wsaccount-addresses) – the complete list of all stored addresses. Use this list when you display an address book or iterate over all addresses.
* [`defaultBillAddress`](#wsaccount-defaultbilladdress) – the main billing address. Use it when the billing address is specifically needed.
* [`defaultDeliveryAddress`](#wsaccount-defaultdeliveryaddress) – the default shipping address. Use it when the shipping address is specifically needed.
* [`typeSeparation`](#wsaccount-typeseparation) – information on whether billing and shipping addresses are managed separately. Evaluate this map before offering the customer to create a new billing address.

Each individual address – no matter which way it is loaded – provides the same properties (e.g. `firstName`, `street`, `zip`). These properties are described once centrally under [Properties of `$wsAccount.addresses`](#eigenschaften-von-wsaccountaddresses) so that they do not have to be repeated for each access path.

***

## Module overview

**Example / excerpt of** `$wsAccount`

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsAccount | json }}
```

**JSON output** (observed structure of a logged-in customer)

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "addressFields": [...],
  "addresses": [...],
  "autoLogInRestriction": "...",
  "backInStockList": [...],
  "customerData": { ... },
  "defaultBillAddress": { ... },
  "defaultDeliveryAddress": { ... },
  "displayName": "...",
  "email": "...",
  "id": "...",
  "isAccountVerified": true,
  "isAutoLogInRestricted": true,
  "isAutoLoggedIn": true,
  "isLoggedIn": true,
  "isPasswordResetRequired": true,
  "lastLogin": "...",
  "loadAddress": "ƒ()",
  "loginRequired": "ƒ()",
  "pseudoCreditCards": [...],
  "typeSeparation": { ... }
}
```

Note: `"ƒ()"` denotes a function (method).

**Variables overview**

| **Name**                  | **Return type** | **Description**                                                             |
| ------------------------- | --------------- | --------------------------------------------------------------------------- |
| `addressFields`           | array           | List of all available address fields with their configuration.              |
| `addresses`               | array           | List of all stored addresses of the customer.                               |
| `autoLogInRestriction`    | string          | Status of the auto-login restriction.                                       |
| `backInStockList`         | array           | Products for which the customer has requested an availability notification. |
| `customerData`            | map             | Customer-specific fields (e.g. label, type, value).                         |
| `defaultBillAddress`      | map             | Main billing address as an address map.                                     |
| `defaultDeliveryAddress`  | map             | Default shipping address as an address map.                                 |
| `displayName`             | string          | Display name of the customer.                                               |
| `email`                   | string          | Email address of the customer account.                                      |
| `id`                      | string          | User ID of the customer account.                                            |
| `isAccountVerified`       | bool            | Whether the customer account has been verified.                             |
| `isAutoLoggedIn`          | bool            | Whether the user was logged in automatically.                               |
| `isAutoLogInRestricted`   | bool            | Whether not all shop functions are available during the automatic login.    |
| `isLoggedIn`              | bool            | Whether the user is logged in.                                              |
| `isPasswordResetRequired` | bool            | Whether the password needs to be reset.                                     |
| `lastLogin`               | string          | Date of the last login.                                                     |
| `pseudoCreditCards`       | array           | Stored credit cards (pseudonymized).                                        |
| `typeSeparation`          | map             | Information about address type separation.                                  |

<Note>
  **To be checked:** The `mainAddress` variable is used in some existing examples but does **not** appear in the observed JSON output above. Before `mainAddress` is documented, it must be checked against the code/actual behavior whether this variable still exists. The examples on this page therefore consistently use the fields `defaultBillAddress`, `defaultDeliveryAddress`, and `addresses` confirmed in the JSON output.
</Note>

**Methods overview**

| **Method**        | **Return type** | **Description**                                     |
| ----------------- | --------------- | --------------------------------------------------- |
| `loadAddress()`   | map             | Loads an address by its ID.                         |
| `loginRequired()` | bool            | Returns whether a specific action requires a login. |

Address maps additionally provide two of their own methods: [`customLabel()`](#addresscustomlabel) and [`defaultValue()`](#addressdefaultvalue).

***

## Templates

The data of a customer can – provided that they are logged in – be loaded and displayed in any `.htm` template.

In the standard delivery shop, the templates for the customer account pages are located in the `views/account` directory. They serve as the basis for displaying and editing customer data. However, you can also use the same data in other templates, for example for a personal greeting on the home page – the only prerequisite is that the customer is logged in (see [Basic concept](#grundkonzept)).

***

## Variables

### \$wsAccount.isLoggedIn

Returns whether the user is logged in.

This check is at the start of almost every account evaluation, because all other variables only return meaningful values in the logged-in state.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  <!-- Customer is logged in -->
{{ else }}
  <!-- Customer is not logged in -->
{{ /if }}
```

### \$wsAccount.email

Returns the email address of the customer account.

In the checkout, a customer can also order as a guest. In that case, there is no account email, but a guest email address from the checkout. The following example therefore covers both cases so that the appropriate address is always displayed:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.guestMail }}
  {{= $wsCheckout.guestMail }}
{{ else }}
  {{= $wsAccount.email }}
{{ /if }}
```

> `$wsCheckout.guestMail` comes from the [\$wsCheckout](/en/frontend/referenz/module/wscheckout) module and is only filled during the ordering process.

### \$wsAccount.id

Returns the user ID of the customer account. Use it to uniquely reference a customer, for example in links or tracking.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  User ID: {{= $wsAccount.id }}
{{ /if }}
```

### \$wsAccount.displayName

Returns the display name of the customer. Use it for a personal greeting without having to load a complete address.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  Hello {{= $wsAccount.displayName }}
{{ /if }}
```

### \$wsAccount.isAccountVerified

Returns whether the customer account has been verified. Evaluate this if certain functions should only be unlocked after verification.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isAccountVerified }}
  <!-- Account is verified -->
{{ /if }}
```

### \$wsAccount.isAutoLoggedIn

Returns whether the user was logged in automatically (via "Stay logged in"). This is relevant because an automatic login can be restricted – see `isAutoLogInRestricted`.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isAutoLoggedIn }}
  <!-- User was logged in automatically -->
{{ /if }}
```

### \$wsAccount.isAutoLogInRestricted

Returns whether **not** all shop functions are available during the automatic login. Evaluate this before offering a customer who is logged in automatically security-relevant actions (e.g. address change) – these may require a renewed login. More information [in the configuration](/en/konfiguration/accounts-benutzerkonten#6-accounts-autologin-angemeldet-bleiben).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isAutoLogInRestricted }}
  <!-- Not all shop functions available – offer renewed login if necessary -->
{{ /if }}
```

### \$wsAccount.autoLogInRestriction

Returns the status of the auto-login restriction as a string. More information [in the configuration](/en/konfiguration/accounts-benutzerkonten#6-accounts-autologin-angemeldet-bleiben).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.autoLogInRestriction }}
  <!-- Auto-login restriction is active -->
{{ /if }}
```

### \$wsAccount.lastLogin

Returns the date of the last login. Use it, for example, for a notice "Your last login was on …".

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.lastLogin }}
  Last login: {{= $wsAccount.lastLogin }}
{{ /if }}
```

### \$wsAccount.isPasswordResetRequired

Returns whether the password needs to be reset. Evaluate this to specifically guide the customer to change the password instead of letting them run into a blocked function. More information [in the configuration](/en/konfiguration/accounts-benutzerkonten#2-accounts-account-benutzerkonto).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isPasswordResetRequired }}
  Please reset your password.
{{ /if }}
```

### \$wsAccount.customerData

Returns customer-specific fields (e.g. label, type, and value). Use this variable to display additionally configured customer fields without knowing each field individually. More information [in the configuration](/en/konfiguration/accounts-benutzerkonten#5-accounts-addressfield-einzelne-adressfelder-definieren).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsAccount.customerData }}
  {{= $field.value }}
{{ /foreach }}
```

### \$wsAccount.addressFields

Returns a list of all available address fields with their configuration. Use it to build address forms dynamically from the configuration instead of hard-wiring fields.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsAccount.addressFields }}
  {{= $field }}
{{ /foreach }}
```

### \$wsAccount.backInStockList

Returns the products for which the customer has requested an availability notification. Display the list in the customer account so that the customer can see and manage their watched products.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $product in $wsAccount.backInStockList }}
  {{= $product }}
{{ /foreach }}
```

### \$wsAccount.pseudoCreditCards

Returns the stored credit cards in pseudonymized form. The pseudonymization is intentional: complete card data may not be available in the frontend for security and data protection reasons.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $card in $wsAccount.pseudoCreditCards }}
  {{= $card }}
{{ /foreach }}
```

### \$wsAccount.typeSeparation

Returns information about the address type separation. Via this map, you check whether billing and shipping addresses are managed separately and what restrictions apply. Evaluate it before offering the customer to create a new billing address – otherwise you offer an action that the shop would reject.

#### Properties of `$wsAccount.typeSeparation`

| **Property**                 | **Return type** | **Description**                                                                              |
| ---------------------------- | --------------- | -------------------------------------------------------------------------------------------- |
| `enabled`                    | bool            | Whether the address type separation is active.                                               |
| `canCreateBillAddress`       | bool            | Whether a new billing address can still be created.                                          |
| `maxBillAddresses`           | int             | Maximum number of allowed billing addresses. `0` = unlimited, `-1` = separation deactivated. |
| `defaultBillAddressReadonly` | bool            | Whether the main billing address is read-only.                                               |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.typeSeparation.enabled }}
  {{ if $wsAccount.typeSeparation.canCreateBillAddress }}
    <!-- A new billing address can be created -->
  {{ else }}
    <!-- Maximum number of billing addresses reached -->
  {{ /if }}
{{ /if }}
```

### \$wsAccount.defaultBillAddress

Returns the customer's main billing address as an address map (including `id`), provided that one exists. Use it when the billing address is specifically needed. The available properties correspond to those of [`$wsAccount.addresses`](#eigenschaften-von-wsaccountaddresses).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.defaultBillAddress }}
  First name: {{= $wsAccount.defaultBillAddress.firstName }}
  Last name: {{= $wsAccount.defaultBillAddress.lastName }}
{{ /if }}
```

### \$wsAccount.defaultDeliveryAddress

Returns the customer's default shipping address as an address map (including `id`), provided that one exists. Use it when the shipping address is specifically needed. The available properties correspond to those of [`$wsAccount.addresses`](#eigenschaften-von-wsaccountaddresses).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.defaultDeliveryAddress }}
  First name: {{= $wsAccount.defaultDeliveryAddress.firstName }}
  Last name: {{= $wsAccount.defaultDeliveryAddress.lastName }}
{{ /if }}
```

### \$wsAccount.addresses

Returns the list of all the customer's stored addresses. Use it for an address book or when you want to iterate over all addresses.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $address in $wsAccount.addresses }}
  {{= $address.firstName }} {{= $address.lastName }}
{{ /foreach }}
```

<Info>
  Each address from `$wsAccount.addresses` (and likewise from `defaultBillAddress`, `defaultDeliveryAddress`, and `loadAddress()`) provides the following properties.
</Info>

#### Properties of `$wsAccount.addresses`

| **Property**               | **Return type** | **Description**                                        |
| -------------------------- | --------------- | ------------------------------------------------------ |
| `id`                       | string          | Address ID                                             |
| `salutationCode`           | string          | Salutation code                                        |
| `titleCode`                | string          | Title code (e.g. Dr., Prof.)                           |
| `firstName`                | string          | First name                                             |
| `lastName`                 | string          | Last name                                              |
| `company`                  | string          | Company name                                           |
| `department`               | string          | Department                                             |
| `street`                   | string          | Street                                                 |
| `streetNumber`             | string          | House number                                           |
| `additionalInfo`           | string          | Additional address information                         |
| `zip`                      | string          | Zip code                                               |
| `city`                     | string          | City                                                   |
| `state`                    | string          | State / region                                         |
| `country`                  | string          | Country                                                |
| `phone`                    | string          | Phone number                                           |
| `mobilephone`              | string          | Mobile phone number                                    |
| `fax`                      | string          | Fax number                                             |
| `businessPhone`            | string          | Business phone number                                  |
| `businessFax`              | string          | Business fax number                                    |
| `dateOfBirth`              | string          | Date of birth                                          |
| `taxId`                    | string          | Tax ID                                                 |
| `addressType`              | string          | Type of the address                                    |
| `custom`                   | map             | User-defined address fields                            |
| `isBillAddress`            | bool            | Whether the address can be used as a billing address.  |
| `isDeliveryAddress`        | bool            | Whether the address can be used as a shipping address. |
| `isDefaultBillAddress`     | bool            | Whether this is the main billing address.              |
| `isDefaultDeliveryAddress` | bool            | Whether this is the default shipping address.          |
| `isReadonly`               | bool            | Whether the address is read-only.                      |
| `type`                     | string          | Pool type of the address (`"bill"` or `"delivery"`).   |

#### \$address.customLabel()

Returns the custom label for a specific address field depending on the address type. Use the method to take form labels from the configuration instead of hard-coding them in the template.

**Signature** `$address.customLabel(fieldName, addressType)`

**Return value** `string` – the configured label for the field.

**Parameters**

| **Name**      | **Type** | **Required** | **Description**                                                                |
| ------------- | -------- | ------------ | ------------------------------------------------------------------------------ |
| `fieldName`   | string   | yes          | Name of the address field (e.g. `"firstName"`).                                |
| `addressType` | string   | yes          | Address type: `"bill"` (billing), `"delivery"` (shipping), or `"both"` (both). |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
First name label: {{= $address.customLabel("firstName", "bill") }}
```

#### \$address.defaultValue()

Returns the configured default value for a specific address field depending on the address type. Use the method to pre-populate fields with sensible defaults.

**Signature** `$address.defaultValue(fieldName, addressType)`

**Return value** `string` – the configured default value for the field.

**Parameters**

| **Name**      | **Type** | **Required** | **Description**                                                                |
| ------------- | -------- | ------------ | ------------------------------------------------------------------------------ |
| `fieldName`   | string   | yes          | Name of the address field (e.g. `"company"`).                                  |
| `addressType` | string   | yes          | Address type: `"bill"` (billing), `"delivery"` (shipping), or `"both"` (both). |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $address.defaultValue("company", "delivery") }}
```

<Note>
  **Note:** The methods `customLabel()` and `defaultValue()` currently only take effect in the checkout once the customer has selected an address. In the customer account, they do not yet distinguish between shipping and billing addresses – this is planned for a future version.
</Note>

***

## Methods

### \$wsAccount.loginRequired()

Returns whether the user has to be logged in for a specific action. Evaluate this before offering an action, so that you guide a customer who is not logged in to the login beforehand, instead of letting them run into a rejected action. More information [in the configuration](/en/konfiguration/accounts-benutzerkonten#6-accounts-autologin-angemeldet-bleiben).

**Signature** `$wsAccount.loginRequired(actionName)`

**Return value** `bool` – `true` if a login is required, otherwise `false`.

**Parameters**

| **Name**     | **Type** | **Required** | **Description**                                                                                |
| ------------ | -------- | ------------ | ---------------------------------------------------------------------------------------------- |
| `actionName` | string   | yes          | Name of the action for which it is checked whether a login is required (e.g. `"EmailUpdate"`). |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.loginRequired("EmailUpdate") }}
  <!-- Login required before the email address can be changed -->
{{ /if }}
```

### \$wsAccount.loadAddress()

Loads a single address by its ID and returns it as an address map. Use the method in the checkout to resolve the billing or shipping address selected by the customer.

**Signature** `$wsAccount.loadAddress(addressId)`

**Return value** `map` – the loaded address with the properties from [Properties of `$wsAccount.addresses`](#eigenschaften-von-wsaccountaddresses).

**Parameters**

| **Name**    | **Type** | **Required** | **Description**                                                                |
| ----------- | -------- | ------------ | ------------------------------------------------------------------------------ |
| `addressId` | string   | yes          | ID of the address to load (e.g. the billing address selected in the checkout). |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $billAddress = $wsAccount.loadAddress($wsCheckout.selectedBillAddress) }}
{{= $billAddress.firstName }} {{= $billAddress.lastName }}
```

> `$wsCheckout.selectedBillAddress` comes from the [\$wsCheckout](/en/frontend/referenz/module/wscheckout) module and returns the ID of the billing address selected during the order process.

***

## Actions

`$wsAccount` itself only reads data. Actions that change data (create, edit, or delete an address, change a password or email) are documented separately: [Actions → Account](/en/frontend/referenz/aktionen/account).

***

## Examples

The following examples are arranged by use case: from the simple state check, through the personal greeting, to address resolution in the checkout. All examples assume a logged-in customer and check this at the start.

### Check the login state and differentiate content

The trigger is the login state. Depending on whether a customer is logged in, you display different content – for example a personal greeting or a login form.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  <!-- Customer is logged in: e.g. greeting and links to the customer account -->
{{ else }}
  <!-- Customer is not logged in: e.g. offer login form -->
{{ /if }}
```

**Result** Logged-in customers see the personal area, non-logged-in visitors see the login offer.

### Personal greeting of a logged-in customer

The trigger is the login state. If a customer is logged in, you address them with their first and last name from their billing address. The `if` check on the address prevents empty greetings if no address has been stored yet.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  {{ var $address = $wsAccount.defaultBillAddress }}
  {{ if $address }}
    Welcome, {{= $address.firstName }} {{= $address.lastName }}!
  {{ /if }}
{{ /if }}
```

**Result** Logged-in customers with a stored billing address are greeted by name.

### Link to the customer account overview

The trigger is the login state. For logged-in customers, you generate a link to the overview page. The URL is built via [`$wsViews.viewUrl()`](/en/frontend/referenz/module/wsviews) so that the path to the template is resolved correctly instead of being hard-wired.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  <a href="{{= $wsViews.viewUrl('account/overview.htm') }}">
    To your customer account overview
  </a>
{{ /if }}
```

**Result** Logged-in customers receive a link that reliably points to the overview page.

### Display billing address

The trigger is the login state. You read out the main billing address and display it with an edit link. The link passes the address `id` so that the action edits the correct address.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  {{ var $address = $wsAccount.defaultBillAddress }}
  {{ if $address }}
    Your billing address
    {{= $address.firstName }} {{= $address.lastName }}
    {{= $address.street }} {{= $address.streetNumber }}
    {{= $address.zip }} {{= $address.city }}
    {{= $address.country }}

    <a href="{{= $wsViews.viewUrl('account/address.htm', {type: 'change', addressId: $address.id}) }}">
      Edit
    </a>
  {{ /if }}
{{ /if }}
```

**Result** The billing address is displayed; the edit link leads to the correct address.

### Address book: iterate over all addresses

The trigger is the login state. You iterate over all stored addresses and display an edit link per address. The loop variable (`$address`) is used consistently so that the link hits exactly the address of the current iteration.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  {{ foreach $address in $wsAccount.addresses }}
    <p>Address ID: {{= $address.id }}</p>
    <a href="{{= $wsViews.viewUrl('account/changeAddress.htm', {addressId: $address.id}) }}">
      Edit
    </a>
  {{ /foreach }}
{{ /if }}
```

**Result** Each stored address is listed with an edit link.

### Load addresses in the checkout

The trigger is the ordering process. During the checkout, [\$wsCheckout](/en/frontend/referenz/module/wscheckout) provides the IDs of the selected addresses. With `loadAddress()`, you resolve these IDs into complete addresses, because in the checkout only the selection IDs are available, not the address data itself.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $billAddress = $wsAccount.loadAddress($wsCheckout.selectedBillAddress) }}
Your billing address:
{{= $billAddress.firstName }} {{= $billAddress.lastName }}

{{ var $shippingAddress = $wsAccount.loadAddress($wsCheckout.selectedShippingAddress) }}
Your shipping address:
{{= $shippingAddress.firstName }} {{= $shippingAddress.lastName }}
```

**Result** The billing and shipping addresses selected in the checkout are displayed with complete data.

### Logout link

The trigger is the login state. For logged-in customers, you generate a logout link via the logout action. After logging out, the customer is directed to the specified target page.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
  <a href="{{= $wsActions.url('Logout', $wsViews.viewUrl('account/overview.htm')) }}">
    Log out
  </a>
{{ /if }}
```

**Result** Logged-in customers can log out and are subsequently directed to the target page.

> `$wsActions.url()` comes from the [\$wsActions](/en/frontend/referenz/module/wsactions) module. The exact spelling of the action names (e.g. for password or email change) is documented under [Actions → Account](/en/frontend/referenz/aktionen/account).

***

## Related links

* [Actions → Account](/en/frontend/referenz/aktionen/account) – Change addresses and the account (create, edit, delete), because `$wsAccount` itself only reads.
* [\$wsCheckout](/en/frontend/referenz/module/wscheckout) – provides the address IDs selected during the order process (`selectedBillAddress`, `selectedShippingAddress`) and the guest email address used in the examples.
* $wsViews](/en/frontend/referenz/module/wsviews) and [$[wsActions](/en/frontend/referenz/module/wsactions) – generate the template and action URLs used in the examples.
* [Configuration: Accounts / customer accounts](/en/konfiguration/accounts-benutzerkonten) – controls auto-login, verification, and address fields referenced by several variables.
* [Practical examples: customer account](/en/frontend/praxisbeispiele/startseite-kundenkonto) – continuous practical example for customer account pages.

Cookies always follow the same flow: set → read → react. Before you can read a cookie, it must first be set.

**Important regarding the time of execution:**\
The [template code](/en/glossar#template-code) is executed during page build, not on click. A cookie is therefore not set at the moment of the click, but only when the click triggers a new request and the template is executed again as part of it. Therefore, always plan setting along a page request.

* [\$wsConsent](/en/frontend/referenz/module/wsconsent) – check the user's consent before setting non-essential cookies.
