162

I am using Thymeleaf as template engine. How I pass a variable from Spring model to JavaScript variable?

Spring-side:

@RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
    model.addAttribute("message", "hello");
    return "index";
}

Client-side:

<script>
    ....
    var m = ${message}; // not working
    alert(m);
    ...
</script>

10 Answers 10

266

According to the official documentation:

<script th:inline="javascript">
/*<![CDATA[*/

    var message = /*[[${message}]]*/ 'default';
    console.log(message);

/*]]>*/
</script>
8
  • 1
    Doesn't work... javascript error uncaught syntax error
    – szxnyc
    Commented Oct 23, 2014 at 1:58
  • 7
    Works fine, also possible to read from messages.properties: var msg = [[#{msg}]];
    – Andrew
    Commented Jan 6, 2015 at 7:35
  • 3
    @szxnyc if you forget the /*<![CDATA[*/ macro you will get that.
    – CodeMonkey
    Commented Dec 1, 2016 at 22:49
  • 17
    Also take attention to <script th:inline="javascript"> Commented Jul 21, 2017 at 22:42
  • 1
    @MichałStochmal you can load inline javascript on top of external javascript and use same variables(defined in inline javascript) in external javascript. Commented Jan 11, 2020 at 13:22
34

Thymeleaf 3 now:

  • Display a constant:

    <script th:inline="javascript">
    var MY_URL = /*[[${T(com.xyz.constants.Fruits).cheery}]]*/ "";
    </script>
    
  • Display a variable:

    var message = [[${message}]];
    
  • Or in a comment to have a valid JavaScript code when you open your template file in a static manner (without executing it at a server).

    Thymeleaf calls this: JavaScript natural templates

    var message = /*[[${message}]]*/ "";
    

    Thymeleaf will ignore everything we have written after the comment and before the semicolon.

More info: http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#javascript-inlining

1
  • thanks you! wanna gave you a beer i was looking for this syntax var MY_URL = /*[[${T(com.xyz.constants.Fruits).cheery}]]*/ "";
    – Aung Aung
    Commented Nov 24, 2018 at 10:48
23
var message =/*[[${message}]]*/ 'defaultanyvalue';
3
  • 9
    Notice it should be NO space between /* */ and the contained [[ ]].
    – jyu
    Commented Feb 15, 2016 at 19:49
  • 1
    It's worth noting that the defaultanyvalue will only be used when running the page statically, i.e. outside a web container. If ran inside a container and the variable message hasn't been declared the resulting source code will be var message = null; Commented May 10, 2017 at 17:51
  • 6
    Also important to add th:inline="javascript" to the script tag.
    – redent84
    Commented Aug 6, 2018 at 18:12
15

MAKE sure you have thymleaf on page already

//Use this in java
@Controller
@RequestMapping("/showingTymleafTextInJavaScript")
public String thankYou(Model model){
 model.addAttribute("showTextFromJavaController","dummy text");
 return "showingTymleafTextInJavaScript";
}


//thymleaf page  javascript page
<script>
var showtext = "[[${showTextFromJavaController}]]";
console.log(showtext);
</script>
0
14

According to the documentation there are several ways to do the inlining.
The right way you must choose based on the situation.

1) Simply put the variable from server to javascript :

<script th:inline="javascript">
/*<![CDATA[*/

var message = [[${message}]];
alert(message);

/*]]>*/
</script>

2) Combine javascript variables with server side variables, e.g. you need to create link for requesting inside the javascript:

<script th:inline="javascript">
        /*<![CDATA[*/
        function sampleGetByJquery(v) {
            /*[+
            var url = [[@{/my/get/url(var1=${#httpServletRequest.getParameter('var1')})}]] 
                      + "&var2="+v;
             +]*/
            $("#myPanel").load(url, function() {});
        }
        /*]]>*/
        </script>

The one situation I can't resolve - then I need to pass javascript variable inside the Java method calling inside the template (it's impossible I guess).

10

If you use Thymeleaf 3:

<script th:inline="javascript">
    var username = [[${session.user.name}]];
</script>
2
  • 2
    This should get more votes, now that Thymeleaf 3 is pretty much the norm, yes? The manual link should also be updated. thymeleaf.org/doc/tutorials/3.0/… ...I just shipped a float[] with audio data to a web page for the first time. Can play it with Web Audio API! This question and these answer were a big help in locating the Javascript inlining used. Commented May 8, 2021 at 5:51
  • VsCode has problems with this syntax, but the code works fine. If you want vscode to stop complaining, use this alterative syntax: var username = "[(${session.user.name})]". Commented Jul 4 at 3:33
8

I've seen this kind of thing work in the wild:

<input type="button"  th:onclick="'javascript:getContactId(\'' + ${contact.id} + '\');'" />
3

If you need to display your variable unescaped, use this format:

<script th:inline="javascript">
/*<![CDATA[*/

    var message = /*[(${message})]*/ 'default';

/*]]>*/
</script>

Note the [( brackets which wrap the variable.

3

Another way to do it is to create a dynamic javascript returned by a java controller like it is written here in the thymeleaf forum: http://forum.thymeleaf.org/Can-I-use-th-inline-for-a-separate-javascript-file-td4025766.html

One way to handle this is to create a dynamic javascript file with the URLs embedded in it. Here are the steps (if you are using Spring MVC)

@RequestMapping(path = {"/dynamic.js"}, method = RequestMethod.GET, produces = "application/javascript")
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public String dynamicJS(HttpServletRequest request) {

        return "Your javascript code....";

}


  
3

Assuming request attribute named "message":

request.setAttribute("message", "this is my message");

To read it in the html page using Thymeleaf template:

<script>
  var message = "[[${message}]]";
  alert(message);
</script>
1
  • Have XSS vulnerability!
    – e-info128
    Commented Aug 31, 2023 at 18:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.