Thymeleaflet provides a lightweight Storybook-style UI for Thymeleaf fragments. It discovers fragments, renders previews, and generates usage examples based on JavaDoc-like comments embedded in HTML templates.
- Fragment list UI and preview pages under a configurable base path
- JavaDoc parsing for fragment parameters, models, and usage examples
- YAML-driven story configuration
- Built-in CSS (Tailwind) for the UI
Live demo: https://demo-thymeleaflet.koyeb.app/thymeleaflet
Thymeleaflet is a developer tool intended for local or internal use during development. It should not be exposed in production environments.
Recommended setup (enable in dev only, disable in prod):
# application-dev.yml
thymeleaflet:
base-path: /thymeleaflet
# application-prod.yml
spring:
autoconfigure:
exclude: io.github.wamukat.thymeleaflet.infrastructure.configuration.StorybookAutoConfigurationYou can also remove the dependency from production builds entirely.
- Java 17+ (runtime / library usage)
- Java 21+ (when building this repository from source)
- Spring Boot 3.1+ / 4.x
- Maven or Gradle
Maven:
<dependency>
<groupId>io.github.wamukat</groupId>
<artifactId>thymeleaflet-spring-boot-starter</artifactId>
<version>0.2.6</version>
</dependency>Gradle:
dependencies {
implementation("io.github.wamukat:thymeleaflet-spring-boot-starter:0.2.6")
}- Add the dependency and start your Spring Boot app.
- Open the UI (default):
http://localhost:6006/thymeleaflet
Port 6006 is used by the sample to reduce clashes with common app ports.
- Place fragment templates under your normal Thymeleaf templates path.
- (Optional) Add story files under:
META-INF/thymeleaflet/stories/{templatePath}.stories.yml
thymeleaflet:
base-path: /thymeleaflet
debug: false
resources:
template-paths:
- /templates/
stylesheets: []
scripts: []
cache-duration-seconds: 3600
cache:
enabled: true
preload: falsethymeleaflet.base-pathcontrols the UI base path.resources.template-pathsmust contain 1 to 5 entries.resources.stylesheetssupports up to 10 entries.resources.scriptssupports up to 10 entries (injection happens inside the preview iframe).- To use JavaScript, register it under
resources.scriptsand wrap the required DOM withpreview.wrapperso the preview matches app behavior. Example:<div data-theme="light">{{content}}</div> cache.enabledenables in-memory caching for fragment discovery, JavaDoc parsing, and dependency analysis.cache.preloadwarms the caches at application startup (useful for low-CPU demo environments).- CSP is intentionally permissive to allow external JS/CSS in previews. Use only in trusted environments.
- Preview iframes allow same-origin so cookies/localStorage and authenticated API calls work.
- By default, Thymeleaflet does not register Spring Security rules.
- If your app uses Spring Security and you want zero-config onboarding, set
thymeleaflet.security.auto-permit=trueto auto-register a minimal permit rule for/thymeleaflet/**. - If you prefer explicit control, keep the default and allow
/thymeleaflet/**in your app-sideSecurityFilterChain.
{basePath}: fragment list UI{basePath}/main-content: lazy-loaded main content{basePath}/{templatePath}/{fragmentName}/{storyName}: story preview page{basePath}/{templatePath}/{fragmentName}/{storyName}/content: HTMX content fragment{basePath}/{templatePath}/{fragmentName}/{storyName}/render: dynamic render endpoint{basePath}/{templatePath}/{fragmentName}/{storyName}/usage: usage example fragment
Thymeleaflet parses JavaDoc-style comments embedded in HTML templates. Example:
<!--
/**
* Member detail (memberDetail)
*
* @param variant {@code String} [optional=standard] Display variant
* @model memberProfile {@code List<Map<String, Object>>} [required] Member model
* @example <div th:replace="~{domain/member/organisms/member-profile :: memberDetail()}"></div>
* @background gray-50
*/
-->- Baseline: Thymeleaf
3.1.2.RELEASE - Reference parser:
org.thymeleaf.standard.expression.FragmentSignatureUtils - v1 UI support set is intentionally narrower than Thymeleaf parse compatibility.
Current stable UI support:
th:fragment="name"th:fragment="name()"th:fragment="name(param1, param2)"
Notes:
- Unsupported signature styles are skipped from discovery and reported via diagnostics.
- Diagnostics are logged with code/severity and surfaced to the UI as user-safe messages.
- See detailed rules:
docs/parser-spec.mdanddocs/parser-model.md.
./mvnw test
npm install
npm run buildSee:
- docs/README.md
- docs/getting-started.md
- docs/configuration.md
- docs/javadoc.md
- docs/stories.md
- docs/security.md
- docs/parser-spec.md
- docs/parser-model.md
See CONTRIBUTING.md.
See SECURITY.md.
Apache-2.0. See LICENSE.
日本語版ドキュメントは README.ja.md を参照してください。
