---
title: "Providing External Components"
manual: "Fluid Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/fluid:component-providers"
source: "Extending/ComponentProviders.rst"
rendered: "2026-09-26T08:24:58+00:00"
---

# Providing External Components {#component-providers}

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

Fluid supports [components that are defined as Fluid templates](https://docs.typo3.org/permalink/fluid:components)
out-of-the-box. However, it is also possible to integrate external component
libraries into your Fluid-based project. This makes it possible to bridge
the gap between Fluid and other templating engines, such as Twig or Mustache.

> [!NOTE]
> There are no official integrations of Fluid with other templating engines.
> This page merely demonstrates how existing Fluid APIs can be used
> to achieve this.

## Architecture Overview {#architecture-overview}

Fluid's component features are based on several classes and interfaces. Some
are meant to be extended/implemented, others merely exist for internal
purposes and are annotated as `@internal` in the PHPDoc header.

The `ComponentDefinitionProviderInterface`, together with
`ComponentRendererInterface`, are the primary interfaces that can
be used (together with a [ViewHelperResolver delegate](https://docs.typo3.org/permalink/fluid:viewhelperresolver-delegates))
to "teach" Fluid how to interact with components. The definition provider
returns instances of `ComponentDefinition`, which is an immutable DTO.

The `ComponentAdapter` is an adapter class that translates between the
ViewHelper API and the described components API. It is used as default
ViewHelper implementation for all components during parse-time and will never
be used once a template is cached. It is marked `@internal` and is not
intended to be extended/replaced.

The `ComponentTemplateResolverInterface` is an internal interface that is
related to Fluid's own component implementation. Same goes for
`ComponentRenderer`, which renders Fluid-based component templates.
`AbstractComponentCollection` is the base implementation for Fluid-based
components, which are documented in a separate chapter about
[Components](https://docs.typo3.org/permalink/fluid:components).

## Custom ComponentRenderer {#custom-componentrenderer}

The `ComponentRendererInterface` specifies how a component should be rendered.
This is the place where e. g. an external templating engine would be initiated
to render a specific template:

**CustomComponentRenderer.php (component renderer)**

```php
namespace Vendor\MyPackage;

use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;

final readonly class CustomComponentRenderer implements ComponentRendererInterface
{
    public function renderComponent(
        string $viewHelperName,
        array $arguments,
        array $slots,
        RenderingContextInterface $parentRenderingContext,
    ): string {
        $view = new TemplatingEngine();
        $view->setVariables($arguments);
        $view->setSlots($slots);
        return $view->render($viewHelperName);
    }
}
```

The `$parentRenderingContext` can be used to extract additional information from
the parent Fluid template that should be passed to the component, such as a `Request`
object.

## Custom ComponentDefinitionProvider {#custom-componentdefinitionprovider}

The `ComponentDefinitionProviderInterface` provides Fluid with all necessary
information to resolve, validate and render external components. Depending
on the available component metadata, the Fluid parser is even able to pre-validate
the supplied component parameters (defined and required arguments, booleans). However, it is
also possible to provide a "non-strict" implementation where any argument can be supplied
to the external components. The interface must always be used in combination with
`ViewHelperResolverDelegateInterface`.

**CustomComponentCollection.php (component definition provider)**

```php
namespace Vendor\MyPackage;

use TYPO3Fluid\Fluid\Core\Component\ComponentDefinition;
use TYPO3Fluid\Fluid\Core\ViewHelper\UnresolvableViewHelperException;
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperResolverDelegateInterface;
use Vendor\MyPackage\CustomComponentRenderer;

final class CustomComponentCollection implements ViewHelperResolverDelegateInterface, ComponentDefinitionProviderInterface
{
    public function getComponentDefinition(string $viewHelperName): ComponentDefinition
    {
        $metadata = TemplatingEngine::getComponentMetadata($viewHelperName);
        $definition = new ComponentDefinition(
            // map metadata...
        );
        return $definition;
    }

    public function getComponentRenderer(): ComponentRendererInterface
    {
        return new CustomComponentRenderer();
    }

    public function resolveViewHelperClassName(string $viewHelperName): string
    {
        if (!TemplatingEngine::componentExists($viewHelperName)) {
            throw new UnresolvableViewHelperException(
                // ...
            );
        }
        return ComponentAdapter::class;
    }

    public function getNamespace(): string
    {
        return static::class;
    }
}
```
