---
title: "Registering an Extbase frontend plugin"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:extbase-registration-of-frontend-plugins@main"
source: "ExtensionArchitecture/Extbase/Registration/FrontendPlugin.rst"
rendered: "2026-09-21T07:19:53+00:00"
---

# Registering an Extbase frontend plugin {#extbase-registration-of-frontend-plugins}

A frontend plugin is an Extbase extension rendered as a content element on a
TYPO3 page. Registration requires two calls in two different files: one in
[`ext_localconf.php`](../../FileStructure/ExtLocalconf.md#file-extension-ext-localconf-php) to configure the Extbase dispatcher, and one in
[`Configuration/TCA/Overrides/tt_content.php`](../../FileStructure/Configuration/TCA/Index.md#file-extension-configuration-tca-overridessomefile-php) to make the plugin
selectable in the backend.

**On this page**

-   [Configuring the plugin dispatcher](https://docs.typo3.org/permalink/t3coreapi:configuring-the-plugin-dispatcher@main)
-   [Registering the plugin in the backend](https://docs.typo3.org/permalink/t3coreapi:registering-the-plugin-in-the-backend@main)
-   [How the plugin configuration is assembled](https://docs.typo3.org/permalink/t3coreapi:how-the-plugin-configuration-is-assembled@main)
-   [TypoScript plugin object path](https://docs.typo3.org/permalink/t3coreapi:typoscript-plugin-object-path@main)

## Configuring the plugin dispatcher {#extbase-registration-frontend-plugin-configure}

`ExtensionUtility::configurePlugin()` registers which controller
actions are allowed and generates the TypoScript to route requests to the Extbase
dispatcher. Call it in [`ext_localconf.php`](../../FileStructure/ExtLocalconf.md#file-extension-ext-localconf-php):

**EXT:my_extension/ext_localconf.php**

```php
<?php

use MyVendor\MyExtension\Controller\ConferenceController;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;

defined('TYPO3') or die();

ExtensionUtility::configurePlugin(
  'MyExtension',
  'ConferenceList',
  [ConferenceController::class => 'list, show, create'],
  [ConferenceController::class => 'create'],
);

```

The four arguments are:

1.  **Extension name** — the extension key in UpperCamelCase
    (`my_extension` → `MyExtension`).
1.  **Plugin name** — a unique UpperCamelCase identifier for this plugin inside
    the extension. Combined with the extension name, it forms the plugin
    signature used in TypoScript and routing (`myextension_conferencelist`).
    The combined length must not exceed 32 characters. snake_case is also
    accepted and normalised internally, but UpperCamelCase is the convention.
1.  **Allowed controller actions** — an array mapping controller class names to
    a comma-separated list of action names. The first entry and its first action
    are the default. Only actions listed here are available via this plugin.
1.  **Non-cacheable actions** — a subset of the above defining output that must not be
    stored in the page cache. See [Non-cacheable Extbase plugin actions and developer responsibility](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-noncacheable@main)
    for the implications.

<!-- TODO: no Markdown rendering for "versionchanged" -->

The fifth parameter $pluginType was removed. All plugins are registered
as CType content elements. Omit this argument entirely.

## Registering the plugin in the backend {#extbase-frontend-plugin-content-element}

`ExtensionUtility::registerPlugin()` adds the plugin to the list of
available content element types in the backend. Call it in
[`Configuration/TCA/Overrides/tt_content.php`](../../FileStructure/Configuration/TCA/Index.md#file-extension-configuration-tca-overridessomefile-php):

**EXT:my_extension/Configuration/TCA/Overrides/tt_content.php**

```php
<?php

use TYPO3\CMS\Extbase\Utility\ExtensionUtility;

defined('TYPO3') or die();

ExtensionUtility::registerPlugin(
  'MyExtension',
  'ConferenceList',
  'my_extension.db:plugin.conferencelist.title',
  'my-extension-conference-list',
  'plugins',
  'my_extension.db:plugin.conferencelist.description',
  'EXT:my_extension/Configuration/FlexForms/ConferenceList.xml',
);

```

The arguments are:

1.  **Extension name** — same as in `configurePlugin()`.
1.  **Plugin name** — same as in `configurePlugin()`. The two values must
    match exactly.
1.  **Plugin title** — label shown in the backend content element wizard.
    Use a translatable label reference. The example uses the
    [translation domain syntax](https://docs.typo3.org/permalink/t3coreapi:label-reference-domain@main)
    (`extension_key.file:label_key`), which is shorter than the
    legacy `LLL:EXT:` path syntax. Both are equivalent and interchangeable.
1.  **Plugin icon** — an icon identifier registered via the Icon
    API, or a path prefixed with
    `EXT:`. Optional. Defaults to the generic plugin icon.
1.  **Group** — groups the plugin in the content element wizard. Common values
    are `'plugins'` (generic plugin group) or a custom group name matching
    your extension.
1.  **Description** — optional longer text shown in the content element wizard.
1.  **FlexForm** — path to a FlexForm XML file that adds configurable fields to
    the content element in the backend, for example
    `'EXT:my_extension/Configuration/FlexForms/ConferenceList.xml'`.
    Optional. Omit if the plugin needs no backend configuration form.

Both calls must use the same extension name and plugin name. A mismatch means
the dispatcher will not find the controller actions registered for that plugin.

## How the plugin configuration is assembled {#extbase-registration-frontend-plugin-configuration-assembly}

When an Extbase frontend plugin handles a request, the framework assembles a
single configuration array from three layers, each able to override the
previous:

1.  `plugin.tx_myextension` — extension-wide defaults, applied to
    every plugin of this extension.
1.  `plugin.tx_myextension_myplugin` — plugin-specific values,
    override the extension-wide layer.
1.  FlexForm data — values the editor entered in the content element's plugin
    tab. These have the highest priority and override both TypoScript layers.
    Only `settings`, `persistence`, and
    `view` keys are merged from the FlexForm.

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

-   `settings` — arbitrary key/value pairs available as
    `$this->settings` in the controller and as `{settings}` in
    Fluid templates (auto-assigned by the framework for frontend plugins).
-   `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`.

## TypoScript plugin object path {#extbase-frontend-plugin-typoscript}

`configurePlugin()` generates a TypoScript object for the plugin at:

```typoscript
plugin.tx_<extensionkey>_<pluginname>
```

Both parts are lowercase; underscores are removed from the extension key. For
the example above that is `plugin.tx_myextension_conferencelist`.
A full example covering all three configuration keys:

**EXT:my_extension/Configuration/Sets/MyExtension/setup.typoscript**

```typoscript
plugin.tx_myextension_conferencelist {
  view {
    templateRootPaths.10 = EXT:my_extension/Resources/Private/Templates/
  }
  persistence {
    storagePid = {$plugin.tx_myextension_conferencelist.persistence.storagePid}
  }
  settings {
    itemsPerPage = 10
  }
}

```

To find the exact TypoScript path of a plugin, open the TYPO3 backend,
navigate to a site or page containing the plugin, and inspect the
computed TypoScript tree in **Site Management > TypoScript**.

> [!NOTE]
> **See also**
>
> -   [Non-cacheable actions](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-noncacheable@main)
>     for the consequences of marking actions non-cacheable and developer
>     responsibilities.
> -   [View layer in Extbase](https://docs.typo3.org/permalink/t3coreapi:extbase-view-overview@main)
>     for template path configuration via TypoScript.
> -   [storagePid — when findAll() returns nothing](https://docs.typo3.org/permalink/t3coreapi:extbase-domain-repository-storagepid@main)
>     for how the persistence storagePid setting limits which records are
>     returned.
