---
title: "The LinkHandler API"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:linkhandler@main"
source: "ApiOverview/LinkHandling/Linkhandler/Index.rst"
rendered: "2026-09-19T06:56:03+00:00"
---

# The LinkHandler API {#linkhandler}

The LinkHandler API currently consists of 7 LinkHandler classes and the
`\TYPO3\CMS\Backend\LinkHandler\LinkHandlerInterface`. The
LinkHandlerInterface can be implemented to create custom LinkHandlers.

Most LinkHandlers cannot receive additional configuration, they are marked as
`@internal` and contain neither hooks nor events. They are therefore
of interest to Core developers only.

Current LinkHandlers:

-   [The PageLinkHandler](https://docs.typo3.org/permalink/t3coreapi:pagelinkhandler@main): for linking pages and content
-   [The RecordLinkHandler](https://docs.typo3.org/permalink/t3coreapi:recordlinkhandler@main): for linking any kind of record
-   UrlLinkHandler: for linking external urls
-   FileLinkHandler: for linking files in the [File abstraction layer (FAL)](https://docs.typo3.org/permalink/t3coreapi:fal@main)
-   FolderLinkHandler: for linking to directories
-   MailLinkHandler: for linking email addresses
-   TelephoneLinkHandler: for linking phone numbers

> [!NOTE]
> In the system extension `core` there are also classes ending on
> "LinkHandler". However those implement the interface `LinkHandlingInterface`
> and are part of the LinkHandling API, not the LinkHandler API.

The links are now stored in the database with the syntax
`<a href="t3://record?identifier=anIdentifier&amp;uid=456">A link</a>`.

1.  TypoScript is used to generate the actual link in the frontend.

    **EXT:some_extension/Configuration/Sets/SomeExtension/setup.typoscript (excerpt)**

    ```typoscript
    config.recordLinks.anIdentifier {
      // Do not force link generation when the record is hidden
      forceLink = 0
      typolink {
        parameter = 123
        additionalParams.data = field:uid
        additionalParams.wrap = &tx_example_pi1[item]=|&tx_example_pi1[controller]=Item&tx_example_pi1[action]=show
      }
    }

    # ...

    ```

    > [!WARNING]
    > **Attention**
    >
    > Do not change the identifier after links have been created  using the LinkHandler. The identifier will be
    > stored as part of the link in the database.

## LinkHandler page TSconfig options {#linkhandler-pagetsconfig}

The minimal page TSconfig configuration is:

**EXT:some_extension/Configuration/page.tsconfig (excerpt)**

```typoscript
TCEMAIN.linkHandler.anIdentifier {
  handler = TYPO3\CMS\Backend\LinkHandler\RecordLinkHandler
  label = extension.messages:link.customTab
  configuration {
    table = tx_example_domain_model_item
  }
}

# ...

```

See [Link handler configuration](https://docs.typo3.org/permalink/t3coreapi:link-handler-configuration@main) for all available options.

### Example: news records from one storage pid {#linkhandler-pagetsconfig-example-news-records}

The following configuration hides the page tree and shows news records only
from the defined storage page:

**EXT:some_extension/Configuration/page.tsconfig (excerpt)**

```typoscript
TCEMAIN.linkHandler.news {
  handler = TYPO3\CMS\Backend\LinkHandler\RecordLinkHandler
  label = News
  configuration {
    table = tx_news_domain_model_news
    storagePid = 123
    hidePageTree = 1
  }
  displayAfter = email
}

# ...

```

It is possible to have another configuration using another storagePid which
also contains news records.

This configuration shows a reduced page tree starting at page with uid 42:

**EXT:some_extension/Configuration/page.tsconfig (excerpt)**

```typoscript
TCEMAIN.linkHandler.bookreports {
  handler = TYPO3\CMS\Backend\LinkHandler\RecordLinkHandler
  label = Book Reports
  configuration {
    table = tx_news_domain_model_news
    storagePid = 42
    pageTreeMountPoints = 42
    hidePageTree = 0
  }
}

# ...

```

The page TSconfig of the LinkHandler is being used in sysext `backend`
in class `\TYPO3\CMS\Backend\LinkHandler\RecordLinkHandler`
which does not contain Hooks.

> [!WARNING]
> **Attention**
>
> It is important, that the `storagePid` is hard coded in TSConfig, because using
> constants, for example from the site configuration, will not work here.

## LinkHandler TypoScript options {#linkhandler-typoscript}

A configuration could look like this:

**EXT:some_extension/Configuration/Sets/SomeExtension/setup.typoscript (excerpt)**

```typoscript
config.recordLinks.anIdentifier {
  forceLink = 0

  typolink {
    parameter = 123
    additionalParams.data = field:uid
    additionalParams.wrap = &tx_example_pi1[item]=|
  }
}

# ...

```

The TypoScript Configuration of the LinkHandler is being used in sysext `frontend`
in class `\TYPO3\CMS\Frontend\Typolink\DatabaseRecordLinkBuilder`.

### Example: news records displayed on fixed detail page {#linkhandler-typoscript-example-news-records}

The following displays the link to the news on a detail page:

**EXT:some_extension/Configuration/Sets/SomeExtension/setup.typoscript (excerpt)**

```typoscript
config.recordLinks.news {
  typolink {
    parameter = 123
    additionalParams.data = field:uid
    additionalParams.wrap = &tx_news_pi1[controller]=News&tx_news_pi1[action]=detail&tx_news_pi1[news]=|
  }
}

# ...

```

Once more if the book reports that are also saved as `tx_news_domain_model_news` record should be displayed on their own
detail page you can do it like this:

**EXT:some_extension/Configuration/Sets/SomeExtension/setup.typoscript (excerpt)**

```typoscript
config.recordLinks.bookreports {
  typolink {
    parameter = 987
    additionalParams.data = field:uid
    additionalParams.wrap = &tx_news_pi1[controller]=News&tx_news_pi1[action]=detail&tx_news_pi1[news]=|
  }
}

# ...

```
