DEV Community

Taui Silva
Taui Silva

Posted on

2

Personalizando o Swagger UI no Spring Boot: Como Aplicar um Tema Dark

O que é o Swagger?

O Swagger é uma poderosa ferramenta para documentar, testar e interagir com APIs REST, proporcionando uma experiência mais intuitiva para desenvolvedores e consumidores da API. Ele permite visualizar e interagir com endpoints no navegador, facilitando a compreensão e validação do serviço.

No Spring Boot, é integrado via Springdoc OpenAPI, oferecendo uma interface intuitiva para explorar endpoints, visualizar modelos e testar requisições HTTP.

Por padrão, o Swagger usa um design com cores claras. Veja um exemplo:

Swagger-padrão

No entanto, em alguns casos, pode ser necessário personalizar sua aparência para adequá-lo à identidade visual do projeto. Neste artigo, mostrarei como modificar o CSS do Swagger para aplicar um tema escuro (dark mode).


Configurando o projeto

Neste exemplo, utilizaremos as seguintes versões:

  • Spring Boot 3.4.3
  • Springdoc OpenAPI 2.8.5

Se o seu projeto ainda não está configurado, você pode criá-lo rapidamente usando o Spring Initializr.

Adicionando a dependência do Springdoc

No arquivo pom.xml, adicione a seguinte dependência:

<!-- Dependência do Swagger para Spring Boot -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.8.5</version> <!-- Sempre verifique a versão mais recente -->
</dependency>
Enter fullscreen mode Exit fullscreen mode

Configurações básicas do Swagger

Agora, configure o Swagger no arquivo application.properties ou application.yml:

Usando application.properties

# Define o endpoint onde a documentação OpenAPI (Swagger) estará disponível
springdoc.api-docs.path=/api-docs  

# Define a versão do OpenAPI usada na documentação  
springdoc.api-docs.version=openapi_3_1  

# Habilita a interface do Swagger UI  
springdoc.swagger-ui.enabled=true  

# Define o caminho da interface gráfica do Swagger UI  
springdoc.swagger-ui.path=swagger-ui.html  

# Ordena as operações na interface do Swagger UI pelo método HTTP (GET, POST, etc.)  
springdoc.swagger-ui.operationsSorter=method  

# Ordena as tags alfabeticamente na interface do Swagger UI  
springdoc.swagger-ui.tagsSorter=alpha  

# Garante que os cabeçalhos HTTP sejam corretamente repassados quando o app está atrás de um proxy reverso (ex: Nginx, Kubernetes)  
server.forward-headers-strategy=framework  
Enter fullscreen mode Exit fullscreen mode

Usando application.yml

springdoc:
  api-docs:
    path: /api-docs
    version: openapi_3_1
  swagger-ui:
    enabled: true
    path: swagger-ui.html
    operations-sorter: method
    tags-sorter: alpha

server:
  forward-headers-strategy: framework
Enter fullscreen mode Exit fullscreen mode

Configurando a classe principal

Agora, vamos configurar a classe principal da aplicação. O Spring Boot utiliza a anotação @SpringBootApplication para definir o ponto de entrada do projeto. Além disso, podemos utilizar @OpenAPIDefinition para definir informações básicas da documentação Swagger, como título, versão e descrição.

Caso o projeto utilize autenticação com JWT, também podemos configurar um esquema de segurança usando @SecurityScheme. Se o seu projeto não exige autenticação, essa configuração pode ser removida sem impactar o funcionamento do Swagger.

Veja abaixo a estrutura da classe principal:

@SpringBootApplication
@OpenAPIDefinition(info = @Info(
    title = "Título da Aplicação", 
    version = "0.1", 
    description = "Descrição da aplicação"
))
@SecurityScheme(
    name = "bearerAuth",
    description = "JWT auth",
    scheme = "bearer",
    type = SecuritySchemeType.HTTP,
    bearerFormat = "JWT",
    in = SecuritySchemeIn.HEADER
)
public class SwaggerDarkApplication {

    public static void main(String[] args) {
        SpringApplication.run(SwaggerDarkApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

Explicação das anotações:

  • @SpringBootApplication → Define a classe principal do projeto Spring Boot.
  • @OpenAPIDefinition → Configura informações básicas da API, como título, versão e descrição.
  • @SecurityScheme (opcional) → Define a autenticação via JWT para proteger a API. Caso seu projeto não use autenticação, essa anotação pode ser removida.

Com tudo configurado, agora podemos iniciar a aplicação e acessar a documentação interativa no Swagger UI através do seguinte caminho:

🔗 http://localhost:8080/swagger-ui/index.html

⚠️ Nota: O exemplo acima usa a porta padrão 8080 do Spring Boot. Se sua aplicação estiver rodando em outra porta, basta ajustá-la na URL conforme necessário.

Inicialização do swagger

Agora podemos partir para a criação do arquivo CSS para personalizar o Swagger UI.


Criando o arquivo CSS

O Swagger UI permite personalização por meio de arquivos CSS estáticos na pasta static dentro de resources. Vamos criar essa estrutura e adicionar um arquivo de estilo para aplicar o tema.

No seu projeto, dentro de src/main/resources, crie uma pasta static (caso ainda não exista) e adicione um arquivo chamado swagger-theme.css.

A estrutura do projeto ficará assim:

├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── swagger_dark/
│   │   │           ├── SwaggerDarkApplication.java
│   │   ├── resources/
│   │   │   ├── application.properties
│   │   │   └── static/
│   │   │       └── swagger-theme.css
Enter fullscreen mode Exit fullscreen mode

Agora que o arquivo swagger-theme.css está no lugar certo, podemos adicionar as regras de estilo para personalizar o Swagger UI.

Deixarei o link do GitHub com o projeto e o CSS aplicado no fim do post.

    .swagger-ui .topbar .download-url-wrapper .select-label select {
        border: 2px solid var(--swagger-color);
    }

    .swagger-ui .info .title small.version-stamp {
        background-color: var(--swagger-color);
    }

    .swagger-ui .info .title small.version-stamp pre {
        color: #3A3D4C;
    }

    .swagger-ui .info a {
        color: var(--link-color);
    }

    .swagger-ui .response-control-media-type--accept-controller select {
        border-color: var(--accept-header-color);
    }

       /*... mais */

Enter fullscreen mode Exit fullscreen mode

Configurando o application.properties ou application.yml:

Para que o Swagger UI consiga carregar corretamente os arquivos estáticos, adicione as seguintes configurações:

application.properties:

spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=classpath:/static/
Enter fullscreen mode Exit fullscreen mode

application.yaml:

spring:
  mvc:
    static-path-pattern: /static/**
  web:
    resources:
      static-locations: classpath:/static/

Enter fullscreen mode Exit fullscreen mode

Isso garante que o Spring Boot consiga servir os arquivos dentro da pasta static corretamente.


Configurando a Injeção do CSS no Swagger UI

Para aplicar o CSS customizado ao Swagger UI, criaremos uma pasta chamada swagger dentro do pacote principal e adicionaremos dois arquivos:

  1. SwaggerConfig.java → Define um Bean para que o Spring reconheça a configuração do Swagger.
  2. SwaggerCustomCssInjector.java → Modifica a página inicial do Swagger UI e injeta nosso CSS.

SwaggerConfig.java:
Este arquivo configura o Bean responsável por inicializar a customização do Swagger.

package com.swagger_dark.swagger_dark.swagger;

import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.core.properties.SwaggerUiOAuthProperties;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webmvc.ui.SwaggerIndexTransformer;
import org.springdoc.webmvc.ui.SwaggerWelcomeCommon;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SwaggerConfig {

  @Bean
  public SwaggerIndexTransformer swaggerIndexTransformer(
    SwaggerUiConfigProperties swaggerUiConfig,
    SwaggerUiOAuthProperties swaggerUiOAuthProperties,
    SwaggerWelcomeCommon swaggerWelcomeCommon,
    ObjectMapperProvider objectMapperProvider) {

    return new SwaggerCustomCssInjector(swaggerUiConfig, swaggerUiOAuthProperties, swaggerWelcomeCommon, objectMapperProvider);
  }
}
Enter fullscreen mode Exit fullscreen mode

SwaggerCustomCssInjector.java:
Este arquivo é responsável por modificar a página inicial do Swagger UI (index.html) e injetar nosso CSS.

package com.swagger_dark.swagger_dark.swagger;

import jakarta.servlet.http.HttpServletRequest;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.core.properties.SwaggerUiOAuthProperties;
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.webmvc.ui.SwaggerIndexPageTransformer;
import org.springdoc.webmvc.ui.SwaggerWelcomeCommon;
import org.springframework.core.io.Resource;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.resource.ResourceTransformerChain;
import org.springframework.web.servlet.resource.TransformedResource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class SwaggerCustomCssInjector extends SwaggerIndexPageTransformer {
  public SwaggerCustomCssInjector(
    final SwaggerUiConfigProperties swaggerUiConfig,
    final SwaggerUiOAuthProperties swaggerUiOAuthProperties,
    final SwaggerWelcomeCommon swaggerWelcomeCommon,
    final ObjectMapperProvider objectMapperProvider) {
    super(swaggerUiConfig, swaggerUiOAuthProperties, swaggerWelcomeCommon, objectMapperProvider);
  }

  @Override
  public @NonNull Resource transform(
    @NonNull HttpServletRequest request,
    @NonNull Resource resource,
    @NonNull ResourceTransformerChain transformer) throws IOException {
    if ("index.html".equals(resource.getFilename())) {
      try (InputStream in = resource.getInputStream();
           BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
        String html = reader.lines().collect(Collectors.joining(System.lineSeparator()));
        String transformedHtml = injectCss(html);
        return new TransformedResource(resource, transformedHtml.getBytes());
      }
    }
    return super.transform(request, resource, transformer);
  }

  private String injectCss(String html) {
    String cssPath = "/static/swagger-theme.css";
    return html.replace("</head>", "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + cssPath + "\" /></head>");
  }
}
Enter fullscreen mode Exit fullscreen mode

No fim temos a seguinte estrutura:

Diretório:
└── swagger-dartk-spring-boot/
    ├── mvnw
    ├── mvnw.cmd
    ├── pom.xml
    ├── src/
    │   ├── main/
    │   │   ├── java/
    │   │   │   └── com/
    │   │   │       └── swagger_dark/
    │   │   │           └── swagger_dark/
    │   │   │               ├── SwaggerDarkApplication.java
    │   │   │               ├── exemple/
    │   │   │               │   ├── ExampleController.java
    │   │   │               │   └── ExampleDTO.java
    │   │   │               └── swagger/
    │   │   │                   ├── SwaggerConfig.java
    │   │   │                   └── SwaggerCustomCssInjector.java
    │   │   └── resources/
    │   │       ├── application.properties
    │   │       └── static/
    │   │           └── swagger-theme.css
    │   └── test/
    │       └── java/
    │           └── com/
    │               └── swagger_dark/
    │                   └── swagger_dark/
    │                       └── SwaggerDarkApplicationTests.java
    └── .mvn/
        └── wrapper/
            └── maven-wrapper.properties
Enter fullscreen mode Exit fullscreen mode

Resultado Final

Após finalizar as configurações, adicionei alguns endpoints e iniciei o projeto. Agora, o tema está aplicado conforme as modificações feitas no CSS:

Swagger com tema modificado

Com essas configurações, o Swagger UI agora carregará automaticamente o arquivo swagger-theme.css, permitindo personalizar seu visual.

Agora sua API não apenas está documentada e testável, mas também personalizada para refletir a identidade visual do seu projeto. Você pode explorar outras customizações no Swagger UI, como a modificação de fontes, ícones e até mesmo a inclusão de novas funcionalidades com JavaScript.

Para conferir o código completo e as configurações, acesse o repositório no GitHub:

Swagger-dartk-spring-boot

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay