Components
Reusable template fragments with props and slots for building consistent UI elements.
How components work
A component is a .tulip file in the components/ directory. Components accept named props and a default slot for inner content. Use @component to render a component and @endcomponent to close it.
Defining a component
Create a file in components/ that uses props and the special {{ slot }} variable:
<!-- components/card.tulip -->
<div class="card">
<h3>{{ title }}</h3>
<div class="card-body">
{{ slot }}
</div>
</div>The {{ slot }} variable is replaced with whatever content is placed between the opening and closing component tags.
Using a component
Invoke a component by name and pass props as a JSON-like object:
@component('card', { title: "Getting Started" })
<p>Welcome to the documentation.</p>
<a href="/docs">Read more</a>
@endcomponentThe path is relative to the components/ directory, without the .tulip extension.
Props
Props are passed as key-value pairs in the second argument to @component. Inside the component template, each prop is available as a variable:
<!-- components/alert.tulip -->
<div class="alert alert-{{ level }}">
<strong>{{ heading }}</strong>
{{ slot }}
</div>Usage:
@component('alert', { level: "warning", heading: "Caution" })
<p>This action cannot be undone.</p>
@endcomponentComponents without slots
If a component template does not reference {{ slot }}, tulip automatically treats it as self-closing — no @endcomponent needed:
<!-- components/divider.tulip -->
<hr class="divider">Usage:
@component('divider')
@component('nav-link', { path: "/about", label: "About" })slot, you must provide @endcomponent. If it doesn't, you can omit it.Navigation example
A navigation component that renders a list of links:
<!-- components/nav.tulip -->
<nav class="site-nav">
{{ slot }}
</nav>Usage:
@component('nav')
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/blog">Blog</a>
@endcomponentComponent file location
All component files must be in the components/ directory at the root of your tulip project:
my-site/
components/
card.tulip # @component('card', { ... })
alert.tulip # @component('alert', { ... })
nav.tulip # @component('nav')
divider.tulip # @component('divider')