Spring Boot with Thymeleaf and Bootstrap
Tags: springboot, webdev, frontend
Published: 2024-05-13 09:37:58

Thymeleaf and Bootstrap are **powerful technologies to develop modern web applications**. In this article, we will show the steps to add Thymeleaf and Bootstrap to our Spring Boot application.

The complete setup can also be created directly in the Bootify Builder. Just open a project with [open project](https://bootify.io/), choose your preferences and select `Thymeleaf + Bootstrap` as frontend stack. If you don't select a frontend, all the following steps can be followed manually. 

## Adding Themeleaf to our app

Thymeleaf is the most used template engine for Spring Boot. Since the **templates are written in valid HTML code**, they can be opened without server-side rendering as well. To setup the engine and all recommended utilities, the following two dependencies are added to our application first.

```gradle
implementation('org.springframework.boot:spring-boot-starter-thymeleaf')
implementation('nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect')
```
_&nbsp; Adding new dependencies for Thymeleaf_

The module `spring-boot-starter-thymeleaf` will automatically integrate the template engine - in the following controller we can already see how this works. The `thymeleaf-layout-dialect` is recommended for most productive applications, in order that **several pages can use the same layout**. We don't need to provide any version here, as they are part of the dependency management plugin of Spring Boot.

```java
@Controller
@RequestMapping("/todo")
public class TodoController {

    // ...

    @GetMapping
    public String list(final Model model) {
        model.addAttribute("todos", todoService.findAll());
        return "todo/list";
    }

}
```
_&nbsp; A simple MVC controller_

Our simple endpoint just shows a list of todos. For this **all current todos are loaded from the service first and added to the model**. With `"todo/list"` the template from `src/main/resources/templates/todo/list.html` is loaded. Unless we configure it otherwise, the `template` folder is the default one from which the templates are picked.

```html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
        layout:decorate="~{layout}">
    <head>
        <title>[[#{todoList.list.headline}]]</title>
    </head>
    <body>
        <div layout:fragment="content">
            <!-- ... -->
            <div th:if="${todoLists.empty}">[[#{todoList.list.empty}]]</div>
            <div th:if="${!todoLists.empty}" class="table-responsive">
                <table class="table table-striped table-hover align-middle">
                    <thead>
                        <tr>
                            <th scope="col">[[#{todoList.name.label}]]</th>
                            <th><!-- --></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr th:each="todo : ${todos}">
                            <td>[[${todo.name}]]</td>
                            <td>
                                <div class="float-end text-nowrap">
                                    <a th:href="@{/todos/edit/{id}(id=${todo.id})}" class="btn btn-sm btn-info">[[#{todo.list.edit}]]</a>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </body>
</html>
```
_&nbsp; A simple Thymeleaf Template_

After adding our `list.html` template, we are already using Thymeleaf and Bootstrap classes successfully - the only missing layout will be shown in a moment. To enable real hot reloading during development, it is not enough to switch off template caching. How to read the HTML files directly from the file system is described [in this article](https://bootify.io/frontend/thymeleaf-templates-hot-reload.html).

## Bootstrap integration using WebJars

Bootstrap is currently the most popular CSS framework and can be **integrated directly into our Spring Boot app using WebJars**. For this we need another dependency first.

```gradle
implementation('org.webjars:bootstrap:5.3.3')
```

We can now include the JavaScript and CSS files for Bootstrap in our `layout.html` as follows. Our own JS or CSS can be provided additionally in `src/main/resources/static/js` and `src/main/resources/static/css` if needed.

```html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head>
        <!-- ... -->
        <link th:href="@{/webjars/bootstrap/5.3.0/css/bootstrap.min.css}" rel="stylesheet" />
        <link th:href="@{/css/app.css}" rel="stylesheet" />
        <script th:src="@{/webjars/bootstrap/5.3.0/js/bootstrap.bundle.min.js}" defer></script>
        <script th:src="@{/js/app.js}" defer></script>
    </head>
    <body>
        <main class="my-5">
            <div class="container">
                <!-- ... -->
                <div layout:fragment="content" />
            </div>
        </main>
    </body>
</html>
```
_&nbsp; Integration of Bootstrap files in their minimized versions_

## Bootstrap integration using Webpack

Alternatively, Bootstrap can also be integrated using Webpack to define **more complex rules for how CSS and JS should be provided to the frontend**. If Webpack is already prepared, only one command is needed to add Bootstrap.

```txt
npm i --save bootstrap @popperjs/core
```

However, since the Webpack setup with npm and DevServer requires a lot of explanation, please check the article about the [setup of Spring Boot with Webpack](https://bootify.io/frontend/webpack-spring-boot.html). Using Webpack offers many advantages - but also comes with the cost of a higher integration effort.

In the Free plan of Bootify, **Spring Boot application including a frontend stack can be initialized** - directly in the browser, without registration. Thymeleaf with Bootstrap is available there, either directly via WebJars or via Webpack.

[**&raquo; Start Project on Bootify.io**](https://bootify.io/)
&nbsp;


### Further readings

[Thymeleaf documentation](https://www.thymeleaf.org/documentation.html)  
[Bootstrap](https://getbootstrap.com)