---
title: "The WebPage type"
manual: "schema"
version: "main"
permalink: "https://docs.typo3.org/permalink/brotkrueml/schema:web-page-type@main"
source: "Developer/WebPage.rst"
rendered: "2026-09-18T07:29:46+00:00"
---

# The WebPage type {#the-webpage-type}

Target group: **Developers**

**Table of Contents**

-   [Introduction](https://docs.typo3.org/permalink/brotkrueml/schema:introduction@main)
-   [Using the API](https://docs.typo3.org/permalink/brotkrueml/schema:using-the-api@main)
-   [Using the view helpers](https://docs.typo3.org/permalink/brotkrueml/schema:using-the-view-helpers@main)
-   [Remark](https://docs.typo3.org/permalink/brotkrueml/schema:remark@main)

## Introduction {#introduction}

There are several web page types available to characterise the content of a web
page. A list of the types can be found in the section
[Available Web Page Types](https://docs.typo3.org/permalink/brotkrueml/schema:webpage-types-list@main).

The `WebPage` type and its descendants (like [AboutPage](https://schema.org/AboutPage) or [ImageGallery](https://schema.org/ImageGallery))
can only appear once on a web page – as opposed to the other types.

This extension defines a [new field](https://docs.typo3.org/permalink/brotkrueml/schema:for-editors@main)
**Type of web page** in the page properties. Choose the appropriate type
for the page and the schema markup is added automatically to the page (if the
corresponding
[configuration setting](https://docs.typo3.org/permalink/brotkrueml/schema:configuration-automaticwebpageschemageneration@main) is
activated). If the configuration option is set and the according page has an
expiration date set, the according property `expires` will be set in the
markup.

But you have various options to set the web page type on your own. This can be
the case, if you want to define the [mainEntity](https://docs.typo3.org/permalink/brotkrueml/schema:main-entity-of-web-page@main)
property for a blog article or a product.

But now let's look at code.

## Using the API {#using-the-api}

As you saw in a previous chapter you can use the [API](https://docs.typo3.org/permalink/brotkrueml/schema:api@main) to define the
schema for a page. The `WebPage` type is no exception to that. Define a
`WebPage` type for a page via API:

**EXT:my_extension/Classes/Controller/MyController.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Controller;

use Brotkrueml\Schema\Manager\SchemaManager;
use Brotkrueml\Schema\Type\TypeFactory;

final class MyController
{
    public function __construct(
        private readonly SchemaManager $schemaManager,
        private readonly TypeFactory $typeFactory,
    ) {}

    public function doSomething(): void
    {
        // ...

        $itemPage = $this->typeFactory->create('ItemPage');
        $this->schemaManager->addType($itemPage);

        // ...
    }
}

```

That is it. But you can add one or more properties to it - let's define a page
with a product as primary content:

**EXT:my_extension/Classes/Controller/MyController.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Controller;

use Brotkrueml\Schema\Manager\SchemaManager;
use Brotkrueml\Schema\Type\TypeFactory;

final class MyController
{
    public function __construct(
        private readonly SchemaManager $schemaManager,
        private readonly TypeFactory $typeFactory,
    ) {}

    public function doSomething(): void
    {
        // ...

        $aggregateRating = $this->typeFactory->create('AggregateRating')
            ->setProperty('ratingValue', '4')
            ->setProperty('reviewCount', '126')
        ;

        $product = $this->typeFactory->create('Product')
            ->setProperties([
                'name' => 'Some fancy product',
                'color' => 'blue',
                'material' => 'wood',
                'image' => 'https://example.org/some-fancy-product.jpg',
                'aggregateRating' => $aggregateRating,
            ])
        ;

        $itemPage = $this->typeFactory->create('ItemPage')
            ->setProperty('mainEntity', $product)
        ;

        $this->schemaManager->addType($itemPage);

        // ...
    }
}

```

The example is rendered as JSON-LD:

```json
{
   "@context": "https://schema.org/",
   "@type": "ItemPage",
   "mainEntity": {
      "@type": "Product",
      "aggregateRating": {
         "@type": "AggregateRating",
         "ratingValue": "4",
         "reviewCount": "126"
      },
      "color": "blue",
      "image": "https://example.org/some-fancy-product.jpg",
      "material": "wood",
      "name": "Some fancy product"
   }
}
```

If you define a web page on your own, this overrules the [page field value](https://docs.typo3.org/permalink/brotkrueml/schema:for-editors@main) of the specific type of web page.

> [!TIP]
> You don't have to define a web page type, if you only want to set the main
> entity of the page. You can also set the main entity independently of the web
> page. Have a look at the chapter [Main entity](https://docs.typo3.org/permalink/brotkrueml/schema:main-entity-of-web-page@main).

## Using the view helpers {#using-the-view-helpers}

But imagine you don't have the possibility to add PHP code to an extension (for example,
it is a third-party extension). So the view helpers come into the game. Let's
implement the same example as above with view helpers:

```html
<schema:type.itemPage>
   <schema:type.product
      -as="mainEntity"
      name="Some fancy product"
      color="blue"
      material="wood"
      image="https://example.org/some-fancy-product.jpg"
   >
      <schema:type.aggregateRating
         -as="aggregateRating"
         ratingValue="4"
         reviewCount="126"
      />
   </schema:type.product>
</schema:type.itemPage>
```

## Remark {#remark}

As mentioned above, only one web page type can exist on a page. But what happens
if you set more than one web page type? Well, the last call wins the race. So
you can define it in your Extbase action and set it in a Fluid template – the
template wins.
