Files
Htmx/docs/Components/Alert.md
T
2026-05-04 19:57:48 +05:00

4.9 KiB
Raw Blame History

Alert

A contextual callout box for informational or error messages. Two variants: default (neutral) and destructive (red). An optional inline SVG icon is positioned automatically.


HTML structure

div[role=alert].{variant classes}
  {icon SVG}               ← positioned absolute top-left via Tailwind arbitrary selectors
  div
    h5.font-medium         ← title (always rendered)
    div.text-sm            ← description (omitted when empty)

CSS mechanics

Class / selector Effect
[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 Positions any direct SVG child at top-left
[&>svg~*]:pl-7 Adds left padding to all siblings after the SVG so text is not covered by the icon
[&>svg+div]:translate-y-[-3px] Vertically aligns the text div with the icon center
border-destructive/50 text-destructive Red destructive variant

The arbitrary selector approach ([&>svg]:*) means you can pass any SVG and it will be positioned correctly without extra wrapper divs.


Constructor signature

public Alert(
    string title,
    string description = "",
    string variant     = "default",
    string icon        = "")
Parameter Description
title Required heading text
description Optional body text below the title
variant "default" or "destructive"
icon Raw SVG string; omit for a text-only alert

Usage examples

Informational (no icon)

new Alert(
    title: "Heads up",
    description: "Your session expires in 5 minutes.")

Destructive

new Alert(
    title: "Error",
    description: "Invalid email or password.",
    variant: "destructive")

With an icon

new Alert(
    title: "New message",
    description: "You have 3 unread messages.",
    variant: "default",
    icon: """
        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24"
             fill="none" stroke="currentColor" stroke-width="2"
             stroke-linecap="round" stroke-linejoin="round">
          <path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07
                   A19.5 19.5 0 013.07 9.77a19.79 19.79 0 01-3.07-8.67
                   A2 2 0 012 .18L5 0a2 2 0 012 1.72 ..."/>
        </svg>
    """)

Title-only

new Alert(title: "Changes saved successfully.", variant: "default")

Tips and tricks

  • The icon SVG should be h-4 w-4 — larger sizes will push text out of alignment.
  • For the destructive variant the icon automatically inherits text-destructive color via the variant class.
  • The description slot is a raw HTML string — you can include <a> links or <code> spans.
  • Use Alert inside a page's optional error slot rather than always rendering it — pass an empty byte array ([]) when there is no error so the slot renders nothing.

Complete page example

Templates/SystemStatusPage.htmx

<div class="max-w-2xl mx-auto py-10 space-y-4">
  <h1 class="text-2xl font-bold mb-6">System Status</h1>
  $$MaintenanceAlert$$
  $$DatabaseAlert$$
  $$ApiAlert$$
</div>

Templates/SystemStatusPage.htmx.cs

namespace Htmx.ApiDemo.Templates;

public sealed class SystemStatusPage : SystemStatusPageBase
{
    private readonly IHtmxComponent _maintenance;
    private readonly IHtmxComponent _database;
    private readonly IHtmxComponent _api;

    public SystemStatusPage(bool maintenanceScheduled, bool dbDegraded, bool apiOk)
    {
        _maintenance = maintenanceScheduled
            ? new Components.Alert(
                title: "Scheduled maintenance",
                description: "The service will be unavailable on Saturday 00:0002:00 UTC.",
                variant: "default")
            : HtmxEmpty.Instance;

        _database = dbDegraded
            ? new Components.Alert(
                title: "Database degraded",
                description: "Query latency is elevated. Our team is investigating.",
                variant: "destructive")
            : HtmxEmpty.Instance;

        _api = apiOk
            ? new Components.Alert(title: "All systems operational.")
            : HtmxEmpty.Instance;
    }

    protected override void RenderMaintenanceAlert(HtmxRenderContext ctx)
        => _maintenance.Render(ctx.Next());
    protected override void RenderDatabaseAlert(HtmxRenderContext ctx)
        => _database.Render(ctx.Next());
    protected override void RenderApiAlert(HtmxRenderContext ctx)
        => _api.Render(ctx.Next());
}

GET handler

[Handler]
[MapGet("/status")]
public static partial class GetSystemStatusHandler
{
    public record Query();

    private static Task<IResult> HandleAsync(
        Query _,
        HttpContext ctx,
        CancellationToken ct)
    {
        var page = new SystemStatusPage(
            maintenanceScheduled: true,
            dbDegraded: false,
            apiOk: true);
        return ctx.WriteHtmxPage(page, title: "System Status");
    }
}