I am making a Spring Boot web app using Thymeleaf. I have been experimenting with Webjars to use things like JQuery and Bootstrap on my web page. Using Spring Boot 2.2.6.RELEASE, and attempting to use Bootstrap Webjar version 4.1.1-1.
I have several different webjars in my pom, but I realized that none of the css files are loading. The Javascript files from the webjars are loading fine, but none of the css is being applied. When looking in the web developer debugger tool, I can see the Javascript files are all there, but none of the css files are present.
Currently, I am specifically trying to get Bootstrap tabs to work, but obviously, without any of the Bootstrap styles, none of the Bootstrap features will work.
This is basically what my controller looks like:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MyController {
@RequestMapping(value = "/stats", method = {RequestMethod.GET, RequestMethod.POST})
public String stats(
Model model) {
// some code adding simple attributes to the model
return "stats";
}
}
I have this web configuration class:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.resourceChain(false);
}
}
A sample of my pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- artifact info... -->
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- some other dependencies -->
<!-- Webjars -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.4.1-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-datepicker</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>popper.js</artifactId>
<version>1.16.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>font-awesome</artifactId>
<version>5.13.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.40</version>
</dependency>
<!-- Spring -->
<!-- some other Spring deps... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here is a sample of my html page (stats.html):
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>My Web App</title>
<link th:rel="stylesheet" th:href="@{webjars/bootstrap/css/bootstrap.min.css}" type="text.css"/>
<!--<link th:rel="stylesheet" th:href="@{webjars/bootstrap-datepicker/css/bootstrap-datepicker.min.css}" type="text/css"/>-->
<link th:rel="stylesheet" th:href="@{webjars/bootstrap-datepicker/css/bootstrap-datepicker.standalone.css}" type="text/css"/>
<link th:rel="stylesheet" th:href="@{webjars/font-awesome/css/all.css} " type="text/css"/>
<link href="../static/css/custom-styles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<script th:src="@{webjars/jquery/jquery.min.js}" type="text/javascript"></script>
<script th:src="@{webjars/popper.js/1.14.3/umd/popper.min.js}" type="text/javascript"></script>
<script th:src="@{webjars/bootstrap/js/bootstrap.min.js}" type="text/javascript"></script>
<script th:src="@{webjars/bootstrap-datepicker/js/bootstrap-datepicker.min.js}" type="text/javascript"></script>
<!-- Other simple web content... -->
<!-- Example straight from Bootstrap 4 documentation https://getbootstrap.com/docs/4.4/components/navs/#tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">...</div>
</div>
</body>
The tab titles (or nav-items) just get displayed as a normal unordered list, with all the actual tabs' contents being displayed all together below that.
As I said, as far as I can tell, the script files are getting loaded properly. I have a Bootstrap datepicker set up and working on the same page, but without the Bootstrap styles. I need to use the bootstrap-datepicker.standalone.css file, because bootstrap-datepicker.min.css doesn't work.
Things I have tried that did not work:
- Deleting the
WebConfigclass - Moving the css links into the body of the HTML document
- Putting a '/' in front of the
@{webjars/...}in the link tags. That does technically work for the Javascript stuff, but it made no difference with the css links. Furthermore, I need to leave the leading '/' off so the app will use page relative links, or else the app doesn't work when deployed to our staging environment - Specifying the version inside the
th:hreflike so:@{/webjars/bootstrap/4.1.1-1/css/bootstrap.min.css} - Taking other things out of the main HTML page until it's pretty much only testing the Bootstrap tabs (i.e. only importing the Bootstrap css and the Javascript files)
- Removing the
th:from the link element
The one thing I've done that does work is using the BootstrapCDN as seen on https://getbootstrap.com/ : <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
If I use that instead of the link I actually have in the HTML above, the styles are applied and everything works (as far as I can tell). However, I would like to know why I can't get the webjar to work, and if anyone else has had this problem. Or perhaps I am doing something obviously wrong which I am too close to see?
Just had the same (or very similar) problem using Bootstrap 4.5.0 The below worked for me:
In pom I have:
I do not have the
@Configurationclass - it actually started working when I removed it.My html starts with:
Hope this helps.
EDIT: Just had a look at your code again. You have
type="text.css"instead oftype="text/css"B.