Spring
Thymeleaf
Environment Variables
Java
Web Development

Get spring application environment in thymeleaf

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Spring applications often keep environment-specific values in application.properties or application.yml, but templates sometimes need to render those values too. The important design question is not only how to read a property in Thymeleaf, but whether the template should access the environment directly or receive a prepared value from the controller. Both approaches work, but they serve different goals.

The Cleanest Option: Pass Values Through the Model

The most maintainable pattern is usually to read configuration in Java code and pass only the values the template needs.

java
1import org.springframework.beans.factory.annotation.Value;
2import org.springframework.stereotype.Controller;
3import org.springframework.ui.Model;
4import org.springframework.web.bind.annotation.GetMapping;
5
6@Controller
7public class HomeController {
8
9    @Value("${app.banner-message}")
10    private String bannerMessage;
11
12    @GetMapping("/")
13    public String home(Model model) {
14        model.addAttribute("bannerMessage", bannerMessage);
15        return "home";
16    }
17}

Then the Thymeleaf template stays simple.

html
<p th:text="${bannerMessage}">Fallback text</p>

This approach keeps the template focused on rendering rather than configuration lookup. It is easier to test and avoids turning the view into a mini configuration client.

Access the Spring Environment Bean Directly

If you really need direct access inside a template, Thymeleaf can call Spring beans through the @beanName syntax. Because Environment is a Spring bean, you can expose or access it and read a property with getProperty.

html
<p th:text="${@environment.getProperty('spring.application.name')}">My App</p>

That expression asks the Spring bean named environment for a property value. It is useful for values such as application name, active profile labels, or feature switches that affect template fragments.

You can also provide a default value in Java before the property reaches the view layer if missing values should never surface in HTML.

Using a Dedicated Configuration Bean

A middle ground between raw environment access and controller-by-controller duplication is a dedicated configuration bean.

java
1import org.springframework.beans.factory.annotation.Value;
2import org.springframework.stereotype.Component;
3
4@Component("uiConfig")
5public class UiConfig {
6
7    @Value("${app.support-email}")
8    private String supportEmail;
9
10    @Value("${app.theme-name:default}")
11    private String themeName;
12
13    public String getSupportEmail() {
14        return supportEmail;
15    }
16
17    public String getThemeName() {
18        return themeName;
19    }
20}

The template can then read from that bean.

html
1<footer>
2  <span th:text="${@uiConfig.supportEmail}">[email protected]</span>
3  <span th:text="${@uiConfig.themeName}">default</span>
4</footer>

This is often a better choice than reaching into Environment everywhere because it gives configuration values stable names and a single place for defaults.

When Profiles Matter

Sometimes the template needs to know which profile is active. That can also be exposed through a bean or controller model. If you do it directly, keep the logic small.

java
1import org.springframework.core.env.Environment;
2import org.springframework.stereotype.Component;
3import java.util.Arrays;
4
5@Component("profileInfo")
6public class ProfileInfo {
7    private final Environment environment;
8
9    public ProfileInfo(Environment environment) {
10        this.environment = environment;
11    }
12
13    public String activeProfiles() {
14        return String.join(", ", Arrays.asList(environment.getActiveProfiles()));
15    }
16}
html
<p th:text="${@profileInfo.activeProfiles()}">default</p>

That keeps profile formatting out of the template and still gives the view what it needs.

Common Pitfalls

A common mistake is putting too much environment logic directly in the Thymeleaf template. A simple property lookup is fine, but once templates start branching on many config values, the view becomes harder to reason about and harder to test.

Another mistake is assuming every missing property should quietly render as blank text. That can hide deployment mistakes. If a property is required, set a default explicitly or fail fast in configuration code instead of silently generating incomplete pages.

Developers also often confuse system environment variables with Spring configuration properties. In Spring Boot, many sources can feed the Environment, including property files, system properties, command-line flags, and actual OS environment variables. The template is usually reading Spring's resolved property view, not raw operating system variables.

Finally, avoid exposing sensitive configuration to the browser. A template should never render secrets such as tokens, passwords, or private connection details just because the application can technically read them.

Summary

  • The simplest and cleanest pattern is to read configuration in Java and pass the needed values into the Thymeleaf model.
  • Direct property lookup in Thymeleaf can work through a Spring bean such as @environment.
  • A dedicated configuration bean is often a better long-term option than raw environment access everywhere.
  • Treat active profiles and other derived config values as view data, not template logic.
  • Never expose sensitive configuration just because it is available in the Spring environment.

Course illustration
Course illustration

All Rights Reserved.