### Out-of-Band Swap Example
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Demonstrates an out-of-band swap using `hx-swap-oob` to update a notification element.
```html
Notification
```
--------------------------------
### Thymeleaf Processing for hx-get
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use `hx:get` for Thymeleaf processing to dynamically generate the URL. The rendered output will use a static `hx-get` attribute. Ensure correct usage of Thymeleaf's `@` and `${}` syntax for URL generation.
```html
Load user details
```
```html
Load user details
```
--------------------------------
### Multiple Values in hx-vals with Thymeleaf
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
This example shows how to include multiple key-value pairs within the `hx:vals` attribute using Thymeleaf's inline map syntax, allowing for the submission of several parameters with the AJAX request.
```html
```
--------------------------------
### Set Response Headers in Exception Handlers with Annotations
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Apply HTMX annotations directly to @ExceptionHandler methods to set response headers. This example uses @HxRetarget to specify an element to retarget on the client-side.
```java
@ExceptionHandler(Exception.class)
@HxRetarget("#error-message")
public String handleError(Exception ex) {
return "error";
}
```
--------------------------------
### Handle HTMX Requests in Exception Handlers
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use HtmxRequest and HtmxResponse as method arguments in @ExceptionHandler methods to conditionally modify the response based on whether the request is an HTMX request. This example retargets an error message element.
```java
@ExceptionHandler(Exception.class)
public String handleError(Exception ex, HtmxRequest htmxRequest, HtmxResponse htmxResponse) {
if (htmxRequest.isHtmxRequest()) {
htmxResponse.setRetarget("#error-message");
}
return "error";
}
```
--------------------------------
### Inline Map Support for hx-vals in Thymeleaf
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
The `hx:vals` attribute supports inline maps in Thymeleaf, simplifying the creation of JSON strings for request parameters. This example demonstrates adding a single key-value pair to the request parameters.
```html
```
```html
```
--------------------------------
### Combine Response Behavior Annotations
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Demonstrates how to combine @HxRetarget, @HxReselect, and @HxReswap annotations to precisely control where and how the response content is updated.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxReselect;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxReswap;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRetarget;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class SwapController {
// Combine retarget, reselect, and reswap
@HxRequest
@HxRetarget("#error-container")
@HxReselect(".error-message")
@HxReswap(HxSwapType.BEFORE_END)
@PostMapping("/validate")
public String validateForm() {
return "forms/errors";
}
}
```
--------------------------------
### Configure Boosted Redirect Strategy for HTMX
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Implement a boosted redirect strategy to preserve HTMX's HX-Boost behavior during authentication success. This ensures that the HX-Boosted header is included in the subsequent request, maintaining the AJAX experience.
```java
import io.github.wimdeblauwe.htmx.spring.boot.security.HxLocationBoostedRedirectStrategy;
import io.github.wimdeblauwe.htmx.spring.boot.security.HxLocationRedirectAuthenticationSuccessHandler;
@Configuration
public class BoostedSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// Use boosted redirect strategy to include HX-Boosted header in new request
var boostedStrategy = new HxLocationBoostedRedirectStrategy();
return http
.formLogin(login -> login
.successHandler(new HxLocationRedirectAuthenticationSuccessHandler(
"/dashboard", boostedStrategy))
)
.build();
}
}
```
--------------------------------
### Configure HxLocationRedirect Handlers
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Integrate HxLocationRedirect handlers for authentication and logout success/failure to leverage htmx's HX-Location header for redirects.
```java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// probably some other configurations here
return http
.formLogin(login -> login
.failureHandler(new HxLocationRedirectAuthenticationFailureHandler("/login?failure"))
.successHandler(new HxLocationRedirectAuthenticationSuccessHandler("/home?login"))
).logout(logout -> logout
.logoutSuccessHandler(new HxLocationRedirectLogoutSuccessHandler("/home?logout"))
).exceptionHandling(handler -> handler
.authenticationEntryPoint(new HxLocationRedirectAuthenticationEntryPoint("/login?unauthorized"))
.accessDeniedHandler(new HxLocationRedirectAccessDeniedHandler("/error?forbidden"))
).build();
}
```
--------------------------------
### Configure Htmx Swap Behavior
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use HtmxReswap to define how htmx swaps content. Options include beforeEnd, afterBegin, outerHtml, delete, innerHtml, none, and custom configurations for timing, scrolling, and view transitions.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxReswap;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxResponse;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.time.Duration;
@Controller
public class ContentController {
@HxRequest
@GetMapping("/content/append")
public String appendContent(HtmxResponse htmxResponse) {
// Insert after last child of target
htmxResponse.setReswap(HtmxReswap.beforeEnd());
return "content/item";
}
@HxRequest
@GetMapping("/content/prepend")
public String prependContent(HtmxResponse htmxResponse) {
// Insert before first child of target
htmxResponse.setReswap(HtmxReswap.afterBegin());
return "content/item";
}
@HxRequest
@GetMapping("/content/replace")
public String replaceContent(HtmxResponse htmxResponse) {
// Replace entire target element
htmxResponse.setReswap(HtmxReswap.outerHtml());
return "content/replacement";
}
@HxRequest
@GetMapping("/content/delete")
public String deleteContent(HtmxResponse htmxResponse) {
// Delete target element regardless of response
htmxResponse.setReswap(HtmxReswap.delete());
return "content/empty";
}
@HxRequest
@GetMapping("/content/animated")
public String animatedContent(HtmxResponse htmxResponse) {
// Full configuration with timing and scrolling
htmxResponse.setReswap(HtmxReswap.innerHtml()
.swap(Duration.ofMillis(500)) // Wait before swap
.settle(Duration.ofMillis(300)) // Wait after swap
.scroll(HtmxReswap.Position.TOP) // Scroll target to top
.scrollTarget("#scroll-container") // Custom scroll target
.show(HtmxReswap.Position.BOTTOM) // Show element at bottom
.showTarget("#viewport") // Custom show target
.focusScroll(true) // Auto-scroll to focused input
.transition()); // Enable View Transitions API
return "content/animated";
}
@HxRequest
@GetMapping("/content/none")
public String noSwapContent(HtmxResponse htmxResponse) {
// Don't swap but still process out-of-band items
htmxResponse.setReswap(HtmxReswap.none());
return "content/oob-only";
}
}
```
--------------------------------
### Render Multiple HTML Fragments with Collection
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Return multiple HTML fragments by providing a Collection of ModelAndView objects. This approach is an alternative to FragmentsRendering for handling Out-of-Band Swaps in HTMX. Requires @HxRequest.
```java
@HxRequest
@GetMapping("/users")
public Collection users() {
return List.of(
new ModelAndView("users/list", Map.of("users", userRepository.findAll())),
new ModelAndView("users/count", Map.of("count", userRepository.count()))
);
}
```
--------------------------------
### Static URL with HTMX Attribute
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
For static URLs, use the standard `hx-` prefix for htmx attributes.
```html
```
--------------------------------
### Render Multiple HTML Fragments with FragmentsRendering
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Return multiple HTML fragments from a controller method using FragmentsRendering. This is useful for Out-of-Band Swaps in HTMX. Requires @HxRequest.
```java
@HxRequest
@GetMapping("/users")
public View users(Model model) {
model.addAttribute("users", userRepository.findAll());
model.addAttribute("count", userRepository.count());
return FragmentsRendering
.with("users/list")
.fragment("users/count")
.build();
}
```
--------------------------------
### Set New Release Version in pom.xml
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use this Maven command to update the pom.xml file with the new release version. Ensure to replace with the actual version number.
```bash
mvn versions:set -DgenerateBackupPoms=false -DnewVersion=
```
--------------------------------
### Configure HxRefreshHeaderAuthenticationEntryPoint
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Add HxRefreshHeaderAuthenticationEntryPoint to your security configuration to force a full page refresh on authentication failure when using htmx.
```java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// probably some other configurations here
var entryPoint = new HxRefreshHeaderAuthenticationEntryPoint();
var requestMatcher = new RequestHeaderRequestMatcher("HX-Request");
http.exceptionHandling(configurer -> configurer.defaultAuthenticationEntryPointFor(entryPoint, requestMatcher));
return http.build();
}
```
--------------------------------
### Return Multiple HTML Fragments with FragmentsRendering
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use FragmentsRendering to return multiple HTML fragments for out-of-band swaps in HTMX requests. This is useful for updating multiple sections of a page simultaneously. Ensure the `HxRequest` annotation is present.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.FragmentsRendering;
import java.util.List;
import java.util.Map;
@Controller
public class FragmentController {
@HxRequest
@GetMapping("/users/list")
public View listUsers(Model model) {
model.addAttribute("users", userRepository.findAll());
model.addAttribute("count", userRepository.count());
// Return multiple fragments for out-of-band swaps
return FragmentsRendering
.with("users/list") // Main content
.fragment("users/count") // OOB fragment
.fragment("users/pagination") // Another OOB fragment
.build();
}
// With Thymeleaf markup selectors
@HxRequest
@GetMapping("/dashboard")
public View dashboard(Model model) {
model.addAttribute("stats", statsService.getStats());
model.addAttribute("notifications", notificationService.getRecent());
return FragmentsRendering
.with("dashboard :: stats") // Select specific fragment
.fragment("dashboard :: notifications")
.fragment("dashboard :: sidebar")
.build();
}
// Alternative using Collection
@HxRequest
@PostMapping("/cart/update")
public Collection updateCart() {
return List.of(
new ModelAndView("cart/items", Map.of("items", cartService.getItems())),
new ModelAndView("cart/total", Map.of("total", cartService.getTotal())),
new ModelAndView("header :: cart-badge", Map.of("count", cartService.getItemCount()))
);
}
}
```
--------------------------------
### Configure HTMX-Friendly Security Handlers in Spring Boot
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Set up Spring Security to use HTMX-compatible handlers for authentication and logout. This configuration replaces standard HTTP redirects with HX-Location headers for smoother AJAX navigation. Ensure necessary imports are present.
```java
import io.github.wimdeblauwe.htmx.spring.boot.security.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/register").permitAll()
.anyRequest().authenticated()
)
.formLogin(login -> login
.loginPage("/login")
// Htmx-friendly redirect on authentication failure
.failureHandler(new HxLocationRedirectAuthenticationFailureHandler("/login?error"))
// Htmx-friendly redirect on authentication success
.successHandler(new HxLocationRedirectAuthenticationSuccessHandler("/dashboard"))
)
.logout(logout -> logout
// Htmx-friendly redirect on logout
.logoutSuccessHandler(new HxLocationRedirectLogoutSuccessHandler("/login?logout"))
)
.exceptionHandling(handler -> handler
// Htmx-friendly redirect on unauthorized access
.authenticationEntryPoint(new HxLocationRedirectAuthenticationEntryPoint("/login"))
// Htmx-friendly redirect on access denied
.accessDeniedHandler(new HxLocationRedirectAccessDeniedHandler("/error/403"))
)
.build();
}
// Alternative: Force full page refresh on auth failure
@Bean
public SecurityFilterChain refreshOnAuthFailure(HttpSecurity http) throws Exception {
var entryPoint = new HxRefreshHeaderAuthenticationEntryPoint();
var htmxRequestMatcher = new RequestHeaderRequestMatcher("HX-Request");
return http
.exceptionHandling(handler -> handler
.defaultAuthenticationEntryPointFor(entryPoint, htmxRequestMatcher)
)
.build();
}
}
```
--------------------------------
### Set htmx Response Headers with HtmxResponse and Views
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use HtmxResponse as a controller argument to set most htmx response headers. For control flow headers like HX-Redirect, use specific Views such as HtmxRedirectView or special view name prefixes like 'redirect:htmx:/path'.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxResponse;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.validation.BindingResult;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.validation.Valid;
@HxRequest
@PostMapping("/user/{id}")
public String user(@PathVariable Long id, @ModelAttribute @Valid UserForm form,
BindingResult bindingResult, RedirectAttributes redirectAttributes,
HtmxResponse htmxResponse) {
if (bindingResult.hasErrors()) {
return "user/form";
}
// update user ...
redirectAttributes.addFlashAttribute("successMessage", "User has been successfully updated.");
htmxResponse.addTrigger("user-updated");
return "redirect:htmx:/user/list";
}
```
--------------------------------
### Render Multiple Thymeleaf Fragments with Collection
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Alternatively, return a Collection of ModelAndView objects to render multiple Thymeleaf fragments, each with its own model data.
```java
@HxRequest
@GetMapping("/users")
public Collection test() {
return List.of(
new ModelAndView("users :: list", Map.of("users", userRepository.findAll())),
new ModelAndView("users :: count", Map.of("count", userRepository.count()))
);
}
```
--------------------------------
### Push Request URL to Browser History with @HxPushUrl
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use @HxPushUrl to add the request URL to the browser's history. This is useful for navigation where each request should create a new history entry.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxValue;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxPushUrl;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class NavigationController {
// Push the request URL to browser history
@HxRequest
@HxPushUrl
@GetMapping("/products")
public String listProducts() {
return "products/list";
}
// Push a custom URL to browser history
@HxRequest
@HxPushUrl("/products/featured")
@GetMapping("/products/load-featured")
public String loadFeatured() {
return "products/featured";
}
// Disable URL pushing even if hx-push-url is set on element
@HxRequest
@HxPushUrl(HtmxValue.FALSE)
@GetMapping("/products/preview")
public String previewProduct() {
return "products/preview";
}
}
```
--------------------------------
### Dynamic Values with hx:vals
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
The `hx:vals` attribute supports inline maps for passing dynamic data, useful for search or submission parameters.
```html
```
--------------------------------
### Setting Htmx Response Headers with HtmxResponse
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Utilize HtmxResponse as a controller method argument to dynamically set htmx response headers. This allows for actions such as triggering client-side events, manipulating browser history URLs, retargeting elements, and configuring swap behaviors.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxResponse;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxReswap;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ItemController {
@HxRequest
@PostMapping("/items")
public String createItem(@RequestParam String name, HtmxResponse htmxResponse) {
// Trigger a client-side event
htmxResponse.addTrigger("itemCreated");
// Trigger event with detail data
htmxResponse.addTrigger("showMessage", Map.of(
"level", "success",
"message", "Item created successfully"
));
// Trigger events at different lifecycle stages
htmxResponse.addTriggerAfterSettle("refreshSidebar");
htmxResponse.addTriggerAfterSwap("scrollToTop");
// Push a new URL to browser history
htmxResponse.setPushUrl("/items?created=true");
// Or replace the current URL
htmxResponse.setReplaceUrl("/items/" + itemId);
// Prevent history update entirely
htmxResponse.preventHistoryUpdate();
// Change the target element for the swap
htmxResponse.setRetarget("#item-list");
// Select which part of the response to swap
htmxResponse.setReselect("#new-item");
// Configure swap behavior
htmxResponse.setReswap(HtmxReswap.innerHtml()
.swap(Duration.ofMillis(100))
.settle(Duration.ofMillis(200))
.scroll(HtmxReswap.Position.TOP)
.transition());
return "items/list";
}
}
```
--------------------------------
### Conditional Rendering Based on Htmx Request
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Conditionally render a full page or a Thymeleaf fragment based on whether the request is an htmx request and if it's boosted.
```java
@GetMapping("/login")
String login(HtmxRequest request) {
return request.isHtmxRequest() && !request.isBoosted()
? "pages/login :: content"
: "pages/login";
}
```
--------------------------------
### Trigger Client-Side Events with @HxTrigger
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use @HxTrigger, @HxTriggerAfterSettle, and @HxTriggerAfterSwap to dispatch client-side events at specific points in the htmx request lifecycle. Events can be single strings or arrays of strings.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxTrigger;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxTriggerAfterSettle;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxTriggerAfterSwap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@Controller
public class NotificationController {
// Trigger single event immediately when response is received
@HxRequest
@HxTrigger("userUpdated")
@PostMapping("/users/{id}")
public String updateUser() {
return "users/detail";
}
// Trigger multiple events
@HxRequest
@HxTrigger({"itemDeleted", "refreshList", "showNotification"})
@DeleteMapping("/items/{id}")
public String deleteItem() {
return "items/empty";
}
// Trigger after the settling step (CSS transitions complete)
@HxRequest
@HxTriggerAfterSettle("animationComplete")
@PutMapping("/animate")
public String animateContent() {
return "content/animated";
}
// Trigger after the swap step
@HxRequest
@HxTriggerAfterSwap("contentSwapped")
@PostMapping("/content")
public String swapContent() {
return "content/new";
}
// Combine all trigger types
@HxRequest
@HxTrigger("operationStarted")
@HxTriggerAfterSettle("operationSettled")
@HxTriggerAfterSwap("operationComplete")
@PostMapping("/complex-operation")
public String complexOperation() {
return "operation/result";
}
}
```
--------------------------------
### Add Maven Dependency for HTMX Spring Boot
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Include this dependency for core functionality, including annotations and helper classes for handling htmx requests and responses.
```xml
io.github.wimdeblauwehtmx-spring-boot5.1.0
```
--------------------------------
### Conditional View Rendering for HTMX Requests
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Conditionally render a fragment for HTMX requests that are not boosted, and the full page otherwise. This allows for optimized responses in HTMX flows.
```java
import io.github.wimdeblauwe.htmx.spring.boot.HtmxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LoginController {
@GetMapping("/login")
public String login(HtmxRequest request) {
// Return fragment for non-boosted htmx requests, full page otherwise
return request.isHtmxRequest() && !request.isBoosted()
? "pages/login :: content"
: "pages/login";
}
}
```
--------------------------------
### Add htmx-spring-boot-thymeleaf Maven Dependency
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Include this dependency to enable the Thymeleaf dialect for working with htmx attributes in your templates.
```xml
io.github.wimdeblauwehtmx-spring-boot-thymeleafLATEST_VERSION_HERE
```
--------------------------------
### Standalone Element with CSRF
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Standalone elements performing unsafe HTTP methods (POST, PUT, PATCH, DELETE) also benefit from automatic CSRF token injection.
```html
Log out
```
```html
```
--------------------------------
### HtmxRedirectView for Client-Side Redirects
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use HtmxRedirectView to send an HX-Redirect header for full page redirects. It supports Spring's RedirectView features like flash attributes.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxRedirectView;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
public class AuthController {
@HxRequest
@PostMapping("/login")
public View login(RedirectAttributes redirectAttributes) {
// Perform authentication...
// Add flash attributes for the redirect target
redirectAttributes.addFlashAttribute("message", "Welcome back!");
// Return htmx redirect view
return new HtmxRedirectView("/dashboard");
}
@HxRequest
@PostMapping("/logout")
public View logout() {
// Context-relative redirect (prepends context path)
return new HtmxRedirectView("/login", true);
}
@HxRequest
@PostMapping("/register")
public View register(RedirectAttributes redirectAttributes) {
// Redirect with model attributes as query parameters
return new HtmxRedirectView("/welcome", true, true);
}
// Using view name prefix instead of View object
@HxRequest
@PostMapping("/submit")
public String submitForm(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("success", true);
return "redirect:htmx:/confirmation";
}
}
```
--------------------------------
### Replace Current URL with @HxReplaceUrl
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Utilize @HxReplaceUrl to replace the current URL in the browser's history instead of pushing a new one. This is suitable for actions that update the current view without creating a new history state.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxValue;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxReplaceUrl;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Controller
public class NavigationController {
// Replace current URL instead of pushing new one
@HxRequest
@HxReplaceUrl
@GetMapping("/products/{id}")
public String viewProduct(@PathVariable Long id) {
return "products/detail";
}
// Replace with custom URL
@HxRequest
@HxReplaceUrl("/products/current")
@GetMapping("/products/latest")
public String latestProduct() {
return "products/detail";
}
// Prevent URL replacement
@HxRequest
@HxReplaceUrl(HtmxValue.FALSE)
@GetMapping("/products/modal")
public String productModal() {
return "products/modal";
}
}
```
--------------------------------
### HtmxLocationRedirectView for AJAX Redirects
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Employ HtmxLocationRedirectView for AJAX redirects without a full page reload, utilizing the HX-Location header. It allows configuration of target element, swap method, select, source, event, headers, values, and handler.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxLocationRedirectView;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.View;
import java.util.Map;
@Controller
public class SpaController {
@HxRequest
@PostMapping("/navigate")
public View navigate() {
// Simple location redirect
return new HtmxLocationRedirectView("/new-page");
}
@HxRequest
@PostMapping("/navigate-advanced")
public View navigateAdvanced() {
HtmxLocationRedirectView view = new HtmxLocationRedirectView("/content");
// Set target element for the response
view.setTarget("#main-content");
// Set swap method
view.setSwap("innerHTML");
// Select specific content from response
view.setSelect("#article");
// Set source element
view.setSource("#nav-link");
// Set triggering event
view.setEvent("click");
// Add custom headers to the request
view.setHeaders(Map.of("X-Custom-Header", "value"));
// Add values to submit with request
view.setValues(Map.of("page", 1, "sort", "date"));
// Set handler callback
view.setHandler("customHandler");
return view;
}
// Using view name prefix
@HxRequest
@PostMapping("/spa-navigate")
public String spaNavigate() {
return "redirect:htmx:location:/dashboard";
}
}
```
--------------------------------
### Dynamic URL with Thymeleaf Expression
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use the `hx:` prefix for dynamic URLs in htmx attributes, allowing Thymeleaf expressions to generate attribute values.
```html
Load User Details
```
--------------------------------
### Add htmx-spring-boot Maven Dependency
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Include this dependency to add annotations and helper classes for htmx integration in your Spring Boot project.
```xml
io.github.wimdeblauwehtmx-spring-bootLATEST_VERSION_HERE
```
--------------------------------
### Accessing Htmx Request Headers with HtmxRequest
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use HtmxRequest as a controller method argument to access various htmx request headers. This includes checking if the request is an htmx request, if it was boosted, if it's a history restore request, and retrieving details like current URL, trigger element ID/name, target element, and prompt response.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class DashboardController {
@HxRequest
@GetMapping("/dashboard")
public String dashboard(HtmxRequest htmxRequest, Model model) {
// Check if this is an htmx request
if (htmxRequest.isHtmxRequest()) {
model.addAttribute("partial", true);
}
// Check if request was boosted (hx-boost)
if (htmxRequest.isBoosted()) {
model.addAttribute("boosted", true);
}
// Check if this is a history restore request
if (htmxRequest.isHistoryRestoreRequest()) {
return "dashboard/full";
}
// Get the current URL of the browser
String currentUrl = htmxRequest.getCurrentUrl();
model.addAttribute("previousUrl", currentUrl);
// Get trigger element information
String triggerId = htmxRequest.getTriggerId();
String triggerName = htmxRequest.getTriggerName();
model.addAttribute("triggeredBy", triggerId != null ? triggerId : triggerName);
// Get target element ID
String target = htmxRequest.getTarget();
model.addAttribute("targetElement", target);
// Get user's response to hx-prompt
String promptResponse = htmxRequest.getPromptResponse();
if (promptResponse != null) {
model.addAttribute("userInput", promptResponse);
}
return "dashboard/partial";
}
}
```
--------------------------------
### Add Maven Dependency for Thymeleaf Integration
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Include this dependency for Thymeleaf integration, which adds a custom Thymeleaf dialect for rendering htmx-specific attributes.
```xml
io.github.wimdeblauwehtmx-spring-boot-thymeleaf5.1.0
```
--------------------------------
### HTMX Exception Handling with HtmxRequest and HtmxResponse
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Handle exceptions specifically for HTMX requests using `HtmxRequest` and `HtmxResponse` in exception handlers. This allows for targeted error display within HTMX-driven interfaces. The `HxRetarget` and `HxReswap` annotations can simplify this process.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxResponse;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRetarget;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxReswap;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxSwapType;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class HtmxExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(Exception ex, HtmxRequest htmxRequest,
HtmxResponse htmxResponse, Model model) {
model.addAttribute("error", ex.getMessage());
if (htmxRequest.isHtmxRequest()) {
// For htmx requests, show error in a specific container
htmxResponse.setRetarget("#error-container");
htmxResponse.setReswap(HtmxReswap.innerHTML());
htmxResponse.addTrigger("errorOccurred");
return "errors/partial";
}
// For regular requests, show full error page
return "errors/full";
}
// Using annotations for exception handling
@ExceptionHandler(ValidationException.class)
@HxRetarget("#form-errors")
@HxReswap(HxSwapType.INNER_HTML)
public String handleValidationError(ValidationException ex, Model model) {
model.addAttribute("errors", ex.getErrors());
return "forms/validation-errors";
}
@ExceptionHandler(NotFoundException.class)
@HxRetarget("#content")
public String handleNotFound(NotFoundException ex, Model model) {
model.addAttribute("message", ex.getMessage());
return "errors/not-found";
}
}
```
--------------------------------
### Specify Target Element for Swap with @HxRetarget
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use @HxRetarget to change the target element where the htmx response will be swapped. This is useful when the response should update a specific part of the DOM that is not the element that triggered the request.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRetarget;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class SwapController {
// Change target element for the swap
@HxRequest
@HxRetarget("#notification-area")
@PostMapping("/notify")
public String showNotification() {
return "notifications/toast";
}
}
```
--------------------------------
### Select Specific Part of Response with @HxReselect
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
The @HxReselect annotation allows you to specify a CSS selector to extract only a portion of the response HTML for swapping. This is helpful when the response contains more content than needed for the current update.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxReselect;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class SwapController {
// Select specific part of response to swap
@HxRequest
@HxReselect("#main-content")
@GetMapping("/page")
public String loadPage() {
return "pages/full"; // Only #main-content from this template will be used
}
}
```
--------------------------------
### HtmxRefreshView for Full Page Refresh
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Utilize HtmxRefreshView to send an HX-Refresh header, instructing htmx to perform a full page refresh. This is useful for applying changes after a save operation.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxRefreshView;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.View;
@Controller
public class RefreshController {
@HxRequest
@PostMapping("/settings/save")
public View saveSettings() {
// Save settings...
// Trigger full page refresh to apply changes
return new HtmxRefreshView();
}
// Using view name prefix
@HxRequest
@PostMapping("/cache/clear")
public String clearCache() {
// Clear cache...
return "refresh:htmx";
}
}
```
--------------------------------
### Form with Automatic CSRF Token Injection
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Forms using `hx:post` with the Thymeleaf dialect automatically include the CSRF token in the `hx-headers`.
```html
```
--------------------------------
### Render Multiple Thymeleaf Fragments with HtmxResponse
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use HtmxResponse to render specific fragments from a Thymeleaf template, identified by Markup Selectors, for htmx Out Of Band Swaps.
```java
@HxRequest
@GetMapping("/users")
public View users(Model model) {
model.addAttribute("users", userRepository.findAll());
model.addAttribute("count", userRepository.count());
return FragmentsRendering
.with("users :: list")
.fragment("users :: count")
.build();
}
```
--------------------------------
### Automatic CSRF Token Injection for htmx
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
The library automatically injects CSRF tokens into htmx requests for methods like POST, PUT, PATCH, and DELETE by utilizing the `hx-headers` attribute. This ensures security even when the htmx element is not part of a standard HTML form.
```html
hx:post
```
```html
hx:put
```
```html
hx:patch
```
```html
hx:delete
```
--------------------------------
### Control Response Swap Behavior with @HxReswap
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
The @HxReswap annotation allows overriding the hx-swap attribute. It can specify the swap type, timing, scrolling behavior, and transitions for the response content.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxReswap;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxSwapType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class SwapController {
// Override swap method
@HxRequest
@HxReswap(HxSwapType.OUTER_HTML)
@PostMapping("/replace")
public String replaceElement() {
return "elements/replacement";
}
// Full reswap configuration with timing and scrolling
@HxRequest
@HxReswap(
value = HxSwapType.INNER_HTML,
swap = 100, // ms before swap
settle = 200, // ms after swap
scroll = HxReswap.Position.TOP,
scrollTarget = "#scroll-area",
show = HxReswap.Position.BOTTOM,
showTarget = "#viewport",
transition = true,
focusScroll = HxReswap.FocusScroll.TRUE
)
@GetMapping("/animated-content")
public String animatedContent() {
return "content/animated";
}
}
```
--------------------------------
### HTMX Target Attribute
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
When using `hx-target` with an ID selector, ensure it is correctly formatted. The `#` symbol is required.
```html
Search
```
```html
Search
```
--------------------------------
### Trigger HTMX Event with @HxTrigger Annotation
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use the @HxTrigger annotation on a controller method to set the HX-Trigger response header, allowing HTMX to fire a custom event after the response is processed. Requires @HxRequest.
```java
@HxRequest
@HxTrigger("userUpdated") // the event 'userUpdated' will be triggered by htmx
@GetMapping("/users")
public String users() {
return "view";
}
```
--------------------------------
### Access htmx Request Headers with HtmxRequest Argument
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Inject the HtmxRequest class as a controller method argument to access various htmx request headers, such as checking for history restore requests.
```java
@HxRequest
@GetMapping("/users")
public String users(HtmxRequest htmxRequest) {
if (htmxRequest.isHistoryRestoreRequest()) {
// do something
}
return "view";
}
```
--------------------------------
### Map HTMX Requests with @HxRequest Annotation
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
The @HxRequest annotation restricts controller methods to only handle htmx requests. It supports filtering by trigger element ID/name, target element, boosted requests, and history restore requests.
```java
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class UserController {
// Only handles htmx requests
@HxRequest
@GetMapping("/users")
public String listUsers() {
return "users/list";
}
// Only handles htmx requests triggered by element with id="my-button"
@HxRequest("my-button")
@GetMapping("/users/search")
public String searchUsers() {
return "users/search-results";
}
// Only handles htmx requests with specific trigger ID
@HxRequest(triggerId = "search-form")
@GetMapping("/users/filter")
public String filterUsers() {
return "users/filtered";
}
// Only handles htmx requests targeting specific element
@HxRequest(target = "user-list")
@GetMapping("/users/refresh")
public String refreshUserList() {
return "users/list";
}
// Exclude boosted requests
@HxRequest(boosted = false)
@GetMapping("/users/ajax-only")
public String ajaxOnlyEndpoint() {
return "users/partial";
}
// Handle history restore requests
@HxRequest(historyRestoreRequest = true)
@GetMapping("/users/history")
public String handleHistoryRestore() {
return "users/list";
}
}
```
--------------------------------
### Checking for HTMX Request
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
Use the `#htmx.isHtmxRequest()` Thymeleaf helper to conditionally render content only when the request is made via HTMX.
```html
This content only shows for htmx requests
```
--------------------------------
### Restrict htmx Request by Target Element
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use the @HxRequest annotation with the target attribute to restrict controller method invocation to requests where a specific target element is defined.
```java
@HxRequest(target = "my-target")
@GetMapping("/users")
public String users() {
return "view";
}
```
--------------------------------
### Restrict htmx Request by Trigger Element Name
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use the @HxRequest annotation with triggerName to restrict controller method invocation to requests originating from an element with a specific name.
```java
@HxRequest(triggerName = "my-element-name")
@GetMapping("/users")
public String users() {
return "view";
}
```
--------------------------------
### Handling '#' in hx-target with Thymeleaf
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
When using Thymeleaf's `hx:target` attribute with a value that includes '#', such as an element ID, you must either use the static `hx-target` attribute or explicitly escape the string within Thymeleaf using `${'#mydiv'}` to prevent Thymeleaf from interpreting it as a translation key.
```html
hx-target="#mydiv"
```
```html
hx:target="${\'#mydiv\'}"
```
--------------------------------
### Restrict htmx Request by Trigger Element ID
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use the @HxRequest annotation with a value or triggerId to restrict controller method invocation to requests originating from a specific element ID.
```java
@HxRequest("my-element")
@GetMapping("/users")
public String users() {
return "view";
}
```
--------------------------------
### Map htmx Requests with @HxRequest
Source: https://github.com/wimdeblauwe/htmx-spring-boot/blob/main/README.md
Use the @HxRequest annotation to ensure a controller method is only invoked for htmx-based requests. This annotation can be composed with other Spring MVC annotations.
```java
@HxRequest
@GetMapping("/users")
public String users() {
return "view";
}
```
--------------------------------
### Conditional HTMX Attributes
Source: https://context7.com/wimdeblauwe/htmx-spring-boot/llms.txt
HTMX attributes can be made conditional using Thymeleaf expressions, allowing dynamic control over triggers and targets.
```html
Content
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.