Co-authored-by: Copilot <copilot@github.com>
4.3 KiB
Alert
A coloured callout box that draws the user's attention — like a sticky note placed on top of the page. Use it to show errors, warnings, or helpful information.
Quick example
new Alert(
title: "Heads up",
description: "Your session expires in 5 minutes.")
All the options
public Alert(
string title,
string description = "",
string variant = "default",
string icon = "")
| Parameter | What it does |
|---|---|
title |
The bold heading line — always shown |
description |
A second line of detail below the title — optional |
variant |
"default" (neutral, grey border) or "destructive" (red) |
icon |
A raw SVG string placed to the left of the text — omit for no icon |
Real-world examples
Login error
new Alert(
title: "Sign in failed",
description: "The email or password you entered is incorrect.",
variant: "destructive")
Success confirmation
new Alert(title: "Changes saved successfully.")
Info notice with a link in the description
description is raw HTML, so you can embed links:
new Alert(
title: "Maintenance scheduled",
description: "The system will be offline on Saturday. <a href='/status' class='underline'>View status page</a>.")
Conditional error slot on a form page
A common pattern is to render the alert only when there is something to show. In the page constructor:
// Store empty bytes when there's no error — WriteUtf8 on empty bytes is a no-op
_errorAlertData = string.IsNullOrEmpty(errorMessage)
? []
: new Alert(title: "Error", description: errorMessage, variant: "destructive")
.ToRenderedBytes();
How it works
The alert is a <div role="alert"> — this tells screen readers to announce its content immediately when it appears on the page.
If you pass an icon, it is placed as a direct child SVG. Tailwind's arbitrary selector [&>svg]:absolute positions it at the top-left corner automatically, and [&>svg~*]:pl-7 shifts all the text to the right so nothing overlaps. You do not need any wrapper divs around your SVG.
The icon should be class="h-4 w-4" — larger icons will misalign the text.
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:00–02: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");
}
}