Skip to content

Getting started

Shadleaf needs Java 17, Spring Boot 4 and Thymeleaf. Your application needs no Node.js and no Tailwind.

<dependency>
<groupId>io.github.wimdeblauwe</groupId>
<artifactId>shadleaf-spring-boot-starter</artifactId>
<version>0.9.0</version>
</dependency>

Include the stylesheet and the theme script

Section titled “Include the stylesheet and the theme script”

In the <head> of your layout:

<head>
<th:block th:replace="~{sl/layout :: theme-script}"></th:block>
<th:block th:replace="~{sl/layout :: assets}"></th:block>
<!-- your own stylesheet after it, so your overrides win -->
<link rel="stylesheet" th:href="@{/css/application.css}">
</head>

assets links the stylesheet of the configured skin and loads the script with Alpine.js, which the interactive components use; see Alpine.js if your application loads Alpine itself. theme-script is a tiny inline script that sets class="dark" on <html> before the first paint: localStorage['shadleaf-theme'] set to light or dark wins, anything else follows the operating system. <sl:theme-toggle> lets the user choose. Behind a Content-Security-Policy, see CSP.

Declare the namespace, then use the tags:

<html xmlns:th="http://www.thymeleaf.org" xmlns:sl="https://shadleaf.dev/sl">
...
<sl:button variant="outline">Cancel</sl:button>
<sl:button type="submit">Save</sl:button>
Property Default
shadleaf.skin vega The visual identity, named after the shadcn/ui style it follows: vega or lyra.
shadleaf.assets.variant standalone embedded leaves out Tailwind’s reset, for applications that compile Tailwind themselves.
shadleaf.assets.alpine bundled Where Alpine.js comes from: bundled, csp or external; see Alpine.js.
shadleaf.csp.nonce-attribute cspNonce The request attribute holding a CSP nonce for the theme script.
shadleaf.dev.web-types-file Writes IDE metadata for your components; see IDE completion.

Load the embedded bundle (shadleaf.assets.variant=embedded). It carries no preflight and no theme variables, so your own Tailwind build keeps its reset, its headings and its @theme. Utility classes such as w-full mt-4 on a component come from your build: the library’s bundles define none.

The Layouts section has whole layouts to copy, with the navigation in a sidebar (Collapses to icons) or in a header (Navigation in the header), a panel on a phone, the skip link, the breadcrumb, the theme toggle and the toasts already in place. The Application shell page helps you pick one and says what every layout needs.