Skip to main content

Why Fluid Primitives?

TYPO3 Fluid is great for templating, but building interactive UI components often becomes painful. Fluid Primitives fixes that.

The Problem with Traditional Components

Traditional Fluid components tend to accumulate props until they become unwieldy:

<ui:card rootClass="some-class" image="path/to/image" imageAlt="Alt text" title="Hello World" titleLevel="3" text="Lorem ipsum" cta="1" ctaVariant="secondary" ctaText="Learn more" ctaLink="/some-page" secondaryCta="1" secondaryCtaText="..." />

Need two buttons? Add more props. Different layout? More conditional logic. Soon you're managing a tangled mess of f:if conditions and documentation becomes impossible.

The Composable Alternative

Fluid Primitives uses the composition pattern popularized by Radix, Base UI, and others:

<ui:card.root class="some-class">
    <ui:card.image src="path/to/image" alt="Alt text" />
    <ui:card.title level="3">Hello World</ui:card.title>
    <ui:card.content>
        <p>Lorem ipsum</p>
        <ui:button variant="secondary" link="/some-page">Learn more</ui:button>
        <ui:button variant="ghost" link="/other-page">Secondary action</ui:button>
    </ui:card.content>
</ui:card.root>

What's different:

Accessibility Without the Work

Interactive components are hard to build correctly. Keyboard navigation, focus management, screen reader support, ARIA states - it's easy to miss something.

Fluid Primitives handles all of this automatically. Every interactive component is built on Zag.js state machines that have been battle-tested across frameworks.

<ui:accordion.root>
    <ui:accordion.item value="item-1">
        <ui:accordion.trigger>Section 1</ui:accordion.trigger>
        <ui:accordion.content>Content here...</ui:accordion.content>
    </ui:accordion.item>
</ui:accordion.root>

This accordion supports:

All without writing a single line of JavaScript or worrying about edge cases.

Unstyled by Design

Components ship with zero visual styles. You bring your own design system:

<ui:accordion.item class="border-b border-gray-200 data-[state=open]:bg-gray-50"></ui:accordion.item>

Use Tailwind utilities, BEM classes, or vanilla CSS. Target states via data attributes like data-state="open" or data-disabled.

Check the Styling Guide for patterns and examples.

Server-First Architecture

Unlike client-side component libraries, Fluid Primitives renders on the server first. The HTML arrives complete, then JavaScript hydrates interactive behavior.

This means: