Skip to content
/ htmx-demo Public template

Very simple demonstration of the use of htmx with Spring Boot and Thymeleaf.

Notifications You must be signed in to change notification settings

wiverson/htmx-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

htmx-demo

Very simple demonstration of the use of htmx with Spring Boot and Thymeleaf. In addition to Thymeleaf, a few examples also use Handlebars/Mustache and j2html.

Build a Single Page Application (SPA) or just progressively add dynamic JavaScript functionality to your app without a complicated JavaScript framework.

It's possible to be a "full stack" Java developer and provide rich application functionality without complex tools and frameworks.

Using This Project

Requirements: JDK 16 and Apache Maven.

That's it. No npm, no JavaScript frameworks, no REST services generating JSON that is then converted back to HTML in the browser.

Once those are installed, just run mvn spring-boot:run and hit http://localhost:8080 and you'll see an index page with links to the various demos.

You'll notice that you don't need to install Node.js, npm, or any other tooling to get rich, dynamic UIs - just html, css, htmx, bootstrap and a bit of hyperscript.

If you want to be fancy, tell folks that you are migrating back to server-side rendering for your SPA applications for performance and security reasons.

Dependencies

WebJars are used to install and manage Bootstrap, jQuery, htmx and hyperscript. While Bootstrap v5 doesn't technically need jQuery any more, I left it in for now just in case. More information on using WebJars with Spring Boot.

You can add the WebJars for htmx and hyperscript to your pom.xml like this:

<dependencies>
    <dependency>
        <groupId>org.webjars.npm</groupId>
        <artifactId>htmx.org</artifactId>
        <version>1.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.webjars.npm</groupId>
        <artifactId>hyperscript.org</artifactId>
        <version>0.0.9</version>
    </dependency>
</dependencies>

...and then add the following to your application Thymeleaf/HTML to use htmx & hyperscript:

<head>
    <script type="text/javascript" th:src="@{/webjars/htmx.org/dist/htmx.min.js}"></script>
    <script type="text/javascript" th:src="@{/webjars/hyperscript.org/dist/_hyperscript.js}"></script>
</head>

Notice that you don't actually specify the version number for htmx or hyperscript in the HTML declaration - that's all handled for you by WebJars and your Maven pom.xml.

Layout

I don't like to repeat myself, so I use Thymeleaf layouts to keep the copy & pasting down to a minimum. Each page uses a layout:fragment="content" declaration to pull in a layout which includes the standard <head>

To see an example of this, index.html includes the line <section layout:fragment="content"> which instructs the Thymeleaf Layout Dialect to wrap the section with layout.html.

Logging

The application.yaml and logback.xml files are set up to dramatically reduce the log noise for a typical Spring Boot project.

Spring Security

This project includes a demo illustrating the use of Spring Security with htmx. When you access a path with /private/ Spring Security will send you to a login page. To create an account, use the sign up page and check the console for a link you can copy and paste into your browser.

This implementation of Spring Security includes a pretty complete workflow for an email/password based user registration system. If you pop in a valid SMTP server into the configuration you will have a working:

  • User login
  • User sign up
  • User email validation
  • User forgot password/email reset
  • RDBMS backed store with properly salted & encrypted passwords

You will find all of the Spring Security implementation details in the /htmx-demo/src/main/java/com/devhow/identity path.

The main fancy feature involving htmx is that if a user is logged in to the app with two pages open - let's say page A and page B. If the user logs out on page A, the session is now invalid for page B. In this demo, page B will now correctly bounce to the login page if htmx requests any new data.

Screenshots

The mandatory basic web-front end to do list sample app. Here are the Java controller and the Thymeleaf template. You may notice that there is a very small amount of hyperscript added to the page to address event edge cases not handled by htmx alone.

To Do

This infinite scroll demo uses the java-faker library to generate an endless stream of fake data. The more you scroll, the more data you'll see. In this case, the Java controller is just using Java text blocks to return the data. While very, very simple (and fast!) this isn't really a great idea, in particular due to potential issues around HTML escaping. For most situations you are much better off using either Thymeleaf templates, Handlebars/Mustache or j2html for these fragments.

Infinite Scroll

The next two screenshots are for a single Java controller and Thymeleaf template .

Every single input immediately posts back data to the controller. In this case, the response is sent back as an element to append to the messages block, but it's easy to imagine the response updating other elements - or perhaps just instantly preserving the user's data with no explicit form submit required.

All the widgets shown are just standard HTML elements. A few of them - like file input - can be a bit tricky to handle correctly - you want to make sure the submission encoding is set right and that you have right configuration on the server.

Fun fact: the checkbox can only be set to an indeterminate state via JavaScript (in this case, I'm just using hyperscript.

Standard HTML Input Widgets

These are mostly various text input widgets. In addition to things like automatically showing special keyboards on various mobile devices, certain fields such as Search are often used for live updates in response to user typing. There that functionality can be added trivially, without any JavaScript.

Standard HTML Input Widgets