---
title: "Use the backend UriBuilder to link to \"Edit Records\""
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:edit-links@main"
source: "ApiOverview/Backend/UriBuilder.rst"
modified: "2026-09-14T11:10:56+00:00"
---

# Use the backend `UriBuilder` to link to "Edit Records"

It is often needed to create links to edit records in the TYPO3 backend.
The same syntax is also used for creating new records.
TYPO3 provides an API for creating such links, namely
`TYPO3CMSBackendRoutingUriBuilder`.

> [!TIP]
> **Hint**
>
> Make sure to use `TYPO3CMSBackendRoutingUriBuilder` to create
> backend links and not `TYPO3CMSExtbaseMvcWebRoutingUriBuilder`.
>
> The variable available as `$this->uriBuilder` in a controller is the
> web routing UriBuilder and can only be used for frontend links.

When using Fluid templates the URI
either has to be created via PHP in the controller or a ViewHelper to be used.

## Display a link to "Edit Record"

The [Uri.editRecord ViewHelper \<be:uri.editRecord>](https://docs.typo3.org/other/typo3/view-helper-reference/main/en-us/Backend/Uri/EditRecord.html#typo3-backend-uri-editrecord) can be used to create a
"create new record" link:

**EXT:my_extension/Resources/Private/Partials/BackendModule/EditRecordLink.fluid.html**

```html
{namespace be=TYPO3\CMS\Backend\ViewHelpers}
{namespace core=TYPO3\CMS\Core\ViewHelpers}
<a href="{be:uri.editRecord(uid:2, table:'pages', returnUrl:'foo/bar')}">
    <core:icon identifier="actions-document-open"/>
    Edit Page 2
</a>

```

If you create the backend link via PHP it is possible to add more options like
default values for certain fields.

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

```php
<?php

namespace MyVendor\MyExtension\Controller;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

class ModuleController extends ActionController
{
  public function __construct(
    protected readonly ModuleTemplateFactory $moduleTemplateFactory,
    private readonly UriBuilder $backendUriBuilder,
  ) {}

  protected function getEditLink(): UriInterface
  {
    $uriParameters = [
      'edit' =>
          [
            'pages' => [1 => 'edit'],
          ],
    ];
    return $this->backendUriBuilder
        ->buildUriFromRoute('record_edit', $uriParameters);
  }

  public function linksAction(): ResponseInterface
  {
    $backendView = $this->initializeModuleTemplate($this->request);
    $editPage1Link = $this->getEditLink();
    $backendView->assignMultiple(
      [
        'editPage1Link' => $editPage1Link,
      ],
    );
    return $backendView->renderResponse('ShowPost');
  }
  protected function initializeModuleTemplate(
    ServerRequestInterface $request,
  ): ModuleTemplate {
    $view = $this->moduleTemplateFactory->create($request);

    // ...

    return $view;
  }
}

```

## Examples of "Edit record" links

The example extension [`t3docs/examples`](https://packagist.org/packages/t3docs/examples) contains extended examples of
different types of edit/create record links in the backend.

Here an excerpt:

**Class T3docs\\Examples\\Controller\\ModuleController**

```php
<?php

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
use Psr\Log\LoggerInterface;
use T3docs\Examples\Service\TableInformationService;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Resource\ResourceFactory;

class ModuleController extends ActionController
{
  public function linksAction(): ResponseInterface
  {
    $pageUid = (int)($this->request->getQueryParams()['id'] ?? 0);
    $returnUrl = (string)$this->backendUriBuilder->buildUriFromRoute(
      'content_examples_links',
      ['id' => $pageUid, 'action' => 'links'],
    );

    $editPage1Link = $this->getEditPageLink(1, $returnUrl);
    $editPagesDoktypeLink = $this->getEditDoktypeLink($returnUrl);
    $createHaikuLink = $this->getCreateHaikuLink($returnUrl);

    $view = $this->initializeModuleTemplate($this->request);
    $view->assignMultiple(
      [
        'editPage1Link' => $editPage1Link,
        'editPagesDoktypeLink' => $editPagesDoktypeLink,
        'createHaikuLink' => $createHaikuLink,
        'returnUrl' => $returnUrl,
      ],
    );
    return $view->renderResponse('Module/Links');
  }

  private function getEditPageLink(int $uid, string $returnUrl): UriInterface
  {
    $uriParameters = [
      'edit' => [
        'pages' => [
          $uid => 'edit',
        ],
      ],
      'returnUrl' => $returnUrl,
    ];
    return $this->backendUriBuilder->buildUriFromRoute(
      'record_edit',
      $uriParameters,
    );
  }

  public function __construct(
    protected readonly ModuleTemplateFactory $moduleTemplateFactory,
    protected readonly IconFactory $iconFactory,
    protected readonly ExtensionConfiguration $extensionConfiguration,
    protected readonly PasswordHashFactory $passwordHashFactory,
    protected readonly ResourceFactory $resourceFactory,
    protected readonly FileRepository $fileRepository,
    protected readonly ConnectionPool $connectionPool,
    protected readonly TableInformationService $tableInformationService,
    protected readonly LoggerInterface $logger,
    protected readonly UriBuilder $backendUriBuilder,
  ) {}
}

```

The links appear in the example backend module:

![](../../Images/ManualScreenshots/Examples/EditLinks/EditLinksDisplay.png)

The examples above leads to the normal edit form for a page:

![](../../Images/ManualScreenshots/Examples/EditLinks/EditLinksEditFull.png)

## Additional options for editing records

When creating the link via PHP it is possible to add more options.

You can specify as many tables and UIDs as needed and you will get them all in
one single form!
(short way of editing more records from the same table at once).

Also the fields to be displayed can be restricted.

**Class T3docs\\Examples\\Controller\\ModuleController**

```php
<?php

use Psr\Http\Message\UriInterface;

class ModuleController extends ActionController
{
  protected function getEditDoktypeLink(string $returnUrl): UriInterface
  {
    $uriParameters =
        [
          'edit' => [
            'pages' => [
              1 => 'edit',
              2 => 'edit',
            ],
            'tx_examples_haiku' => [
              1 => 'edit',
            ],
          ],
          'columnsOnly' => [
            'pages' => [
              'title',
              'doktype',
            ],
          ],
          'returnUrl' => $returnUrl,
        ];
    return $this->backendUriBuilder->buildUriFromRoute(
      'record_edit',
      $uriParameters,
    );
  }
}

```

> [!NOTE]
> **Changed in version 14.0**
>
> Accepting  a comma-separated list of fields as value for `columnsOnly`
> has been removed. See [Migration: Table dependant definition of columnsOnly](https://docs.typo3.org/m/typo3/reference-coreapi/13.4/en-us/ApiOverview/Backend/UriBuilder.html#edit-links-columnsOnly-migration).

The fields to be included can be listed in the `columnsOnly` parameter, as a comma-separated list.
The order of the fields doesn't matter, they get displayed in the order they appear in the TCA.
If a field is missing or access restricted in one of the tables it just doesn't appear.
However if one record to be edited is missing none of the records gets displayed.

The example above results in the following:

![](../../Images/ManualScreenshots/Examples/EditLinks/EditLinksEditRestricted.png)

## Display a link to "Create a New Record"

The [Uri.newRecord ViewHelper \<be:uri.newRecord>](https://docs.typo3.org/other/typo3/view-helper-reference/main/en-us/Backend/Uri/NewRecord.html#typo3-backend-uri-newrecord) can be used to create a
"create new record" link:

**EXT:examples/Resources/Private/Partials/Module/CreateHaikuBlankLink.fluid.html**

```html
<html data-namespace-typo3-fluid="true"
      xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
      xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
>
   <a href="{be:uri.newRecord(pid:1, table:'tx_examples_haiku', returnUrl:returnUrl)}">
      <core:icon identifier="actions-document-new"/>
      <f:translate key="function_links_new_haiku"/>
   </a>
</html>

```

If you create the backend link via PHP it is possible to add more options like
default values for certain fields.

**Class T3docs\\Examples\\Controller\\ModuleController**

```php
<?php

use Psr\Http\Message\UriInterface;

class ModuleController extends ActionController
{
  protected function getCreateHaikuLink(string $returnUrl): UriInterface
  {
    $uriParameters =
        [
          'edit' => [
            'tx_examples_haiku' => [
              1 => 'new',
            ],
          ],
          'defVals' => [
            'tx_examples_haiku' => [
              'title' => 'New Haiku?',
              'season' => 'Spring',
            ],
          ],
          'columnsOnly' => [
            'tx_examples_haiku' => [
              'title',
              'season',
              'color',
            ],
          ],
          'returnUrl' => $returnUrl,
        ];
    return $this->backendUriBuilder->buildUriFromRoute(
      'record_edit',
      $uriParameters,
    );
  }
}

```

> [!NOTE]
> **Changed in version 14.0**
>
> Accepting  a comma-separated list of fields as value for `columnsOnly`
> has been removed. See [Migration: Table dependant definition of columnsOnly](https://docs.typo3.org/m/typo3/reference-coreapi/13.4/en-us/ApiOverview/Backend/UriBuilder.html#edit-links-columnsOnly-migration).

It can then be displayed like this:

**EXT:examples/Resources/Private/Partials/Module/CreateHaikuLink.fluid.html**

```html
<html data-namespace-typo3-fluid="true"
      xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
>
   <a href="{createHaikuLink}">
      <core:icon identifier="actions-document-new"/>
      <f:translate key="function_links_new_spring_haiku"/>
   </a>
</html>

```

The link triggers the creation a new record for the table `tx_examples_haiku`
on page 1. It also sets a default value for the `title` field ("New haiku") and
selects the season "Spring". It only displays the fields defined by `columnsOnly`.

Note the following things:

-   the first parameter is called "edit" even if this is about creating a new record.
    The creation of a record is indicated by the value "new".
-   the key of the entry with value "new" indicates the pid on which the record is to be created.
-   the values get automatically url-encoded so you can use any special char in the defaults

This results in the following new record form with a pre-filled
title and season field.

![](../../Images/ManualScreenshots/Examples/EditLinks/EditLinksNew.png)
