---
title: "State Manager"
manual: "Environment State Manager"
version: "main"
permalink: "https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-state-manager@main"
source: "Developer/StateManager/Index.rst"
rendered: "2026-10-17T14:50:33+00:00"
---

# State Manager {#developer-state-manager}

The `StateManagerInterface` is the central, public service of this
extension. It bootstraps an environment for a given context, applies it to the
global TYPO3 state and is able to back up and restore that state.

> [!NOTE]
> Both frontend and backend environments are bootstrapped, selected through
> the `ApplicationType` of the `StateBuildContext`. The examples
> below use `ApplicationType::FRONTEND`; see the
> [environment builder](https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-environment-builder@main) for a backend
> example.

The state manager is available as a public service through
`StateManagerInterface`, resolved to a TYPO3 core version compatible
implementation. Inject it through dependency injection:

```php
use FGTCLB\EnvironmentStateManager\StateManagerInterface;

final class MyService
{
    public function __construct(
        private readonly StateManagerInterface $stateManager,
    ) {}
}
```

> [!NOTE]
> Always type-hint `StateManagerInterface`, never a concrete
> `Core13StateManager` or `Core14StateManager`. The dependency
> injection container resolves the implementation for the running TYPO3 core
> version. See [Public API and stability](https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-public-api@main) for the full public API surface.

## Execute code within an environment {#execute-code-within-an-environment}

The recommended way to run code inside a built environment is the
`execute()` method. It backs up the current environment, bootstraps the
environment described by the `StateBuildContext`, runs the given closure
and restores the previous environment afterwards – even if the closure throws:

```php
use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::FRONTEND,
    pageId: 42,
    languageId: 0,
);

$this->stateManager->execute($stateBuildContext, function () {
    // Code in here runs within the frontend environment built for page 42.
    // The previous environment is restored automatically afterwards.
});
```

## Manual backup, bootstrap and restore {#manual-backup-bootstrap-and-restore}

If you need finer control, the individual steps are available as well. Always
make sure to restore a previously created backup, for example by using a
`try`/`finally` block:

```php
use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::FRONTEND,
    pageId: 42,
    languageId: 0,
);

$this->stateManager->backup();
try {
    $state = $this->stateManager->bootstrap($stateBuildContext);
    // work with the bootstrapped $state ...
} finally {
    $this->stateManager->restore();
}
```

## Applying a pre-built state {#applying-a-pre-built-state}

A `StateInterface` instance – for example one created through the
[environment builder](https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-environment-builder@main) – can be applied to
the global environment directly:

```php
$this->stateManager->apply($state);
```

## PSR-14 events {#psr-14-events}

The state manager dispatches the following events that can be used to react on
state changes:

| Event | Dispatched |
| --- | --- |
| `FGTCLBEnvironmentStateManagerEventStateApplyEvent` | When a state is applied to the global environment. |
| `FGTCLBEnvironmentStateManagerEventStateBackupEvent` | When the current environment is backed up onto the snapshot stack. |

Register an event listener as usual through the `Services.yaml` /
`Services.php` or the `#[AsEventListener]` attribute:

```php
use FGTCLB\EnvironmentStateManager\Event\StateApplyEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;

final class MyStateApplyListener
{
    #[AsEventListener]
    public function __invoke(StateApplyEvent $event): void
    {
        // react on the applied state
    }
}
```
