Create

Frameworks

Spring Boot

Use WDS in a Spring Boot app with Thymeleaf templates.

Spring Boot renders HTML on the server, so it uses the ready-made wds.bundle.js: no Node.js in the project, no import map and no CDN. The component pages have no Spring Boot tab; use the code from their HTML tab.

Installation#

Copy the static files#

Put the bundle and the tokens in static, where Spring Boot serves them from.

tree
src/main/resources/
├── static/wds/
│   ├── wds.bundle.js   <- @wds/core/dist/wds.bundle.js
│   └── tokens.css      <- @wds/tokens/src/tokens.css
└── templates/
    └── signup.html
bash
# from a folder where @wds/core and @wds/tokens are installed
cp node_modules/@wds/core/dist/wds.bundle.js node_modules/@wds/tokens/src/tokens.css \
   my-app/src/main/resources/static/wds/

Add them to the template#

templates/signup.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <link rel="stylesheet" th:href="@{/wds/tokens.css}" />
  <script type="module" th:src="@{/wds/wds.bundle.js}"></script>
</head>

Forms and validation#

  • th:field works only on native fields; for wds-* use name with th:value or th:checked.
  • An error from BindingResult: th:invalid on wds-field and th:errors in wds-field-error.
  • th:action adds the _csrf token when Spring Security is on.
  • A reset button goes back to the values rendered by the server.
templates/signup.html
<form method="post" th:action="@{/signup}" th:object="${signupForm}">
  <!-- th:field works only on native fields: use name + th:value instead -->
  <wds-field th:invalid="${#fields.hasErrors('email')} ? '' : null">
    <wds-field-label>Email</wds-field-label>
    <wds-input type="email" name="email" th:value="*{email}" required></wds-input>
    <wds-field-error th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></wds-field-error>
  </wds-field>

  <wds-radio-group name="plan" th:value="*{plan}">
    <wds-radio value="free">Free</wds-radio>
    <wds-radio value="pro">Pro</wds-radio>
  </wds-radio-group>

  <!-- an unchecked checkbox sends nothing: _newsletter tells Spring to set false -->
  <wds-checkbox name="newsletter" value="true" th:checked="*{newsletter}">Newsletter</wds-checkbox>
  <input type="hidden" name="_newsletter" value="on" />

  <wds-button type="submit">Create account</wds-button>
</form>
SignupController.java
public class SignupForm {
    @NotBlank @Email
    private String email;
    private String plan = "free";
    private boolean newsletter;
    // getters and setters
}

@Controller
public class SignupController {

    @GetMapping("/signup")
    public String form(Model model) {
        model.addAttribute("signupForm", new SignupForm());
        return "signup";
    }

    @PostMapping("/signup")
    public String submit(@Valid SignupForm signupForm, BindingResult result) {
        if (result.hasErrors()) {
            return "signup"; // errors go to wds-field-error, the field gets invalid
        }
        return "redirect:/welcome";
    }
}
Footer