If you've built Django sites, you've composed pages with {% include %}, {% extends %} / {% block %} and the occasional custom template tag. These work, but they were designed for page-level layout and value substitution, not for building small, self-contained pieces of UI you reuse and nest. That gap is what components fill.
{% include %} pulls in another template, but you can only hand it flat context values. You can't pass a block of markup, or nest other pieces inside it.{% extends %} / {% block %} is great for one page-level skeleton, but it's single inheritance and top-down: a template fills a parent's holes, it can't be dropped in repeatedly like a widget.A component is a single, self-contained piece of UI that you use like an HTML tag. It bundles three things:
<c-card title="Welcome">.<div class="card">
<h2>{{ title }}</h2>
{{ slot }}
</div>
Now use it like a tag, passing an attribute and nesting whatever content you like, including other components:
<c-card title="Welcome">
<p>Any HTML, or even <c-icon name="star" />, goes here.</p>
</c-card>
{% cotton card title="Welcome" %}
<p>Any HTML, or even {% cotton icon name="star" %}{% endcotton %}, goes here.</p>
{% endcotton %}
The instincts you already have map directly onto components:
| When you'd reach for... | Use a component |
|---|---|
{% include %} with context |
A tag with attributes: <c-card title="..." /> |
{% block %} / {% extends %} |
A <c-slot> for each content hole |
| A presentational custom tag | A component, just an HTML file, no Python |