---
title: "Registering an Extbase backend module"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:extbase-examples-user-module@main"
source: "ExtensionArchitecture/Extbase/Registration/BackendModule.rst"
rendered: "2026-09-21T11:24:09+00:00"
---

# Registering an Extbase backend module {#extbase-examples-user-module}

Backend modules are registered via
[`Configuration/Backend/Modules.php`](../../FileStructure/Configuration/Backend/Index.md#file-extension-configuration-backend-modules-php). This is the [standard TYPO3
backend module registration mechanism](https://docs.typo3.org/permalink/t3coreapi:backend-modules-api@main) which is not
Extbase-specific. Extbase adds two extra keys to the configuration
([extensionName](https://docs.typo3.org/permalink/t3coreapi:confval-backend-module-extensionname@main)
and [controllerActions](https://docs.typo3.org/permalink/t3coreapi:confval-backend-module-controlleractions@main)) that tell
TYPO3 to bootstrap Extbase and route requests to an
`ActionController`.

**On this page**

-   [Registering the module](https://docs.typo3.org/permalink/t3coreapi:registering-the-module@main)
-   [Access control](https://docs.typo3.org/permalink/t3coreapi:access-control@main)
-   [Module labels](https://docs.typo3.org/permalink/t3coreapi:module-labels@main)
-   [Rendering in the module controller](https://docs.typo3.org/permalink/t3coreapi:rendering-in-the-module-controller@main)
-   [How the module configuration is assembled](https://docs.typo3.org/permalink/t3coreapi:how-the-module-configuration-is-assembled@main)

## Registering the module {#extbase-registration-backend-module-modules-php}

Create or extend [`Configuration/Backend/Modules.php`](../../FileStructure/Configuration/Backend/Index.md#file-extension-configuration-backend-modules-php) in your extension.
Return an array where each key is a unique module identifier and the values are
the module configuration:

**EXT:my_extension/Configuration/Backend/Modules.php**

```php
<?php

declare(strict_types=1);

use MyVendor\MyExtension\Controller\ConferenceController;

return [
  'my_extension_conferences' => [
    'parent' => 'web',
    'position' => ['after' => '*'],
    'access' => 'user',
    'path' => '/module/web/my-extension-conferences',
    'iconIdentifier' => 'my-extension-conference-module',
    'labels' => 'my_extension.modules.conferences',
    'extensionName' => 'MyExtension',
    'controllerActions' => [
      ConferenceController::class => [
        'index', 'show', 'new', 'create', 'edit', 'update', 'delete',
      ],
    ],
  ],
];

```

The Extbase-specific keys are:

-   **[extensionName](https://docs.typo3.org/permalink/t3coreapi:confval-backend-module-extensionname@main)**

    The extension name in UpperCamelCase, for example, if the extension key is
    `my_extension` the extension name will be `MyExtension`.

-   **[controllerActions](https://docs.typo3.org/permalink/t3coreapi:confval-backend-module-controlleractions@main)**

    An array mapping controller class names to a list of allowed action names.
    The first entry and its first action are the default. Actions can be set
    as an array (as shown above) or as a comma-separated string.

These two keys instruct TYPO3 to bootstrap Extbase for this module. Do not use
them for modules whose controllers do not extend
`ActionController`. Use the
standard [routes](https://docs.typo3.org/permalink/t3coreapi:confval-backend-module-routes@main) key instead.

The remaining keys — `parent`, `position`, `access`, `path`,
`iconIdentifier`, `labels` — are standard backend module configuration and
apply to all modules regardless of whether they use Extbase or not. See
[Backend modules API](https://docs.typo3.org/permalink/t3coreapi:backend-modules-api@main) for the full reference.

## Access control {#extbase-registration-backend-module-access}

The `access` key limits who can access the module:

-   `'user'` — available to backend users who have been granted access in
    their user or group settings.
-   `'admin'` — available to administrators only.
-   `'systemMaintainer'` — available to system maintainers only.

User-level access (`'user'`) requires permission to be explicitly granted in
**Backend Users > Edit > Modules**. Admin-only modules skip this check.

## Module labels {#extbase-registration-backend-module-labels}

The `labels` key accepts either a translation label reference or a
translation domain string. Using the
[domain syntax](https://docs.typo3.org/permalink/t3coreapi:label-reference-domain@main) introduced in TYPO3 v14:

```php
'labels' => 'my_extension.modules.conferences',
```

This resolves to
`EXT:my_extension/Resources/Private/Language/Modules/conferences.xlf`.
The middle segment (`modules`) becomes a subdirectory under
`Resources/Private/Language/`; the last segment (`conferences`)
becomes the filename. The file should define the key `title` and optionally
`description` and `shortDescription`.

The legacy `LLL:EXT:` syntax is equally valid and remains fully supported.

## Rendering in the module controller {#extbase-registration-backend-module-template}

Extbase backend module controllers extend
`ActionController`, just like
frontend controllers. The key difference is that instead of `$this->view`,
the controller uses a
`ModuleTemplate` object obtained from
`ModuleTemplateFactory`. The
`ModuleTemplate` provides
`assign()` and `renderResponse()` methods and wraps the rendered
output in the backend page frame. Always pass the template name, relative to
the `Templates/` folder, to `renderResponse()`. Unlike
`$this->view`, it does not derive the name from the controller and action
and throws an exception without one:

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

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Controller;

use MyVendor\MyExtension\Domain\Repository\ConferenceRepository;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

class ConferenceController extends ActionController
{
  public function __construct(
    protected readonly ModuleTemplateFactory $moduleTemplateFactory,
    protected readonly ConferenceRepository $conferenceRepository,
  ) {}

  public function indexAction(): ResponseInterface
  {
    $moduleTemplate = $this->moduleTemplateFactory->create($this->request);
    $moduleTemplate->assign(
      'conferences',
      $this->conferenceRepository->findAll(),
    );
    return $moduleTemplate->renderResponse('Conference/Index');
  }
}

```

Do not use `$this->view` in a backend module controller. The
`$this->view` object operates in a frontend context — it lacks the backend
link generation, flash message queue, and header components that
`ModuleTemplate` provides.

`ModuleTemplateFactory` provides the
backend page frame, toolbar buttons, flash message area, and navigation
components — but only when the Fluid template uses the backend Module Layout.
Without it, `renderResponse()` returns plain rendered HTML with no backend
chrome. Using the Module Layout is strongly recommended for any module that
should look like a native TYPO3 backend page. See [ModuleTemplateFactory](https://docs.typo3.org/permalink/t3coreapi:moduletemplatefactory@main)
for the full API.

## How the module configuration is assembled {#extbase-registration-backend-module-configuration-assembly}

When an Extbase backend module handles a request, the framework assembles a
single configuration array from two layers, each able to override the previous:

1.  `module.tx_myextension` — extension-wide defaults, applied to
    every module of this extension.
1.  `module.tx_myextension_mymodule` — module-specific values,
    override the extension-wide layer.

There is no FlexForm layer — backend modules are not content elements and have
no `pi_flexform` record.

The resulting array has three top-level keys that Extbase uses directly:

-   `settings` — arbitrary key/value pairs available as
    `$this->settings` in the controller.
    `ModuleTemplate` does not
    auto-assign `{settings}` to the template — pass it explicitly with
    `$moduleTemplate->assign('settings', $this->settings)` when needed.
-   `persistence` — controls record loading; the most relevant
    sub-key is `storagePid`, which limits which page(s) the
    repository queries.
-   `view` — overrides template file resolution via
    `templateRootPaths`, `layoutRootPaths`, and
    `partialRootPaths`.

> [!NOTE]
> **See also**
>
> -   [Backend modules API](https://docs.typo3.org/permalink/t3coreapi:backend-modules-api@main) for the full reference for all module configuration
>     keys including `parent`, `position`, `access`, `path`, and
>     submodule definitions.
> -   [ModuleTemplateFactory](https://docs.typo3.org/permalink/t3coreapi:moduletemplatefactory@main) for how to add buttons, menus, and
>     navigation to the chrome module.
