> ## 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.

# $wsCmsPage - Output a CMS page

> The $wsCmsPage module: read the page document of a CMS page from Strapi in the template.

With the `$wsCmsPage` module, you access the page document of the currently requested CMS page in the template. The module delivers the JSON document from the object storage unchanged, without renaming or reordering. A typical use case is the CMS page template, which outputs the content of a content page maintained in Strapi.

<Note>
  The module is only populated on CMS pages, i.e. on pages rendered via the `CmsPage` view controller. On all other pages, `$wsCmsPage` is empty (`null`).
</Note>

Further pages on this topic:

* [Delivery of CMS pages to the shop](/en/strapi-cms/grundlagen-architektur-von-strapi#auslieferung-von-cms-seiten-in-den-shop) explains how the pages get into the object storage, how the SEO URL is created, and which fields the shop itself evaluates.
* [Template theme](/en/frontend/die-basics/template-theme#cms-seitentemplate) explains the CMS page template and its integration into the base template.

***

## Module overview

**Example / excerpt of** `$wsCmsPage`

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

**JSON output**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "contentType": "api::contentpage.contentpage",
  "meta": {
    "id": 92,
    "documentId": "jyllb6ubw0dj62vndr0lh7z1",
    "locale": "de",
    "createdAt": "2026-06-26T08:00:00.000Z",
    "updatedAt": "2026-07-16T09:00:00.000Z",
    "publishedAt": "2026-07-16T09:03:00.000Z",
    "url": "Zahlungsarten",
    "metaTitle": "Zahlungsarten",
    "metaDescription": "Beschreibung zu Zahlungsarten",
    "robots": ["noindex", "nofollow"],
    "hreflang": [
      {
        "language": "fr-fr",
        "url": "myshop.fr/paiement",
        "subshopId": "francais",
        "default": false
      }
    ]
  },
  "fields": [
    { "name": "Markup", "type": "richtext", "value": "AGB Content" },
    {
      "name": "content",
      "type": "dynamiczone",
      "value": [
        {
          "component": "elemente.ws-markup",
          "id": 96,
          "fields": [
            { "name": "FullWidth", "type": "boolean", "value": false }
          ]
        }
      ]
    }
  ]
}
```

**Variables overview**

| **Name**                            | **Return type**   | **Description**                                                                                           |
| ----------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------- |
| `contentType`                       | string            | Strapi identifier of the content type the page originates from. Not evaluated by the shop.                |
| `meta`                              | map               | Administrative data of the page plus the SEO block.                                                       |
| `meta.url`                          | string            | URL of the page, without a leading slash.                                                                 |
| `meta.metaTitle`                    | string            | Meta title. Additionally set by the shop as the page title and available via `$wsViews.metaTitle()`.      |
| `meta.metaDescription`              | string            | Meta description. Additionally set by the shop and available via `$wsViews.metaDescription()`.            |
| `meta.robots`                       | array             | Robots directives of the page. Additionally merged by the shop into `$wsViews.current.robotOptions`.      |
| `meta.publishedAt`                  | string or null    | Timestamp of publication. `null` for drafts.                                                              |
| `meta.hreflang`                     | array             | Alternate language objects (`language`, `url`, `subshopId`, `default`). Are **not** output automatically. |
| `meta.id`                           | number            | Internal numeric Strapi ID (per language version).                                                        |
| `meta.documentId`                   | string            | Stable, language-independent document ID.                                                                 |
| `meta.locale`                       | string            | Language of the document, for example `de`.                                                               |
| `meta.createdAt` / `meta.updatedAt` | string (ISO-8601) | Timestamps from Strapi.                                                                                   |
| `fields`                            | array             | The content fields of the page, each `{ name, type, value }`. Unchanged from Strapi.                      |

## Methods

No methods are available for `$wsCmsPage`.

***

## Variables

### \$wsCmsPage.contentType

Returns the Strapi content type the requested page originates from. The content type corresponds to the input mask behind the page and defines which fields an editor can fill in.

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

### \$wsCmsPage.meta

Contains the administrative data and the SEO block of the page.

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

<Note>
  The shop already sets the meta title and meta description itself. In the base template, they are usually output via the functions [\$wsViews.metaTitle()](https://dokumentation.websale.de/frontend/referenz/module/wsviews#\$wsviews-metatitle) and [\$wsViews.metaDescription()](https://dokumentation.websale.de/frontend/referenz/module/wsviews#\$wsviews-metadescription), so that all page types are handled consistently. Direct access via `$wsCmsPage.meta` is only needed if you require the raw values elsewhere.
</Note>

Which of these fields the shop evaluates and which fields are purely administrative data is described under [The SEO block in meta](/en/strapi-cms/grundlagen-architektur-von-strapi#der-seo-block-in-meta).

### \$wsCmsPage.fields

Contains the content fields of the page. Each entry has the keys `name`, `type`, and `value`.

The shop passes this list on unchanged and does not interpret it. Which field names and components exist depends on the Strapi modeling of the respective shop. For access, the list is converted once into a name/value object:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCmsPage }}
    {{ var $cFields = {} }}
    {{ foreach $cField in $wsCmsPage.fields }}
        {{ $cFields[$cField.name] = $cField.value }}
    {{ /foreach }}

    <h1>{{= $wsCmsPage.meta.metaTitle }}</h1>
    <div>{{! $cFields.Markup }}</div>
{{ /if }}
```

The pattern applies at every level, including within components (`value.fields`) and for the blocks of content blocks. The field types and the form of the respective `value` are described under [The field types](/en/strapi-cms/migration-der-strapi-datenstruktur-v5#the-field-types), migrating existing field accesses under [Step 4](/en/strapi-cms/migration-der-strapi-datenstruktur-v5#step-4-update-field-accesses) and [Step 5](/en/strapi-cms/migration-der-strapi-datenstruktur-v5#step-5-adjust-content-blocks-dynamic-zone).

<Warning>
  The order of the `fields` list follows the schema definition and is meaningless for rendering. Therefore, always access fields via `name` and never via position. The order **within** an array value (content blocks, repeatable components), by contrast, corresponds exactly to the editor's arrangement and must be preserved when rendering.
</Warning>

***

## Actions

No actions are available for `$wsCmsPage`.

***

## Examples

### Check a shared base template for CMS content

Since `$wsCmsPage` is `null` on all other pages, a shared base template can safely check for it:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCmsPage }}
    {{# only on CMS pages #}}
{{ /if }}
```

### Output alternate languages

`meta.hreflang` is not automatically included in the shop's hreflang directives, [\$wsViews.current.getHreflangAutomatic()](https://dokumentation.websale.de/frontend/referenz/module/wsviews#\$wsviews-current-gethreflangautomatic) returns nothing for CMS pages. For output in the HTML head:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cAlt in $wsCmsPage.meta.hreflang }}
    <link rel="alternate" hreflang="{{= $cAlt.language }}" href="{{= $cAlt.url }}">
{{ /foreach }}
```

### Make unknown components visible in test mode

Without an `{{ else }}` branch, a newly created component that is not implemented in the template silently disappears from the page:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cItem in $cFields.content }}
    {{ if $cItem.component == "elemente.ws-markup" }}
        {{# … output … #}}
    {{ else }}
        {{ if $wsTestMode.active }}
            <!-- Component "{{= $cItem.component }}" is not implemented in the template -->
        {{ /if }}
    {{ /if }}
{{ /foreach }}
```

### Mark a draft in test mode

A draft (`meta.publishedAt` is `null`) is only delivered when [test mode](/en/frontend/referenz/aktionen/testmode) is active. This can be made visible in the template:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCmsPage && !$wsCmsPage.meta.publishedAt }}
    <p class="notice">This page is a draft and not publicly accessible.</p>
{{ /if }}
```

***

## Related links

* [Delivery of CMS pages to the shop](/en/strapi-cms/grundlagen-architektur-von-strapi#auslieferung-von-cms-seiten-in-den-shop)
* [Template theme - CMS page template](/en/frontend/die-basics/template-theme#cms-seitentemplate)
* [content.cmsTemplates](/en/konfiguration/content-katalog-kategorien-produkte#content-cmstemplates-cms-seiten)
* [Migration of the Strapi data structure (version 5)](/en/strapi-cms/migration-der-strapi-datenstruktur-v5)
* [\$wsViews](/en/frontend/referenz/module/wsviews)
* [\$wsTestMode](/en/frontend/referenz/module/wstestmode)


## Related topics

- [Template theme](/en/frontend/die-basics/template-theme.md)
- [Basics & architecture of Strapi](/en/strapi-cms/grundlagen-architektur-von-strapi.md)
- [Overview - Strapi CMS](/en/strapi-cms.md)
- [seoMetaData - Meta data & SEO texts](/en/konfiguration/seometadata-meta-daten-seo-texte.md)
- [Migration of the Strapi data structure (version 5)](/en/strapi-cms/migration-der-strapi-datenstruktur-v5.md)
