---
title: "URI builder (Extbase)"
manual: "TYPO3 Explained"
version: "12.4"
permalink: "https://docs.typo3.org/permalink/t3coreapi:extbase-uri-builder@12.4"
source: "ExtensionArchitecture/Extbase/Reference/UriBuilder.rst"
rendered: "2026-10-21T15:29:37+00:00"
---

> [!WARNING]
> **Attention**
>
> TYPO3 v12 has reached end-of-life as of April 30th 2026 and
> is no longer being maintained. Use the version switcher on the top
> left of this page to select documentation for a supported version of TYPO3.
>
> Need more time before upgrading?
> You can purchase Extended Long Term Support (ELTS) for TYPO3 v12 here:
> [TYPO3 ELTS](https://typo3.com/services/extended-support-elts).

# URI builder (Extbase) {#extbase-uri-builder}

The URI builder offers a convenient way to create links in an Extbase context.

## Usage in an Extbase controller {#usage-in-an-extbase-controller}

The URI builder is available as a property in a controller class which extends
the [ActionController](https://docs.typo3.org/permalink/t3coreapi:extbase-action-controller@12.4) class. The request context is automatically
available to the UriBuilder.

Example:

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

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Controller\MyController;

use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

final class MyController extends ActionController
{
    public function myAction(): ResponseInterface
    {
        $url = $this->uriBuilder
            ->reset()
            ->setTargetPageUid(42)
            ->uriFor(
                'another', // only action name, not `myAction`
                [
                    'myRecord' => 21,
                ],
                'My', // only controller name, not `MyController`
                'myextension',
                'myplugin',
            );

        // do something with $url
    }
}

```

Have a look into the [API](https://docs.typo3.org/permalink/t3coreapi:uri-builder-api@12.4) for the available methods of
the URI builder.

> [!WARNING]
> **Attention**
>
> As the URI builder holds state, you have to call `reset()` before
> creating a URL.

## Usage in another context {#usage-in-another-context}

The class `\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder` can be injected
via constructor in a class:

**EXT:my_extension/Classes/MyClass.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\MyClass;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;

final class MyClass
{
    public function __construct(
        private readonly UriBuilder $uriBuilder,
    ) {}

    public function doSomething()
    {
        $this->uriBuilder->setRequest($this->getExtbaseRequest());

        $url = $this->uriBuilder
            ->reset()
            ->setTargetPageUid(42)
            ->uriFor(
                'my', // only action name, not `myAction`
                [
                    'myRecord' => 21,
                ],
                'My', // only controller name, not `MyController`
                'myextension',
                'myplugin',
            );

        // do something with $url
    }

    private function getExtbaseRequest(): RequestInterface
    {
        /** @var ServerRequestInterface $request */
        $request = $GLOBALS['TYPO3_REQUEST'];

        // We have to provide an Extbase request object
        return new Request(
            $request->withAttribute('extbase', new ExtbaseRequestParameters()),
        );
    }
}

```

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

The Extbase request object should be set via the setRequest() method
before using the URI builder. If not done, a deprecation notice will be
raised. In TYPO3 v13 setting the request object before first usage will be
mandatory.

> [!NOTE]
> In the above example, the [PSR-7 request object](https://docs.typo3.org/permalink/t3coreapi:typo3-request@12.4) is
> retrieved from the global variable `TYPO3_REQUEST`. This is not
> recommended and is only a fallback. See the section
> [Getting the PSR-7 request object](https://docs.typo3.org/permalink/t3coreapi:getting-typo3-request-object@12.4) to learn how to retrieve the request
> PSR-7 object depending on the context.

> [!WARNING]
> **Attention**
>
> When using the URI builder to build frontend URLs, the current content
> object is required. It is initialized from the handed in local request
> object. In case extensions set the request object without the request attribute
> [currentContentObject](https://docs.typo3.org/permalink/t3coreapi:typo3-request-attribute-current-content-object@12.4),
> an automatic fallback is applied in TYPO3 v12, triggering a PHP deprecation
> warning. The fallback has been removed in TYPO3 v13.

### Example in Extbase ViewHelper {#extbase-uri-builder-viewhelper}

**EXT:my_extension/Classes/ViewHelper/MyLinkViewHelper.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Controller\MyController;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;

final class MyLinkViewHelper extends AbstractViewHelper
{
    public function __construct(private UriBuilder $uriBuilder) {}

    public function render(): string
    {
        if (method_exists($this->renderingContext, 'getRequest')) {
            // TYPO3 v12 compatibility
            $request = $this->renderingContext->getRequest();
        } elseif ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) {
            // TYPO3 v13+ compatibility
            $request = $this->renderingContext->getAttribute(ServerRequestInterface::class);
        } else {
            throw new \RuntimeException(
                'The rendering context of this ViewHelper is missing a valid request object, probably because it is used outside of Extbase context.',
                1730537505,
            );
        }

        // Request context is needed before $this->uriBuilder is first used for returning links.
        // Note: this will not be reset on calling $this->uriBuilder->reset()!
        $this->uriBuilder->setRequest($request);

        $url = $this->uriBuilder
            ->reset()
            ->setTargetPageUid(2751)
            ->uriFor(
                'another', // only action name, not `myAction`
                [
                    'myRecord' => 21,
                ],
                'My', // only controller name, not `MyController`
                'myextension',
                'myplugin',
            );

        // do something with $url, for example:
        return 'Link: ' . $url . '</a>';
    }
}

```

> [!NOTE]
> This example was taken from `\TYPO3\CMS\Fluid\ViewHelpers\Uri\ActionViewHelper`
> of the TYPO3 Core. These ViewHelpers are always a useful example to see the best practice on how
> to retrieve request context.

> [!WARNING]
> **Attention**
>
> This example uses the `\TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper` to be extended from,
> which does not have its own constructor, making constructor-based dependency injection straight forward.
> However, if you use `\TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper` as a base, which already
> provides a constructor, be sure to call `parent::_construct()` in your custom constructor.
> Alternatively (though less recommendable), you can use `GeneralUtility::makeInstance()` to retrieve
> the UriBuilder instance, or use method-based injection (`injectUriBuilder(UriBuilder $uriBuilder)`).
> Note, always flush the TYPO3 cache after adding/modifying ViewHelpers with new injected dependencies.
> See [Dependency injection](https://docs.typo3.org/permalink/t3coreapi:dependency-injection@12.4) for more details.

## API {#uri-builder-api}

-   **class UriBuilder**

    -   *Fully qualified name:* `\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder`

    An URI Builder

    -   **setRequest(\\TYPO3\\CMS\\Extbase\\Mvc\\RequestInterface $request)**

        Sets the current request

        -   *param $request:* the request
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setArguments(array $arguments)**

        Additional query parameters.

        If you want to "prefix" arguments, you can pass in multidimensional arrays:
        array('prefix1' => array('foo' => 'bar')) gets "&prefix1\[foo\]=bar"

        -   *param $arguments:* the arguments
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setSection(string $section)**

        If specified, adds a given HTML anchor to the URI (#...)

        -   *param $section:* the section
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setFormat(string $format)**

        Specifies the format of the target (e.g. "html" or "xml")

        -   *param $format:* the format
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setCreateAbsoluteUri(bool $createAbsoluteUri)**

        If set, the URI is prepended with the current base URI. Defaults to FALSE.

        -   *param $createAbsoluteUri:* the createAbsoluteUri
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setAbsoluteUriScheme(string $absoluteUriScheme)**

        Sets the scheme that should be used for absolute URIs in FE mode

        -   *param $absoluteUriScheme:* the scheme to be used for absolute URIs
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setLanguage(?string $language)**

        Enforces a URI / link to a page to a specific language (or use "current")

        -   *param $language:* the language

        *Returns:* `TYPO3CMSExtbaseMvcWebRoutingUriBuilder`

    -   **getLanguage()**

        *Returns:* `?string`

    -   **setAddQueryString(string|int|bool $addQueryString)**

        If set, the current query parameters will be merged with $this->arguments in backend context.

        In frontend context, setting this property will only include mapped query arguments from the
        Page Routing. To include any - possible "unsafe" - GET parameters, the property has to be set
        to "untrusted". Defaults to FALSE.

        -   *param $addQueryString:* is set to "1", "true", "0", "false" or "untrusted"
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setArgumentsToBeExcludedFromQueryString(array $argumentsToBeExcludedFromQueryString)**

        A list of arguments to be excluded from the query parameters
        Only active if addQueryString is set

        -   *param $argumentsToBeExcludedFromQueryString:* the argumentsToBeExcludedFromQueryString
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setArgumentPrefix(string $argumentPrefix)**

        Specifies the prefix to be used for all arguments.

        -   *param $argumentPrefix:* the argumentPrefix
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setLinkAccessRestrictedPages(bool $linkAccessRestrictedPages)**

        If set, URIs for pages without access permissions will be created

        -   *param $linkAccessRestrictedPages:* the linkAccessRestrictedPages
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setTargetPageUid(int $targetPageUid)**

        Uid of the target page

        -   *param $targetPageUid:* the targetPageUid
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setTargetPageType(int $targetPageType)**

        Sets the page type of the target URI. Defaults to 0

        -   *param $targetPageType:* the targetPageType
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **setNoCache(bool $noCache)**

        by default FALSE; if TRUE, &no_cache=1 will be appended to the URI

        -   *param $noCache:* the noCache
        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **reset()**

        Resets all UriBuilder options to their default value

        -   *Return description:* The current UriBuilder to allow method chaining

        *Returns:* `static`

    -   **uriFor(?string $actionName = NULL, ?array $controllerArguments = NULL, ?string $controllerName = NULL, ?string $extensionName = NULL, ?string $pluginName = NULL)**

        Creates an URI used for linking to an Extbase action.

        Works in Frontend and Backend mode of TYPO3.

        -   *param $actionName:* Name of the action to be called, default: NULL
        -   *param $controllerArguments:* Additional query parameters. Will be "namespaced" and merged with $this->arguments., default: NULL
        -   *param $controllerName:* Name of the target controller. If not set, current ControllerName is used., default: NULL
        -   *param $extensionName:* Name of the target extension, without underscores. If not set, current ExtensionName is used., default: NULL
        -   *param $pluginName:* Name of the target plugin. If not set, current PluginName is used., default: NULL
        -   *Return description:* The rendered URI

        *Returns:* `string`

    -   **build()**

        Builds the URI
        Depending on the current context this calls buildBackendUri() or buildFrontendUri()

        -   *Return description:* The URI

        *Returns:* `string`
