Sweet Alerts With Go and TailwindCSS
In modern web development, effective user interfaces are key to a compelling digital experience. Among these, the humble website alert plays a critical role in communicating information, confirming actions, or highlighting important messages to users. By combining the powerful backend capabilities of Golang, the seamless client-server interactions provided by HTMX, the intuitive and customizable alert designs from SweetAlert2, and the utility-first styling of TailwindCSS, we can create truly eye-catching and functional alerts.
This tutorial will guide you through integrating these technologies to build visually stunning and highly functional website alerts. This approach merges aesthetic appeal with robust functionality, significantly enhancing the overall user experience of your web applications.
The JavaScript for Our SweetAlert
The core of our alert system lies in a small piece of JavaScript. This script listens for the htmx:confirm
event, which HTMX triggers before sending a request when an element has the hx-confirm
attribute. If the id
of the element initiating the request matches our specified elementID
, we prevent the default HTMX request and instead fire a SweetAlert.
The key to its flexibility is that properties like elementID
, icon
, title
, confirmText
, cancelText
, and bodyText
will all be dynamically passed from our Go template.
document.addEventListener("htmx:confirm", function(e) {
// Check if the ID of the element issuing the HTMX request matches our target ID
if (e.detail.elt.id === elementID) {
e.preventDefault(); // Prevent the default HTMX request from being issued immediately
// Fire the SweetAlert dialog
Swal.fire({
showCancelButton: true, // Show a cancel button (can be parametrized)
icon: icon, // Icon type (e.g., 'warning', 'info', 'success')
title: title, // Main title of the alert
confirmButtonText: confirmText, // Text for the confirmation button
cancelButtonText: cancelText, // Text for the cancel button
text: bodyText, // Main body text of the alert
buttonsStyling: false, // Disable SweetAlert's default button styling
// This allows us to use our own TailwindCSS classes below
customClass: { // Apply custom TailwindCSS classes to various SweetAlert elements
popup: '!bg-base-100 !relative !transform !overflow-hidden !rounded-lg !bg-white !text-left !shadow-xl !transition-all !p-0 !flex !flex-col',
icon: '!m-0 !mx-auto !flex !h-12 !w-12 !flex-shrink-0 !items-center !justify-center !rounded-full !border-0 !bg-red-100 !mt-5 !col-start-1 !col-end-3',
title: '!p-0 !pt-3 !text-center !text-base !font-semibold !leading-6 !text-gray-900 !pl-4 !pr-4 !col-start-1 !col-end-3',
htmlContainer: '!bg-base-100 !mt-2 !m-0 !text-center !text-sm !text-gray-500 !pl-4 !pr-4 !pb-4 !col-start-1 !col-end-3',
actions: '!bg-base-100 !w-full !flex !justify-between !items-center !p-4 !col-start-1 !col-end-3',
confirmButton: 'bg-orange-800 px-4 py-1 text-white rounded-md', // Tailwind for confirm button
cancelButton: 'border border-gray-400 px-4 py-1 rounded-md', // Tailwind for cancel button
},
}).then(function(result) {
// Check if the user confirmed the alert
if (result.isConfirmed) {
e.detail.issueRequest(true); // If confirmed, issue the original HTMX request
}
});
}
});
Explanation of !important
in Tailwind Classes:
You might notice !bg-base-100
, !relative
, etc. The exclamation mark !
prefix in TailwindCSS makes the utility class !important
. SweetAlert2 applies its own inline styles, which have higher specificity than regular Tailwind classes. Using !important
ensures that our Tailwind classes override SweetAlert's default styling, giving us full control over the alert's appearance.
The Templ Component (views/page.templ
)
To integrate this JavaScript and provide a page to test our alert, we'll use a templ
component. templ
is a Go HTML templating language that compiles to Go code, allowing for type-safe and performant HTML rendering.
First, create a views
directory and inside it, a file named page.templ
.
// views/page.templ
package views
import "github.com/a-h/templ" // Import the templ package
// alertScript is a templ script component that renders the JavaScript code
// for our SweetAlert logic. It takes parameters that will be injected into
// the JavaScript to customize the alert's behavior and content.
script alertScript(elementID, icon, title, confirmText, cancelText, bodyText string) {
// The JavaScript code from the "The alert" section above goes here.
// Ensure you replace the placeholder with the actual JS.
// Example:
// document.addEventListener("htmx:confirm", function(e) {
// if (e.detail.elt.id === elementID) {
// e.preventDefault();
// Swal.fire({
// showCancelButton: true,
// icon: icon,
// title: title,
// confirmButtonText: confirmText,
// cancelButtonText: cancelText,
// text: bodyText,
// buttonsStyling: false,
// customClass: {
// // ... your TailwindCSS classes here ...
// },
// }).then(function(result) {
// if (result.isConfirmed) {
// e.detail.issueRequest(true);
// }
// });
// }
// });
}
// Page is the main templ component for our web page.
// It includes the necessary CSS and JavaScript libraries and
// renders a button that triggers our SweetAlert.
templ Page() {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.tailwindcss.com"></script>
<title>Sweet Alerts</title>
</head>
<body>
@alertScript("my-btn", "warning", "Are you sure?", "Yes, delete it!", "No, keep it", "You won't be able to revert this!")
<div class="min-h-screen flex items-center justify-center bg-gray-100">
<button
id="my-btn" // The ID that our JavaScript event listener targets
hx-get="/confirm" // An example HTMX GET request that would be issued on confirmation
hx-confirm="" // This empty hx-confirm tells HTMX to emit htmx:confirm event
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
Show Alert
</button>
</div>
</body>
</html>
}
Important: You need to paste the full JavaScript code from the "The JavaScript for Our SweetAlert" section into the script alertScript(...) { ... }
block in your page.templ
file.
The Entrypoint (main.go
)
Finally, we need our Go application's entrypoint (main.go
). This file will set up a simple HTTP server using the echo
web framework, define a single GET handler to serve our templ
page, and start the server.
First, install echo
and templ
:
go get github.com/labstack/echo/v4
go get github.com/a-h/templ
Now, create your main.go
file:
package main
import (
"log" // For logging fatal errors
"net/http" // Standard HTTP status codes
"sweeter-alerts/views" // Import our templ views package (adjust if your module name differs)
"github.com/a-h/templ" // Templ runtime library
"github.com/labstack/echo/v4" // Echo web framework
)
// main function sets up the Echo server and defines routes.
func main() {
e := echo.New() // Create a new Echo instance
// Define a GET route for the root path ("/")
// When accessed, it will call our PageHandler function.
e.GET("/", PageHandler)
// This is a dummy handler for the hx-get="/confirm" request.
// In a real application, this would perform the action confirmed by the alert.
e.GET("/confirm", func(c echo.Context) error {
// Simulate some action, e.g., deleting a resource
log.Println("Action confirmed! Performing simulated GET request.")
return c.String(http.StatusOK, "Action Confirmed! (This message is from /confirm endpoint)")
})
// Start the Echo server on port 8080. Log any fatal errors.
log.Fatal(e.Start(":8080"))
}
// Render is a helper function to render templ components into an Echo context.
func Render(ctx echo.Context, statusCode int, t templ.Component) error {
ctx.Response().Writer.WriteHeader(statusCode) // Set the HTTP status code
// Set the Content-Type header to HTML. Crucial for HTMX.
ctx.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML)
// Render the templ component to the response writer.
return t.Render(ctx.Request().Context(), ctx.Response().Writer)
}
// PageHandler is the Echo handler function that renders our main views.Page() templ component.
func PageHandler(c echo.Context) error {
return Render(c, http.StatusOK, views.Page())
}
Note on Module Name: The import path sweeter-alerts/views
assumes your Go module name is sweeter-alerts
. If your go.mod
file has a different module name (e.g., github.com/yourusername/yourproject
), please adjust the import path accordingly.
Running the Application
- Save all the files into their respective paths:
main.go
in your project root.views/page.templ
in theviews
directory.
- Open your terminal in the root of your Go project.
- Generate Go code from
templ
files:
This command will createtempl generate
page_templ.go
in yourviews
directory, which is the Go code representation of your HTML template. - Run the application:
go run .
- Open your web browser and navigate to
http://localhost:8080
.
You should see a button. Upon clicking it, you'll be greeted with your beautifully styled SweetAlert dialog, complete with custom TailwindCSS styling. When you confirm, HTMX will then issue the /confirm
request, and you'll see a log in your terminal.
Conclusion
While the alert itself might not be "jaw-dropping" in its current form, you now possess a powerful foundation! You've learned how to seamlessly integrate Go for backend logic, HTMX for dynamic, JavaScript-free interactions, SweetAlert2 for customizable and engaging alert dialogs, and TailwindCSS for precise and efficient styling.
This robust setup empowers you to craft a wide array of visually stunning and highly functional alerts, elevating the user experience of your web applications. The beauty of this approach lies in its maintainability and the minimal amount of custom JavaScript needed for rich interactions.