Labs ICT
Pro Login

Inlining

JavaScript and CSS inlining in templates.

JavaScript Inlining

Thymeleaf lets you inject server-side data directly into JavaScript using the th:inline attribute. This is incredibly handy when you need to pass model data to your client-side scripts.


<script th:inline="javascript">
    var username = [[${user.name}]];
    var items = [[${itemList}]];
    console.log("Welcome, " + username);
</script>
    

The double brackets [[${...}]] are Thymeleaf's inlining syntax. Thymeleaf processes them server-side and outputs valid JavaScript. If the data is a string, it automatically adds quotes. For objects and arrays, it serializes them to JSON.

CSS Inlining

You can also inline values into CSS styles using the same approach. This lets you dynamicize themes or responsive breakpoints based on server data.


<style th:inline="css">
    .header {
        background-color: [[${theme.primaryColor}]];
        font-size: [[${fontSize}]]px;
    }
</style>
    

This works just like JavaScript inlining. Thymeleaf replaces the expressions with their actual values at render time, producing clean CSS output.

Accessing Model Data in JavaScript

In practice, you'll often need to pass multiple pieces of data to JavaScript for use in AJAX calls, charts, or form validation. Thymeleaf makes this clean and straightforward.


<script th:inline="javascript">
    var appConfig = {
        userId: [[${user.id}]],
        apiEndpoint: [[${apiUrl}]],
        isAdmin: [[${user.admin}]]
    };

    fetch(appConfig.apiEndpoint + "/users/" + appConfig.userId)
        .then(response => response.json())
        .then(data => console.log(data));
</script>
    

By grouping your data into a config object, your JavaScript stays organized and easy to maintain. Just be careful not to expose sensitive data this way.

Try it Yourself →

JSON Serialization

When you inline a Java object or collection, Thymeleaf uses Jackson to serialize it to JSON. This means complex nested objects work out of the box.


<script th:inline="javascript">
    var products = [[${productList}]];
    var firstProduct = products[0];
    document.getElementById("name").textContent = firstProduct.name;
    document.getElementById("price").textContent = "$" + firstProduct.price;
</script>
    

Make sure Jackson is on your classpath (it usually is with Spring Boot). Thymeleaf handles the conversion automatically, so you get valid JSON without writing serialization code yourself.

Escaping and Security

When inlining user-generated content, always be mindful of XSS attacks. Thymeleaf escapes HTML by default in normal expressions, but inlined JavaScript doesn't get the same treatment. Use th:utext cautiously and validate your data.


<script th:inline="javascript">
    var userInput = [[${safeUserData}]];
    var rawHtml = [[${rawHtmlContent}]];
</script>
    

If the data might contain untrusted content, sanitize it on the server side before passing it to the template. Never blindly trust inlined values that come from user input.