Breadcrumb
Navigation component that helps users understand their location within a website's hierarchy.
TailwindCSS
package showcase
import "github.com/axzilla/templui/components"
templ BreadcrumbDefault() {
@components.Breadcrumb() {
@components.BreadcrumbList() {
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/",
}) {
Home
}
}
@components.BreadcrumbItem() {
@components.BreadcrumbSeparator()
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/docs",
}) {
Documentation
}
}
@components.BreadcrumbItem() {
@components.BreadcrumbSeparator()
@components.BreadcrumbPage(components.BreadcrumbItemProps{Current: true}) {
Components
}
}
}
}
}
package components
import (
"github.com/axzilla/templui/icons"
"github.com/axzilla/templui/utils"
)
type BreadcrumbProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbListProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbItemProps struct {
ID string
Class string
Attributes templ.Attributes
Current bool
}
type BreadcrumbLinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
}
type BreadcrumbSeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
UseCustom bool
}
templ Breadcrumb(props ...BreadcrumbProps) {
{{ var p BreadcrumbProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<nav
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex",
p.Class,
),
}
aria-label="Breadcrumb"
{ p.Attributes... }
>
{ children... }
</nav>
}
templ BreadcrumbList(props ...BreadcrumbListProps) {
{{ var p BreadcrumbListProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<ol
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</ol>
}
templ BreadcrumbItem(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<li
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</li>
}
templ BreadcrumbLink(props ...BreadcrumbLinkProps) {
{{ var p BreadcrumbLinkProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<a
if p.ID != "" {
id={ p.ID }
}
if p.Href != "" {
href={ templ.SafeURL(p.Href) }
}
class={
utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</a>
}
templ BreadcrumbSeparator(props ...BreadcrumbSeparatorProps) {
{{ var p BreadcrumbSeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
if p.UseCustom {
{ children... }
} else {
@icons.ChevronRight(icons.IconProps{Size: 14, Class: "text-muted-foreground"})
}
</span>
}
templ BreadcrumbPage(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),
}
aria-current="page"
{ p.Attributes... }
>
{ children... }
</span>
}
Usage
@components.Breadcrumb(components.BreadcrumbProps{...})
Examples
With Icons
package showcase
import (
"github.com/axzilla/templui/components"
"github.com/axzilla/templui/icons"
)
templ BreadcrumbWithIcons() {
@components.Breadcrumb() {
@components.BreadcrumbList() {
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/",
}) {
@icons.House(icons.IconProps{Size: 16})
<span class="ml-1">Home</span>
}
}
@components.BreadcrumbItem() {
@components.BreadcrumbSeparator()
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/docs",
}) {
@icons.FileText(icons.IconProps{Size: 16})
<span class="ml-1">Documentation</span>
}
}
@components.BreadcrumbItem() {
@components.BreadcrumbSeparator()
@components.BreadcrumbPage(components.BreadcrumbItemProps{Current: true}) {
@icons.Component(icons.IconProps{Size: 16})
<span class="ml-1">Components</span>
}
}
}
}
}
package components
import (
"github.com/axzilla/templui/icons"
"github.com/axzilla/templui/utils"
)
type BreadcrumbProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbListProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbItemProps struct {
ID string
Class string
Attributes templ.Attributes
Current bool
}
type BreadcrumbLinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
}
type BreadcrumbSeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
UseCustom bool
}
templ Breadcrumb(props ...BreadcrumbProps) {
{{ var p BreadcrumbProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<nav
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex",
p.Class,
),
}
aria-label="Breadcrumb"
{ p.Attributes... }
>
{ children... }
</nav>
}
templ BreadcrumbList(props ...BreadcrumbListProps) {
{{ var p BreadcrumbListProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<ol
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</ol>
}
templ BreadcrumbItem(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<li
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</li>
}
templ BreadcrumbLink(props ...BreadcrumbLinkProps) {
{{ var p BreadcrumbLinkProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<a
if p.ID != "" {
id={ p.ID }
}
if p.Href != "" {
href={ templ.SafeURL(p.Href) }
}
class={
utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</a>
}
templ BreadcrumbSeparator(props ...BreadcrumbSeparatorProps) {
{{ var p BreadcrumbSeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
if p.UseCustom {
{ children... }
} else {
@icons.ChevronRight(icons.IconProps{Size: 14, Class: "text-muted-foreground"})
}
</span>
}
templ BreadcrumbPage(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),
}
aria-current="page"
{ p.Attributes... }
>
{ children... }
</span>
}
Custom Separator
package showcase
import (
"github.com/axzilla/templui/components"
"github.com/axzilla/templui/icons"
)
templ BreadcrumbCustomSeparator() {
@components.Breadcrumb() {
@components.BreadcrumbList() {
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/",
}) {
Home
}
}
@components.BreadcrumbItem() {
@components.BreadcrumbSeparator(components.BreadcrumbSeparatorProps{UseCustom: true}) {
@icons.Slash(icons.IconProps{Size: 14})
}
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/products",
}) {
Products
}
}
@components.BreadcrumbItem() {
@components.BreadcrumbSeparator(components.BreadcrumbSeparatorProps{UseCustom: true}) {
@icons.Slash(icons.IconProps{Size: 14})
}
@components.BreadcrumbPage(components.BreadcrumbItemProps{Current: true}) {
Category
}
}
}
}
}
package components
import (
"github.com/axzilla/templui/icons"
"github.com/axzilla/templui/utils"
)
type BreadcrumbProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbListProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbItemProps struct {
ID string
Class string
Attributes templ.Attributes
Current bool
}
type BreadcrumbLinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
}
type BreadcrumbSeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
UseCustom bool
}
templ Breadcrumb(props ...BreadcrumbProps) {
{{ var p BreadcrumbProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<nav
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex",
p.Class,
),
}
aria-label="Breadcrumb"
{ p.Attributes... }
>
{ children... }
</nav>
}
templ BreadcrumbList(props ...BreadcrumbListProps) {
{{ var p BreadcrumbListProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<ol
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</ol>
}
templ BreadcrumbItem(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<li
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</li>
}
templ BreadcrumbLink(props ...BreadcrumbLinkProps) {
{{ var p BreadcrumbLinkProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<a
if p.ID != "" {
id={ p.ID }
}
if p.Href != "" {
href={ templ.SafeURL(p.Href) }
}
class={
utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</a>
}
templ BreadcrumbSeparator(props ...BreadcrumbSeparatorProps) {
{{ var p BreadcrumbSeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
if p.UseCustom {
{ children... }
} else {
@icons.ChevronRight(icons.IconProps{Size: 14, Class: "text-muted-foreground"})
}
</span>
}
templ BreadcrumbPage(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),
}
aria-current="page"
{ p.Attributes... }
>
{ children... }
</span>
}
Responsive
package showcase
import "github.com/axzilla/templui/components"
templ BreadcrumbResponsive() {
<!-- Mobile view (simplified with ellipsis) -->
<div class="md:hidden">
@components.Breadcrumb() {
@components.BreadcrumbList() {
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/",
}) {
Home
}
}
@components.BreadcrumbSeparator()
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "#",
}) {
...
}
}
@components.BreadcrumbSeparator()
@components.BreadcrumbItem() {
@components.BreadcrumbPage(components.BreadcrumbItemProps{Current: true}) {
Current Page
}
}
}
}
</div>
<!-- Desktop view (full breadcrumb) -->
<div class="hidden md:block">
@components.Breadcrumb() {
@components.BreadcrumbList() {
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/",
}) {
Home
}
}
@components.BreadcrumbSeparator()
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/category",
}) {
Category
}
}
@components.BreadcrumbSeparator()
@components.BreadcrumbItem() {
@components.BreadcrumbLink(components.BreadcrumbLinkProps{
Href: "/category/subcategory",
}) {
Subcategory
}
}
@components.BreadcrumbSeparator()
@components.BreadcrumbItem() {
@components.BreadcrumbPage(components.BreadcrumbItemProps{Current: true}) {
Current Page
}
}
}
}
</div>
}
package components
import (
"github.com/axzilla/templui/icons"
"github.com/axzilla/templui/utils"
)
type BreadcrumbProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbListProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BreadcrumbItemProps struct {
ID string
Class string
Attributes templ.Attributes
Current bool
}
type BreadcrumbLinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
}
type BreadcrumbSeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
UseCustom bool
}
templ Breadcrumb(props ...BreadcrumbProps) {
{{ var p BreadcrumbProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<nav
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex",
p.Class,
),
}
aria-label="Breadcrumb"
{ p.Attributes... }
>
{ children... }
</nav>
}
templ BreadcrumbList(props ...BreadcrumbListProps) {
{{ var p BreadcrumbListProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<ol
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</ol>
}
templ BreadcrumbItem(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<li
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</li>
}
templ BreadcrumbLink(props ...BreadcrumbLinkProps) {
{{ var p BreadcrumbLinkProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<a
if p.ID != "" {
id={ p.ID }
}
if p.Href != "" {
href={ templ.SafeURL(p.Href) }
}
class={
utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</a>
}
templ BreadcrumbSeparator(props ...BreadcrumbSeparatorProps) {
{{ var p BreadcrumbSeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
if p.UseCustom {
{ children... }
} else {
@icons.ChevronRight(icons.IconProps{Size: 14, Class: "text-muted-foreground"})
}
</span>
}
templ BreadcrumbPage(props ...BreadcrumbItemProps) {
{{ var p BreadcrumbItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),
}
aria-current="page"
{ p.Attributes... }
>
{ children... }
</span>
}