### 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.wimdeblauwe htmx-spring-boot 5.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.wimdeblauwe htmx-spring-boot-thymeleaf LATEST_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.wimdeblauwe htmx-spring-boot LATEST_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.wimdeblauwe htmx-spring-boot-thymeleaf 5.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.