htmx/www/content/examples/async-auth.md
Christian Tanul ee4ef5f18d
update /patterns & /help page (#3513)
* fix autofocus on mobile search bar

* improve pattern documentation structure and titles

- inline-validation.md → active-validation.md
- bulk-update.md → bulk-actions.md
- delete-row.md → delete-in-place.md
- sortable.md → drag-to-reorder.md
- click-to-edit.md → edit-in-place.md
- value-select.md → linked-selects.md
- reset-user-input.md → reset-on-submit.md
- Merged tabs-hateoas.md and tabs-javascript.md into single tabs.md
- Removed obsolete files:
- file-upload-input.md (merged into file-upload.md)
- web-components.md (content moved to /docs - not a pattern)
- Refreshed titles and descriptions
- Updated icons for better visual consistency
- Disabled interactive demos:
- Commented out {{ demo_environment() }} and demo code blocks in: animations, click-to-load, infinite-scroll, file-upload, bulk-actions, drag-to-reorder, edit-in-place, active-search
- Minor formatting cleanup across multiple pattern files

* update /help page
2025-11-10 19:56:53 -07:00

1.5 KiB

+++ title = "Async Authentication" template = "demo.html" +++

This example shows how to implement an an async auth token flow for htmx.

The technique we will use here will take advantage of the fact that you can delay requests using the htmx:confirm event.

We first have a button that should not issue a request until an auth token has been retrieved:

  <button hx-post="/example" hx-target="next output">
    An htmx-Powered button
  </button>
  <output>
    --
  </output>

Next we will add some scripting to work with an auth promise (returned by a library):

<script>
  // auth is a promise returned by our authentication system

  // await the auth token and store it somewhere
  let authToken = null;
  auth.then((token) => {
    authToken = token
  })
  
  // gate htmx requests on the auth token
  htmx.on("htmx:confirm", (e)=> {
    // if there is no auth token
    if(authToken == null) {
      // stop the regular request from being issued
      e.preventDefault() 
      // only issue it once the auth promise has resolved
      auth.then(() => e.detail.issueRequest()) 
    }
  })

  // add the auth token to the request as a header
  htmx.on("htmx:configRequest", (e)=> {
    e.detail.headers["AUTH"] = authToken
  })
</script>

Here we use a global variable, but you could use localStorage or whatever preferred mechanism you want to communicate the authentication token to the htmx:configRequest event.

With this code in place, htmx will not issue requests until the auth promise has been resolved.