The Layout dialect is a Thymeleaf dialect that allows users to create layouts and templates for reusing HTML code. It has a hierarchical approach and uses a decorator pattern to “decorate” layout files. Layout Dialect is a separate project and does not ship with Thymeleaf. However, this is open source code, available on GitHub, it is well documented and, it seems, also maintained in good condition.
Installation
We will need to add the Thymeleaf starter package to your Spring Boot pom:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
However, starting with Spring Boot 2, this is no longer enough. The dialect pom is not part of Spring Boot, and we must add it ourselves:
<dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> <version>2.3.0</version> </dependency>
The code examples also use Bootstrap, so you also need to add web files:
')
<dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.0.0</version> </dependency>
As a final step, we need to create a LayoutDialect bean in the annotated @Configuration class.
@Bean public LayoutDialect layoutDialect() { return new LayoutDialect(); }
Come on.
Layout Dialect example
This example will show how we can use Layout Dialect to define layouts for our pages so that we can better reuse the code: using the index.html page, which uses layout.html as the layout. The name Layout.html is arbitrary and can be anything. There are a few more files added, but they are only for demonstration.

The picture shows the structure of the resource folder. Spring Boot will automatically find all Thymeleaf templates in the resources / templates directory.
Layout.html
<!DOCTYPE html> <html> <head> <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Igorski.co</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.min.css}" rel="stylesheet" media="screen" /> </head> <body> <div th:replace="fragments/header :: header"> This header content is going to be replaced.</div> <div class="container"> <div class="row"> <div class="col-2" layout:fragment="sidebar"> <h1>This is the layout's sidebar</h1> <p>This content will be replaced if the page using the layout also defines a layout:fragment="sidebar" segment.</p> </div> <div class="col" layout:fragment="content"> <h1>This is the Layout's main section</h1> <p>This content will be replaced if the page using the layout also defines a layout:fragment="content" segment. </p> </div> </div> </div> <footer th:insert="fragments/footer :: footer" class="footer"> This content will remain, but other content will be inserted after it. </footer> </body> </html>
In
layout.html ,
two of the five processors presented in Layout Dialect are used. First is the layout:
the header template processor . The header template processor helps the user determine the best heading for the resulting page. In this example, it defines the final title as a combination of the page title and the layout title. For this, two special tokens are used, represented in Layout Dialect,
$ LAYOUT_TITLE and
$ CONTENT_TITLE .
The two placeholders (or fragments) defined by the layout have the highest value in layout.html:
the fragment processor . This processor allows us to define content placeholders in our layouts. The contents of these placeholders will later be replaced by the contents of the pages using the layout. In the example, two different fragments are defined, one for the sidebar and the other for the main content. We can, however, have as many fragments as we wish, provided that they all have different names.
Index.html
<!DOCTYPE html> <html xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="~{layouts/layout}"> <head> <title>Home Page</title> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link th:href="@{/css/core.css}" rel="stylesheet" media="screen" /> </head> <body> <div class="container"> <div class="row"> <div class="col-2" layout:fragment="sidebar"> <h1>Sidebar</h1> <a href="#">Login</a> </div> <div class="col" layout:fragment="content"> <h1>Welcome to the Index page</h1> <br>This content is replacing the content of the layout:fragment="content"<br> placeholder in layout.html</p> </div> </div> </div> </body> </html>
We declare that index.html uses layout.html as its layout for the processor layout: decorate. By doing this, we declare that index.html will use the layout.html template. Here the most important thing is the use
of a fragment processor . It specifies the content to be used instead of the content of the layout fragments with the same name. One more thing worth mentioning is the
headline . On the resulting index.html page, which we will receive, after processing, the title will be a combination of two headers, one from index.html, and the other from the layout. They will be merged.
Both layout.html and index.html can be viewed in a browser without any processing. But after processing, we see that index.html is very different. The contents of index.html are used to decorate the layout and place the content inside the layout based on what the layout defines.
In the example there are two other elements: header and footer. However, they use the Thymeleaf Standard Layout th: replace and th: insert processors. Very similar to the
last two of the five processors represented in Layout Dialect, layout: insert, and layout: replace . They more or less do the same. Unlike previous processors, which we discussed, these two use not a hierarchical, but an inclusive approach. This is more characteristic of the typical form of Thymeleaf.

The picture shows the final form of the page. It has both a header and a footer, although none of them is mentioned in the index.html markup.