---
title: "Examples for typolink.userFunc"
manual: "TypoScript Explained"
version: "13.4"
permalink: "https://docs.typo3.org/permalink/t3tsref:typolink-userfunc-examples@13.4"
source: "Functions/_Examples/Typolink-Example.rst"
rendered: "2026-09-19T07:15:48+00:00"
noindex: true
---

# Examples for `typolink.userFunc` {#typolink-userfunc-examples}

Given this TypoScript example:

**EXT:site_package/Configuration/TypoScript/setup.typoscript**

```typoscript
registration {
  value = My Link Title
  typolink {
    parameter = 4711
    additionalParams = &someKey=someValue
    language = 3
    ATagParams = rel="noreferrer"
    title = My Link Title
    userFunc = MyVendor\MySitePackage\UserFunctions\TypoLinkUserFunc->createUserFuncLink
    userFunc {
      eventUid = TEXT
      eventUid.data = field:eventUid
      someFuncParam = someFuncValue
    }
  }
}

```

This would first create a TypoLink
`LinkResultInterface` that would resolve
to something like
`<a href="/en/pages/4711?someKey=someValue" rel="noreferrer">My Link Text</a>`.

But because `userFunc = MyVendor\SitePackage\UserFunctions\TypoLinkUserFunc->createUserFuncLink`
is defined you can now manipulate the generated link to your liking.

The usual case would be to enrich the link with any kind of attributes, or also
to change existing ones:

**EXT:site_package/Classes/UserFunctions/TypoLinkUserFunc.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MySitePackage\UserFunctions;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Frontend\Typolink\LinkResultInterface;

class TypoLinkUserFunc
{
  public function createUserFuncLink(
    LinkResultInterface $content,
    array $conf,
    ServerRequestInterface $request,
  ): LinkResultInterface {
    // First check what kind of link this is.
    // This example only operates on TYPE_PAGE for internal
    // links; the userFunc can of course also react to
    // types like TYPE_URL (external pages)
    if ($content->getType() === LinkService::TYPE_PAGE) {
      // Add (or replace) a custom "title" link attribute and
      // add "target=_blank" to it, and adjust the link text:

      return $content
          ->withTarget('_blank')
          ->withAttribute('title', 'Custom Title')
          ->withLinkText('A replaced link');
    }

    // If the condition does not match, return the unmodified
    // link.
    return $content;
  }
}

```

This class would take the
`LinkResultInterface` object, enrich it
with attributes, pass it to a new immutable object and return that. Then this is
what finally gets emitted after full processing:

**Example output**

```html
<a href="/en/pages/4711"
   target="_blank"
   title="Custom Title"
   rel="noreferrer">A replaced link</a>
```

Here is another example which uses more complex operations and also operates on the
linked URL:

**EXT:site_package/Classes/UserFunctions/TypoLinkUserFunc.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MySitePackage\UserFunctions;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\Typolink\LinkResult;
use TYPO3\CMS\Frontend\Typolink\LinkResultInterface;

class TypoLinkUserFunc
{
  public function createUserFuncLink(
    LinkResultInterface $content,
    array $conf,
    ServerRequestInterface $request,
  ): LinkResultInterface {

    // First check what kind of link this is.
    // This example only operates on TYPE_PAGE for internal
    // links; the userFunc can of course also react to
    // types like TYPE_URL (external pages)
    if ($content->getType() === LinkService::TYPE_PAGE) {
      $cObj = $this->getContentObjectRenderer($request);

      // Check if typolink.userFunc additional data is set
      // and act on it
      if ($conf['eventUid.']['data'] ?? null) {
        $url = $content->getAttribute('href')
          . '/event/' . (int)$conf['eventUid.']['data'];
        // Here you could do database lookups for example
        // to add extbase routing URIs and retrieve
        // fields. This is just an example, proper link building
        // needs to be performed here, also considering cHash.
        $linkText = 'Event Title #18';
      } else {
        // Use currently defined URL
        $url = $content->getUrl();
        // Example how to utilize the cObj and it's wrapping so
        // that `<a href=...><strong>(TITLE!)</strong></a>`
        // would be returned.
        $linkText = $cObj->stdWrap_dataWrap('<strong>{FIELD:title}</strong');
      }

      return $content
          ->withTarget('_blank')
          ->withAttribute('href', $url)
          ->withAttribute('title', 'Custom: ' . $cObj->data['title'])
          ->withLinkText($linkText);
    }

    if ($conf['freshExternalLink'] ?? false) {
      // Depending on conditions, you could also return a completely new object
      // for an external link:
      return (new LinkResult(LinkService::TYPE_URL, 'https://example.com'))
              ->withLinkText('I am an external link');
    }

    if ($conf['freshInternalLink'] ?? false) {
      // ... or an internal link (UID in $conf['freshInternalPageUid']):
      // NOTE: You might want to use the PageLinkBuilder to achieve this;
      //       (this is not yet documented)
      $cObj = $this->getContentObjectRenderer($request);
      $frontendUrl = $cObj->typoLink_URL(['parameter' => $conf['freshInternalPageUid'] ?? 1]);
      return (new LinkResult(LinkService::TYPE_PAGE, $frontendUrl))
          ->withLinkText('I am an internal link');
    }

    // If the condition does not match, return the unmodified link.
    return $content;
  }

  protected function getContentObjectRenderer(ServerRequestInterface $request): ContentObjectRenderer
  {
    return $request->getAttribute('currentContentObject');
  }
}

```

This class would take the
`LinkResultInterface` object, retrieve
some data from it, alter it, pass it to a new immutable object and return that.
Then this is what finally gets emitted after full processing:

**Example output**

```html
<a href="/en/pages/4711/event/18"
   target="_blank"
   title="Custom: My Link Text"
   rel="noreferrer">Event Title #18</a>
```

You can also apply a custom `userFunc` to vital objects like the
[lib.parseFunc_RTE.userFunc](https://docs.typo3.org/permalink/t3tsref:parsefunc-userfunc@13.4)
routine. This would allow you to modify any kind of link generated from the
parsing of the Rich-Text-Editor (RTE), usually by adding CSS classes to it,
adjusting `rel` attributes or attaching `data-XXX` attributes.
