---
title: "Migration"
manual: "schema"
version: "main"
permalink: "https://docs.typo3.org/permalink/brotkrueml/schema:migration@main"
source: "Migration/Index.rst"
rendered: "2026-09-18T07:29:46+00:00"
---

# Migration {#migration-1}

**Table of Contents**

-   [From version 3.x to version 4.0](https://docs.typo3.org/permalink/brotkrueml/schema:from-version-3-x-to-version-4-0@main)
-   [From version 2.x to version 3.0](https://docs.typo3.org/permalink/brotkrueml/schema:from-version-2-x-to-version-3-0@main)
-   [From version 1.x to version 2.0](https://docs.typo3.org/permalink/brotkrueml/schema:from-version-1-x-to-version-2-0@main)

## From version 3.x to version 4.0 {#from-version-3-x-to-version-4-0}

In version 4.0, the compatibility with TYPO3 v11 LTS and TYPO3 v12 LTS has been
removed.

### PSR-14 event `RegisterAdditionalTypePropertiesEvent` {#psr-14-event-registeradditionaltypepropertiesevent}

The [deprecated](https://docs.typo3.org/permalink/brotkrueml/schema:confval-deprecation-registeradditionaltypepropertiesevent@main)
PSR-14 event `RegisterAdditionalTypePropertiesEvent` has been removed. As an
alternative create a class implementing `AdditionalPropertiesInterface`
(which is available since version 3.10.0), see
[Register additional properties](https://docs.typo3.org/permalink/brotkrueml/schema:extending-register-additional-properties@main) for details.

### Manual instantiation of a type model class {#manual-instantiation-of-a-type-model-class}

Instantiating a type model class manually with "new" is not supported anymore.
The `\Brotkrueml\Schema\Type\TypeFactory->create()` method should be used
instead (which is available since version 3.0.0):

```diff
  use Brotkrueml\Schema\Model\Type\Event;
+ use Brotkrueml\Schema\Type\TypeFactory;

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

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

-         $event = new Event();
+         $event = $this->typeFactory->create('Event');

          // ...
      }
  }
```

> [!NOTE]
> **See also**
>
> -   [Create a model via the TypeFactory](https://docs.typo3.org/permalink/brotkrueml/schema:types@main)
> -   [Deprecation: direct instantiation of a type model](https://docs.typo3.org/permalink/brotkrueml/schema:confval-deprecation-directinstantiationoftypemodel@main)
> -   [Deprecation: TypeFactory::createType() method](https://docs.typo3.org/permalink/brotkrueml/schema:confval-deprecation-typefactorycreatetype@main)

### Types and view helpers representing enumerations {#types-and-view-helpers-representing-enumerations}

Types and view helpers representing enumerations were removed. It is unlikely
that they were used as they had no real purpose. Use real
[enumerations](https://docs.typo3.org/permalink/brotkrueml/schema:enumerations@main) instead which are available since version
3.9.0.

### Properties moved from core to pending {#properties-moved-from-core-to-pending}

Over the time some properties moved from the core vocabulary to pending with
newer version of the Schema.org definition (for whatever reason). To avoid
breaking, these properties were reapplied to the corresponding type models.
Those properties have now been removed. If you need some of them, register them
yourself like explained in [Register additional properties](https://docs.typo3.org/permalink/brotkrueml/schema:extending-register-additional-properties@main) or
install the [schema_pending](https://extensions.typo3.org/extension/schema_pending) extension.

### Type declarations added to `TypeInterface` {#type-declarations-added-to-php-typeinterface}

Missing return type declarations and type declarations for the argument of the
`setId()` method have been added. If you do not implement custom type models
directly from the `\Brotkrueml\Schema\Core\Model\TypeInterface`, you are
not affected by this change. Otherwise you have to adjust the methods of your
type model classes.

However, implementing a type model directly from the interface is
discouraged and might not work in the future, extend from
`\Brotkrueml\Schema\Core\Model\AbstractType` instead.

> [!NOTE]
> **See also**
>
> -   [Adding types](https://docs.typo3.org/permalink/brotkrueml/schema:extending-adding-types@main)

## From version 2.x to version 3.0 {#from-version-2-x-to-version-3-0}

In version 3.0, the compatibility with TYPO3 v10 LTS was removed. Also PHP 8.1
or higher is necessary.

### Type model classes {#type-model-classes}

The type models classes were previously registered via a
`Configuration/TxSchema/TypeModels.php` file. This file is not recognised
anymore, you have to mark a type model class with the attribute
`\Brotkrueml\Schema\Attributes\Type` now. See the
[Adding types](https://docs.typo3.org/permalink/brotkrueml/schema:extending-adding-types@main) section for more information.

Additionally, the static property `$propertyNames` of a type model class is
now type-hinted as an array.

```diff
+ use Brotkrueml\Schema\Attributes\Type;

+ #[Type('MyCustomType')]
  final class MyCustomType extends AbstractType
  {
-     protected static $propertyNames = [
+     protected static array $propertyNames = [
         // ... the properties ...
      ]
  }
```

### View helpers {#view-helpers}

Custom view helpers need to specify a property which holds the name of the
type:

```diff
  final class MyCustomTypeViewHelper extends AbstractTypeViewHelper
  {
+     protected string $type = 'MyCustomType';
  }
```

### Type factory {#type-factory}

The call of the static method `\Brotkrueml\Schema\Type\TypeFactory::createType()`
has been deprecated. Instead, inject the `TypeFactory` into the constructor
and use the new `create()` method:

```diff
 <?php

 declare(strict_types=1);

 namespace MyVendor\MyExtension\Controller;

 use Brotkrueml\Schema\Type\TypeFactory;

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

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

-        $person = TypeFactory::createType('Person');
+        $person = $this->typeFactory->create('Person');

         // ...
     }
 }
```

## From version 1.x to version 2.0 {#from-version-1-x-to-version-2-0}

In version 2.0, the compatibility with TYPO3 v9 LTS was removed. Also PHP 7.4
or higher is necessary.

### Signal/Slots {#signal-slots}

The signal/slots were removed:

-   registerAdditionalTypeProperties
-   shouldEmbedMarkup

You can migrate the slots easily to the PSR-14 event listeners:

**Previous slot** (in `ext_localconf.php`):

**EXT:my_extension/ext_localconf.php**

```php
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
   TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class
);
$signalSlotDispatcher->connect(
   \Brotkrueml\Schema\Core\Model\AbstractType::class,
   'registerAdditionalTypeProperties',
   \MyVendor\MyExtension\EventListener\AdditionalPropertiesForPerson::class,
   '__invoke'
);
```

**PSR-14 event listener** (in `Configuration/Services.yaml`):

```yaml
services:
   # Place here the default dependency injection configuration

   MyVendor\MyExtension\EventListener\AdditionalPropertiesForPerson:
      tags:
         - name: event.listener
           identifier: 'myAdditionalPropertiesForPerson'
```

You can find more information about the PSR-14 event listeners in the chapter
[PSR-14 events](https://docs.typo3.org/permalink/brotkrueml/schema:events@main).

### Removed Deprecations {#removed-deprecations}

The following [deprecated methods and classes](https://docs.typo3.org/permalink/brotkrueml/schema:api-deprecations@main) were
removed:

-   `\Brotkrueml\Schema\Core\Model\AbstractType->isEmpty()`
-   `\Brotkrueml\Schema\Manager\SchemaManager->setMainEntityOfWebPage()`
-   `\Brotkrueml\Schema\Provider\TypesProvider`

For the migration follow the instructions on the
[deprecations](https://docs.typo3.org/permalink/brotkrueml/schema:api-deprecations@main) chapter.

### Markup is embedded by default on "noindex" pages {#markup-is-embedded-by-default-on-noindex-pages}

In schema version 1.x the markup was not embedded on "noindex" pages (with
installed [SEO system extension](https://docs.typo3.org/c/typo3/cms-seo/14.3/en-us/Introduction/Index.html#introduction)). In version 2
the markup is embedded by default also on these pages. You can deactivate this
behaviour in the [extension configuration](https://docs.typo3.org/permalink/brotkrueml/schema:configuration-embedmarkuponnoindexpages@main).

Also in version 1.x a PSR-14 event
`\Brotkrueml\Schema\Event\ShouldEmbedMarkupEvent` was available to change
the default behaviour of not embedding the markup on "noindex" pages. With the
new configuration option this is not necessary anymore and event listeners for
this event must be removed.
