Utilizing Thymeleaf With JavaScript in Spring Boot: A Comprehensive Guide

Within my Spring Boot project, I am attempting to utilize Thymeleaf for injecting data into a JavaScript file that undergoes preprocessing with babel via WebPack.

The Thymeleaf setup is outlined as follows:

@Bean
public SpringTemplateEngine templateEngine(MessageSource webTemplateMessageSource) {
    // Code snippet here
}

@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
    // Code snippet here
}

public SpringResourceTemplateResolver htmlTemplateResolver() {
    // Code snippet here
}

public SpringResourceTemplateResolver javaScriptTemplateResolver() {
    // Code snippet here
}

An example of an HTML page structure is provided below:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <title>Secrets</title>
</head>

<body>

    <button id="secret-button">Tell me the secret</button>

    <script th:src="@{/js/scripts.js}"></script>
</body>
</html>

In this scenario, I aim to populate the secretMessage variable in a JavaScript file using ThymeLeaf with the following message property:

const secretMessage = [[#{secret}]];
document.querySelector("#secret-button").addEventListener("click", ev => {
    alert(secretMessage);
});

The message content resides within a dedicated message source as shown:

secret=Elvis 'still alive

Lastly, the relevant segment of the WebPack configuration is detailed below:

let babelConfig = {
    test: /\.js$/i,
    exclude: /(node_modules)/,
    use: {
        loader: 'babel-loader',
        options: {
            presets: ['@babel/preset-react', '@babel/preset-env']
        }
    }
};

Despite the efforts put into this setup, there are issues encountered. Specifically, babel throws errors concerning the line:

const secretMessage = [[#{secret}]];
within the JavaScript file.

Furthermore, uncertainties remain as to whether additional configurations are necessary. Resources or examples demonstrating proper implementation of Thymeleaf in conjunction with Spring Boot for JavaScript parsing are sought after for guidance and assistance.

Edit

For experimentation purposes, attempts were made to process the JavaScript file without relying on webpack bundling. Despite placing the JS file directly within the static/build/js directory, it fails to be processed by the Thymeleaf engine when requested by the HTML page.


Hence, aside from the webpack preprocessing challenge, an obstacle persists in terms of Thymeleaf processing. Limited resources and tutorials addressing this hurdle have led to a trial-and-error predicament, unsure of the feasibility of the desired outcome.

Edit 2:

Deleted

Edit 3:

Following suggestions from M. Deinum, a `ViewController` was implemented by overriding `addViewControllers` within the `WebMvcConfigurer` interface:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("*.js");
}

In addition, to address lingering issues persisting despite these changes, the

templateResolver.setPrefix("/js/");
line within the relevant javaScriptTemplateResolver was removed in hopes of eliminating any potential limitations. Despite these adjustments, Thymeleaf still does not process the JavaScript file as intended.

Answer №1

To properly configure your template engine, make sure to include both resolvers:

templateEngine.addTemplateResolver(htmlTemplateResolver());
templateEngine.addTemplateResolver(javaScriptTemplateResolver());

If you are utilizing Thymeleaf, don't forget to create a controller with a mapping for your JavaScript file:

@GetMapping("/js/index.js")
public String indexJs() {
  return "index";
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular - Ensure completion of a function call before continuing with the code execution

I'm currently working on developing a code snippet that checks for potential adverse drug reactions between two medications. Within my checkForClash() function, there is a call to getCollisionsList(), which is responsible for populating the interacti ...

What is the best way to initiate the registration page through the @auth0/auth0-react library?

I've hit a roadblock in trying to automatically launch the sign-up (registration) page using @auth0/auth0-react. Previously, I would send mode which worked with auth0-js. So far, I have attempted the following without success: const { loginWithRedir ...

Scrolling to zoom in on the div content

I need the ability to resize the content within a div without changing the size of the div itself when the user scrolls. The function I currently have is as follows: var zoomable = document.getElementById('zoomable'), zX = 1; window.addEvent ...

Discovering the method to extract a specific section from a lengthy string

Looking to extract phone numbers from an HTML source code using PHP? Each phone number in the code starts with 'phone=' and ends with %. For example, consider the following sample HTML code: b2e1d163b0b4dc6ebfa5&amp;t=s&amp;phone=9535503 ...

The responsive navigation bar yielded an unforeseen outcome

Looking to create a responsive navigation bar similar to the one shown here My code successfully shows and hides the navigation items, but it's not updating the burger icon No console errors or warnings are present This is my HTML: <nav> ...

Obtain an Instance of a Class Using a Decorator

Delving deep into the world of decorators, I stumbled upon some fascinating ideas for incorporating them into my reflux implementation. My concept involves tagging a store's class method with an action, so that whenever that action is triggered, it au ...

JavaScript Thumbnail Slider Builder

I've been working hard on developing a custom JavaScript thumbnail slider that uses data-src. Everything seems to be in order, except the next and previous buttons are not functioning properly. Any assistance would be greatly appreciated. Here's ...

What could be causing the slow build time for npm run serve on a Vue.js project?

My Vue.js project was running smoothly until about an hour ago when I noticed that it is now taking a very long time to build. Specifically, it gets stuck at 32% for more than 5 minutes. Does anyone have any suggestions on how to fix this issue? I'm n ...

How to attach an event listener to an input element using Angular

I am looking to add a listener to an input element that will be triggered every time the user changes the input values. The goal is to display the current values chosen by the user. Example HTML template: <div id="idDoseLabel1" class="da ...

Next.js Refresh Screen

Is there a way to refresh my client's web page from the server at a specific time? I need the client's page to be refreshed at 12pm, and although I'm using a scheduler, it doesn't seem to be automatically refreshing the web page on the ...

What is the best way to combine a string with a $scope variable in AngularJS?

Is there a way to add a variable to the $scope model in order to concat it? I'm attempting this code: for(var i=0; i<=response.length-1; i++) { $scope.formData.jobId+i = response[i].jobId; } How can I combine the variable i with $scope.formDat ...

What are the steps to creating a unique event within an AngularJs service?

In the midst of my AngularJs project, I find myself faced with a dilemma. I have a service designed to manage button events, but I want another service to handle these events indirectly without directly interacting with the buttons themselves. So, my goal ...

Puppeteer does not support the use of multiple proxies concurrently

How can I effectively set up multiple proxies with puppeteer? Here is the approach I have taken: const puppeteer = require('puppeteer'); (async () => { let browsers = []; const proxies = [ 'socks5://myuser: ...

Leveraging require in AWS lambda operations

As part of my exploration into AWS Lambda functions, I've been trying to determine if the require statement can be used within them. This would allow me to incorporate other non-lambda functions into my code. Although zipping the node modules folder i ...

A useful tip for emphasizing tags that have attributes with endings

Here is the HTML list I'm working with: <li class=​"info" data-info=​"" data-title=​"info 1" data-info-id=​"222643">…</li> <li class=​"info" data-info=​"" data-title=​"info 2" data-info-id=​"217145">…</li> ...

The issue of the background image not updating with jQuery persists in Internet Explorer 11

Hello everyone, I am facing an issue where I am trying to change the background image of a div using jQuery on click. The code I have written works perfectly on all browsers except for IE. Can someone please provide me with some guidance or help on how to ...

Just released a new npm package called vue-izitheme. It's fully functional from the command line, but for some reason it's not showing up in search results. Any suggestions on how to fix

I released my project, vue-izitheme, two days ago but I can't seem to find it when searching. It is functioning correctly from the command line and has already been downloaded 44 times. Do you have any thoughts on what could be causing this issue? ...

jquery is showing up in the browserify bundle.js file, however, it is not functioning properly

Currently, I am trying to follow a brief tutorial on how to use Browserify. Despite following the instructions precisely, jQuery seems to not be working properly when bundled. Specifically, the button element in my app.js code is not appended to the body. ...

The jQuery click event does not fire within a bootstrap carousel

I am trying to set up a bootstrap carousel where clicking on an image inside it will trigger a self-made lightbox. However, I am facing some issues with the JavaScript code not being triggered with the following syntax: $('html').on("click", ".l ...

Retrieving the specific value of an input from a group of inputs sharing a common class

After extensive research, I have not found a suitable solution to my specific issue. I am creating a block of HTML elements such as <div>, <span>, <i>, and <input> multiple times using a for loop (the number of times depends on the ...