DEV Community

Cover image for Como deixar o Swagger com tema dark mode usando NestJS
Wiliam V. Joaquim
Wiliam V. Joaquim

Posted on

Como deixar o Swagger com tema dark mode usando NestJS

O tema padrão claro do Swagger já incomodou você? Isso já me incomodou muito e hoje vou mostrar como deixar em Dark mode para quem utiliza o NestJS.

O que é o Swagger?

Vou explicar de forma bem resumida, o Swagger é uma aplicação open source que facilita a documentação da sua API, fornece ao usuário que vai consumir sua API uma forma simples de usar sua rotas, ver os erros retornados, dados retornados entre outros. O Swagger utiliza o padrão da OpenAPI.

Por padrão o tema do SwaggerUi é branco:

Swagger claro

Mas, como podemos deixar esse tema dark? Bom, existem duas formas de fazer isso usando NestJS, ainda não temos suporte nativamente do Swagger para isso (existe um PR aberto, para implementar essa opção, veja aqui), mas até a data da publicação este post ainda não foi implementado.

Vamos criar um projeto com NestJS:

npm i -g @nestjs/cli
nest new swagger-dark-mode
Enter fullscreen mode Exit fullscreen mode

Agora, vamos instalar e configurar o swagger no NestJS, conforme a documentação:

npm install --save @nestjs/swagger
Enter fullscreen mode Exit fullscreen mode

No fim, nosso main.js deve ficar assim:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

Rodando o projeto com npm run start:dev e acessando a api (http://localhost:3000/api), temos essa tela:

Swagger docs nestjs

Agora, vamos deixar em modo dark, como dito anteriormente, não existe o suporte nativo do swagger para dark mode, mas vamos injetar nosso CSS, para isso vamos ajustar as configs do swagger no nosso main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {
  DocumentBuilder,
  SwaggerCustomOptions,
  SwaggerModule,
} from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);

  const myCustom: SwaggerCustomOptions = {
    customSiteTitle: 'Swagger dark mode',
    customCss: ``,
    swaggerOptions: {
      docExpansion: 'none',
      apisSorter: 'alpha',
    },
  };

  SwaggerModule.setup('api', app, document, myCustom);

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

Separamos algumas configs em myCustom, o SwaggerCustomOptions nos permite informar algumas opções:

customSiteTitle: Alteramos o title da nossa documentação.
customCss: Aqui é onde vamos colocar nosso css personalizado.
docExpansion: Podemos determinar se cada rota abre expandido ou recolhido:

Conforme exemplo abaixo, isso facilita quando sua documentação possui muitas rotas.

swagger usando docExpansion

apisSorter: Usando a opção alpha, vai ordenar as tags por ordem alfabética.

Existem muitas outras opções, você pode conferir acessando a tipagem do SwaggerCustomOptions.

Vamos ao css, vou deixar aqui um gist (clicando aqui), com o css que já deixa em dark mode, mas você pode editar como quiser, ou buscar temas já prontos.

Ficaria assim:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {
  DocumentBuilder,
  SwaggerCustomOptions,
  SwaggerModule,
} from '@nestjs/swagger';
import { css } from './swagger/custom-css';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);

  const myCustom: SwaggerCustomOptions = {
    customSiteTitle: 'Swagger dark mode',
    customCss: css,
    swaggerOptions: {
      docExpansion: 'none',
      apisSorter: 'alpha',
    },
  };

  SwaggerModule.setup('api', app, document, myCustom);

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

Apenas importamos o nosso css e colocamos em customCss e pronto, dark mode funcionando:

swagger dark mode

Com o css, podemos alterar qualquer coisa do layout padrão.

Existe outra forma de utilizar o dark mode no swagger com NestJS, usando o pacote swagger-themes.

Veja como ficaria o nosso main.ts, utilizar esse pacote:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {
  DocumentBuilder,
  SwaggerCustomOptions,
  SwaggerModule,
} from '@nestjs/swagger';
import { SwaggerTheme } from 'swagger-themes';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);

  const theme = new SwaggerTheme('v3');

  const myCustom: SwaggerCustomOptions = {
    customSiteTitle: 'Swagger dark mode',
    customCss: theme.getBuffer('dark'),
    swaggerOptions: {
      docExpansion: 'none',
      apisSorter: 'alpha',
    },
  };

  SwaggerModule.setup('api', app, document, myCustom);

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

Fica bem mais simples, basta instanciar o SwaggerTheme com const theme = new SwaggerTheme('v3'); e depois no customCss, informar o tema desejado theme.getBuffer('dark').

Temos algumas opções de temas como, dark, monokai, material entre outros, veja as opções na documentação do swagger-themes, veja como ficaria o monokai:

swagger monokai tema

Mas se podemos usar o swagger-theme, por que deveríamos alterar o CSS manualmente?

Bom, alterando o CSS manualmente, temos o poder e liberdade de alterar o tema da forma que desejarmos, podemos alterar cores, logo, textos, entre outros, mas se você deseja apenas colocar um tema dark, usar o swagger-theme pode ser a forma mais fácil e rápida de fazer isso.

Top comments (4)

Collapse
 
micalevisk profile image
Micael Levi L. C. • Edited

Vale mencionar que aquele CSS do gist acaba escondendo os schemas que ficam no fim da página.

Resolvi isso removendo as seguintes regras que estão lá:

.swagger-ui section.models.is-open  {
  display: none !important;
}
Enter fullscreen mode Exit fullscreen mode
.swagger-ui section.models {
  visibility: hidden;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
wiliamvj profile image
Wiliam V. Joaquim

Boa observação, essa regra está aplicada a meu caso de uso, não precisamos desses schemas.

Collapse
 
micalevisk profile image
Micael Levi L. C.

uma outra forma de esconder aquela seção é usando defaultModelsExpandDepth: -1 no swaggerOptions

Thread Thread
 
wiliamvj profile image
Wiliam V. Joaquim

Boa, não sabia dessa opção, vou utilizar. Obrigado