{"id":13770823,"url":"https://github.com/donseba/go-htmx","last_synced_at":"2026-02-01T23:11:15.814Z","repository":{"id":65855038,"uuid":"600389720","full_name":"donseba/go-htmx","owner":"donseba","description":"Seamless HTMX integration in golang applications","archived":false,"fork":false,"pushed_at":"2026-01-09T19:44:48.000Z","size":1772,"stargazers_count":552,"open_issues_count":1,"forks_count":30,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-01-12T20:28:34.483Z","etag":null,"topics":["go-htmx","golang","htmx","hypermedia","webdev","webdevelopment"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/donseba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"donseba","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2023-02-11T10:45:23.000Z","updated_at":"2026-01-11T22:33:51.000Z","dependencies_parsed_at":"2023-03-07T23:00:36.315Z","dependency_job_id":"2ee068a7-3e56-4ba6-afec-d404f46defc1","html_url":"https://github.com/donseba/go-htmx","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/donseba/go-htmx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-htmx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-htmx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-htmx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-htmx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/donseba","download_url":"https://codeload.github.com/donseba/go-htmx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-htmx/sbom","scorecard":{"id":352010,"data":{"date":"2025-08-11","repo":{"name":"github.com/donseba/go-htmx","commit":"dfb38caef19a120ec60cd3534f5d8c625029dde6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.1,"checks":[{"name":"Code-Review","score":3,"reason":"Found 4/11 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: topLevel 'contents' permission set to 'read': .github/workflows/golangci-lint.yml:10","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/donseba/go-htmx/golangci-lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/donseba/go-htmx/golangci-lint.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/donseba/go-htmx/golangci-lint.yml/main?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T08:34:46.380Z","repository_id":65855038,"created_at":"2025-08-18T08:34:46.380Z","updated_at":"2025-08-18T08:34:46.380Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28993985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T23:10:54.274Z","status":"ssl_error","status_checked_at":"2026-02-01T23:10:47.298Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go-htmx","golang","htmx","hypermedia","webdev","webdevelopment"],"created_at":"2024-08-03T17:00:42.554Z","updated_at":"2026-02-01T23:11:15.782Z","avatar_url":"https://github.com/donseba.png","language":"Go","funding_links":["https://github.com/sponsors/donseba"],"categories":["Examples by Back-end"],"sub_categories":["Go"],"readme":"# go-htmx\n**Seamless HTMX integration in golang applications.**\n\n[![GoDoc](https://pkg.go.dev/badge/github.com/donseba/go-htmx?status.svg)](https://pkg.go.dev/github.com/donseba/go-htmx?tab=doc)\n[![GoMod](https://img.shields.io/github/go-mod/go-version/donseba/go-htmx)](https://github.com/donseba/go-htmx)\n[![Size](https://img.shields.io/github/languages/code-size/donseba/go-htmx)](https://github.com/donseba/go-htmx)\n[![License](https://img.shields.io/github/license/donseba/go-htmx)](./LICENSE)\n[![Stars](https://img.shields.io/github/stars/donseba/go-htmx)](https://github.com/donseba/go-htmx/stargazers)\n[![Go Report Card](https://goreportcard.com/badge/github.com/donseba/go-htmx)](https://goreportcard.com/report/github.com/donseba/go-htmx)\n\n## Description\n\nThis repository contains the htmx Go package, designed to enhance server-side handling of HTML generated with the [HTMX library](https://htmx.org/). \nIt provides a set of tools to easily manage swap behaviors, trigger configurations, and other HTMX-related functionalities in a Go server environment.\n\n## Disclaimer\nThis package is built around the specific need to be able to work with HTMX in a Go environment.\nAll functionality found in this repository has a certain use case in various projects that I have worked on.\n\n- Design decisions are documented in the [DESIGN_DECISIONS.md](https://github.com/donseba/go-htmx/blob/main/DESIGN_DECISIONS.md) file.\n- Locality of Behavior is documented in the [LOB.md](https://github.com/donseba/go-htmx/blob/main/LOB.md) file.\n\n## Features\n\n- **Component Rendering**: Render (partial) components in response to HTMX requests, enhancing user experience and performance.\n- **Swap Configuration**: Configure swap behaviors for HTMX responses, including style, timing, and scrolling.\n- **Trigger Management**: Define and manage triggers for HTMX events, supporting both simple and detailed triggers.\n- **Middleware Support**: Integrate HTMX seamlessly with Go middleware for easy HTMX header configuration.\n- **io.Writer Support**: The HTMX handler implements the io.Writer interface for easy integration with existing Go code.\n\n---\n\n## Getting Started\n\n### Installation\n\nTo install the htmx package, use the following command:\n\n```sh\ngo get -u github.com/donseba/go-htmx\n```\n\n### Usage\n\ninitialize the htmx service like so : \n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/donseba/go-htmx\"\n)\n\ntype App struct {\n\thtmx *htmx.HTMX\n}\n\nfunc main() {\n\t// new app with htmx instance\n\tapp := \u0026App{\n\t\thtmx: htmx.New(),\n\t}\n\n\tmux := http.NewServeMux()\n\t// wrap the htmx example middleware around the http handler\n\tmux.HandleFunc(\"/\", app.Home)\n\n\terr := http.ListenAndServe(\":3000\", mux)\n\tlog.Fatal(err)\n}\n\nfunc (a *App) Home(w http.ResponseWriter, r *http.Request) {\n\t// initiate a new htmx handler\n\th := a.htmx.NewHandler(w, r)\n\n\t// check if the request is a htmx request\n\tif h.IsHxRequest() {\n\t\t// do something\n\t}\n\t\n\t// check if the request is boosted\n\tif h.IsHxBoosted() {\n\t\t// do something\n\t}\n\t\n\t// check if the request is a history restore request\n\tif h.IsHxHistoryRestoreRequest() { \n\t\t// do something \n\t}\n\t\n\t// check if the request is a prompt request\n\tif h.RenderPartial() { \n\t\t// do something\n\t}\n\t\t\n\t// set the headers for the response, see docs for more options\n\th.PushURL(\"http://push.url\")\n\th.ReTarget(\"#ReTarged\")\n\n\t// write the output like you normally do.\n\t// check the inspector tool in the browser to see that the headers are set.\n\t_, _ = h.Write([]byte(\"OK\"))\n}\n```\n\n### HTMX Request Checks\n\nThe htmx package provides several functions to determine the nature of HTMX requests in your Go application. These checks allow you to tailor the server's response based on specific HTMX-related conditions.\n\n#### IsHxRequest\n\nThis function checks if the incoming HTTP request is made by HTMX.\n\n```go\nfunc (h *Handler) IsHxRequest() bool\n```\n- **Usage**: Use this check to identify requests initiated by HTMX and differentiate them from standard HTTP requests.\n- **Example**: Applying special handling or returning partial HTML snippets in response to an HTMX request.\n\n#### IsHxBoosted\n\nDetermines if the HTMX request is boosted, which typically indicates an enhancement of the user experience with HTMX's AJAX capabilities.\n\n```go\nfunc (h *Handler) IsHxBoosted() bool\n```\n- **Usage**: Useful in scenarios where you want to provide an enriched or different response for boosted requests.\n- **Example**: Loading additional data or scripts that are specifically meant for AJAX-enhanced browsing.\n\n#### IsHxHistoryRestoreRequest\n\nChecks if the HTMX request is a history restore request. This type of request occurs when HTMX is restoring content from the browser's history.\n\n```go\nfunc (h *Handler) IsHxHistoryRestoreRequest() bool\n```\n- **Usage**: Helps in handling scenarios where users navigate using browser history, and the application needs to restore previous states or content.\n- **Example**: Resetting certain states or re-fetching data that was previously displayed.\n\n#### RenderPartial\n\nThis function returns true for HTMX requests that are either standard or boosted, as long as they are not history restore requests. It is a combined check used to determine if a partial render is appropriate.\n\n```go\nfunc (h *Handler) RenderPartial() bool\n```\n- **Usage**: Ideal for deciding when to render partial HTML content, which is a common pattern in applications using HTMX.\n- **Example**: Returning only the necessary HTML fragments to update a part of the webpage, instead of rendering the entire page.\n\n### Swapping\nSwapping is a way to replace the content of a dom element with the content of the response.\nThis is done by setting the `HX-Swap` header to the id of the dom element you want to swap.\n\n```go\nfunc (c *Controller) Route(w http.ResponseWriter, r *http.Request) {\n\t// initiate a new htmx handler \n\th := a.htmx.NewHandler(w, r)\n\t\n\t// Example usage of Swap \n\tswap := htmx.NewSwap().Swap(time.Second * 2).ScrollBottom() \n\t\n\th.ReSwapWithObject(swap)\n\t\n\t_, _ = h.Write([]byte(\"your content\"))\n}\n```\n\n### Trigger Events \nTrigger events are a way to trigger events on the dom element.\nThis is done by setting the `HX-Trigger` header to the event you want to trigger.\n\n```go\nfunc (c *Controller) Route(w http.ResponseWriter, r *http.Request) {\n\t// initiate a new htmx handler \n\th := a.htmx.NewHandler(w, r)\n\t\n\t// Example usage of Swap \n\ttrigger := htmx.NewTrigger().AddEvent(\"event1\").AddEventDetailed(\"event2\", \"Hello, World!\") \n\t\n\th.TriggerWithObject(trigger)\n\t// or \n\th.TriggerAfterSettleWithObject(trigger)\n\t// or\n\th.TriggerAfterSwapWithObject(trigger)\n\t\n\t_, _ = h.Write([]byte(\"your content\"))\n}\n```\n\n---\n\n## utility methods \n\n### Notification handling \nComprehensive support for triggering various types of notifications within your Go applications, enhancing user interaction and feedback. The package provides a set of functions to easily manage and trigger different notification types such as success, info, warning, error, and custom notifications.\nAvailable Notification Types\n\n- **Success**: Use for positive confirmation messages.\n- **Info**: Ideal for informational messages.\n- **Warning**: Suitable for cautionary messages.\n- **Error**: Use for error or failure messages.\n- **Custom**: Allows for defining your own notification types.\n\n### Usage\n\nTriggering notifications is straightforward. Here are some examples demonstrating how to use each function:\n\n```go\nfunc (h *Handler) MyHandlerFunc(w http.ResponseWriter, r *http.Request) {\n\t// Trigger a success notification \n\th.TriggerSuccess(\"Operation completed successfully\")\n\t\n\t// Trigger an info notification \n\th.TriggerInfo(\"This is an informational message\")\n\n\t// Trigger a warning notification \n\th.TriggerWarning(\"Warning: Please check your input\")\n\t\n\t// Trigger an error notification \n\th.TriggerError(\"Error: Unable to process your request\")\n\t\n\t// Trigger a custom notification \n\th.TriggerCustom(\"customType\", \"This is a custom notification\", nil)\n}\n```\n\n### Notification Levels\n\nThe htmx package provides built-in support for four primary notification levels, each representing a different type of message:\n\n- `success`: Indicates successful completion of an operation.\n- `info`: Conveys informational messages.\n- `warning`: Alerts about potential issues or cautionary information.\n- `error`: Signals an error or problem that occurred.\n\nEach notification type is designed to communicate specific kinds of messages clearly and effectively in your application's user interface.\n### Triggering Custom Notifications\n\nIn addition to these standard notification levels, the htmx package also allows for custom notifications using the TriggerCustom method. This method provides the flexibility to define a custom level and message, catering to unique notification requirements.\n\n```go\nfunc (h *Handler) MyHandlerFunc(w http.ResponseWriter, r *http.Request) {\n\t// Trigger standard notifications \n\th.TriggerSuccess(\"Operation successful\")\n\th.TriggerInfo(\"This is for your information\")\n\th.TriggerWarning(\"Please be cautious\")\n\th.TriggerError(\"An error has occurred\")\n\t\n\t// Trigger a custom notification \n\th.TriggerCustom(\"customLevel\", \"This is a custom notification\")\n}\n```\nThe TriggerCustom method enables you to specify a custom level (e.g., \"customLevel\") and an accompanying message. This method is particularly useful when you need to go beyond the predefined notification types and implement a notification system that aligns closely with your application's specific context or branding.\n\n### Advanced Usage with Custom Variables\n\nYou can also pass additional data with your notifications. Here's an example:\n\n```go\nfunc (h *Handler) MyHandlerFunc(w http.ResponseWriter, r *http.Request) {\n\tcustomData := map[string]string{\"key1\": \"value1\", \"key2\": \"value2\"}\n\th.TriggerInfo(\"User logged in\", customData)\n}\n```\n\n### the HTMX part \n\nplease refer to the [htmx documentation](https://htmx.org/headers/hx-trigger/) regarding event triggering. and the example [confirmation UI](https://htmx.org/examples/confirm/)\n\n`HX-Trigger: {\"showMessage\":{\"level\" : \"info\", \"message\" : \"Here Is A Message\"}}`\n\nAnd handle this event like so:\n\n```js \ndocument.body.addEventListener(\"showMessage\", function(evt){\n    if(evt.detail.level === \"info\"){\n        alert(evt.detail.message);\n    }\n})\n```\nEach property of the JSON object on the right hand side will be copied onto the details object for the event.\n\n### Customizing Notification Event Names\n\nIn addition to the standard notification types, the htmx package allows you to customize the event name used for triggering notifications. This is done by modifying the htmx.DefaultNotificationKey. Changing this key will affect the event name in the HTMX trigger, allowing you to tailor it to specific needs or naming conventions of your application.\nSetting a Custom Notification Key\n\nBefore triggering notifications, you can set a custom event name as follows:\n\n```go\nhtmx.DefaultNotificationKey = \"myCustomEventName\"\n```\n\n---\n\n## Component Rendering\n\nThe components documentation can be found in the [COMPONENTS.md](https://github.com/donseba/go-htmx/blob/main/COMPONENTS.md) file.\n\n---\n\n## Middleware\nThe htmx package is designed for versatile integration into Go applications, providing support both with and without the use of middleware. Below, we showcase two examples demonstrating the package's usage in scenarios involving middleware.\n\n### standard mux middleware example:\n\n```go\nfunc MiddleWare(next http.Handler) http.Handler {\n    fn := func(w http.ResponseWriter, r *http.Request) {\n        ctx := r.Context()\n\n        hxh := htmx.HxRequestHeaderFromRequest(c.Request())\n\n        ctx = context.WithValue(ctx, htmx.ContextRequestHeader, hxh)\n\n        next.ServeHTTP(w, r.WithContext(ctx))\n    }\n    return http.HandlerFunc(fn)\n}\n```\n\n**NOTE** : The `MiddleWare` function is deprecated but will remain as a reference for users who prefer to use it.\nIt would be best to create your own middleware function that fits your application's requirements.\n\n### echo middleware example: \n\n```go\nfunc MiddleWare(next echo.HandlerFunc) echo.HandlerFunc {\n\treturn func(c echo.Context) error {\n\t\tctx := c.Request().Context()\n\n\t\thxh := htmx.HxRequestHeaderFromRequest(c.Request())\n\n\t\tctx = context.WithValue(ctx, htmx.ContextRequestHeader, hxh)\n\n\t\tc.SetRequest(c.Request().WithContext(ctx))\n\n\t\treturn next(c)\n\t}\n}\n```\n\n--- \n\n## Custom logger \n\nIn case you want to use a custom logger, like zap, you can inject them into the slog package like so:\n\n```go\nimport (\n    \"go.uber.org/zap\"\n    \"go.uber.org/zap/exp/zapslog\"\n)\n\nfunc main() {\n    // create a new htmx instance with the logger\n    app := \u0026App{\n        htmx: htmx.New(),\n    }\n\n    zapLogger := zap.Must(zap.NewProduction())\n    defer zapLogger.Sync()\n    \n    logger := slog.New(zapslog.NewHandler(zapLogger.Core(), nil))\n    \n    app.htmx.SetLog(logger)\n}\n```\n\n--- \n\n## Usage in other frameworks\nThe htmx package is designed to be versatile and can be used in various Go web frameworks. \nBelow are examples of how to use the package in two popular Go web frameworks: Echo and Gin.\n\n### echo\n\n```go\nfunc (c *controller) Hello(c echo.Context) error {\n    // initiate a new htmx handler \n    h := c.app.htmx.NewHandler(c.Response(), c.Request())\n    \n    // Example usage of Swap \n    swap := htmx.NewSwap().Swap(time.Second * 2).ScrollBottom() \n    \n    h.ReSwapWithObject(swap)\n    \n    _, _ = h.Write([]byte(\"your content\"))\n}\n```\n\n### gin\n\n```go\nfunc (c *controller) Hello(c *gin.Context) {\n    // initiate a new htmx handler \n    h := c.app.htmx.NewHandler(c.Writer, c.Request)\n    \n    // Example usage of Swap \n    swap := htmx.NewSwap().Swap(time.Second * 2).ScrollBottom() \n    \n    h.ReSwapWithObject(swap)\n    \n    _, _ = h.Write([]byte(\"your content\"))\n}\n```\n\n--- \n\n## Server Sent Events (SSE)\n\nThe htmx package provides support for Server-Sent Events (SSE) in Go applications. This feature allows you to send real-time updates from the server to the client, enabling live updates and notifications in your web application.\n\nYou can read about this feature in the [htmx documentation](https://htmx.org/extensions/server-sent-events/) and the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).\n\n### Usage\n\nCreate an endpoint in your Go application to handle SSE requests. (see the example for a better understanding)\n```go\nfunc (a *App) SSE(w http.ResponseWriter, r *http.Request) {\n    cl := \u0026client{\n        id: uuid.New().String()\n        ch: make(chan *htmx.SSEMessage),\n    }\n    \n    sseManager.Handle(w, cl)\n}\n```\n\nTo send a message to the client, you can use the `Send` method on the `SSEManager` object.\n\n```go\ngo func() {\n    for {\n        // Send a message every seconds \n        time.Sleep(1 * time.Second) \n\t\t\t\n        msg := sse.\n            NewMessage(fmt.Sprintf(\"The current time is: %v\", time.Now().Format(time.RFC850))).\n            WithEvent(\"Time\")\n            \n        sseManager.Send()\n    }\n}()\n``` \n\n### HTMX helper methods \n\nThere are two helper methods to simplify the usage of SSE in your HTMX application.\nThe Manager is created in the background and is not exposed to the user.\nYou can change the default worker pool size by setting the `htmx.DefaultSSEWorkerPoolSize` variable.\n\n```go\n\n// SSEHandler handles the server-sent events. this is a shortcut and is not the preferred way to handle sse.\nfunc (h *HTMX) SSEHandler(w http.ResponseWriter, cl sse.Client)\n\n// SSESend sends a message to all connected clients.\nfunc (h *HTMX) SSESend(message sse.Envelope)\n\n```\n--- \n\n## Contributing\n\nContributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.\n\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag \"enhancement\".\n\n**Remember to give the project a star! Thanks again!**\n\n1. Fork this repo\n2. Create a new branch with `main` as the base branch\n3. Add your changes\n4. Raise a Pull Request\n\n--- \n\n## License\n\nDistributed under the MIT License. See `LICENSE` for more information.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonseba%2Fgo-htmx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonseba%2Fgo-htmx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonseba%2Fgo-htmx/lists"}