NestJs Swagger how to add custom favicon

Viewed 2158

I am trying to add a custom favicon to my NestJs documentation. However, I am a bit lost on how the path file gets resolved and not sure how to achieve this.

I am using nestjs/swagger module version 3.1.0 and trying to pass the path file like so when initializing the Swagger Module.

My main.ts file

SwaggerModule.setup('/v1/docs', app, document, {
    customCss: CUSTOM_STYLE,
    customSiteTitle: 'My API Documentation',
    customfavIcon: './public/favicon.jpg'
});

Searched on the github issues and didn't find anything useful. And as you can see from the code I was able to modify the CSS styles, but I cannot figure out how to make the favicon custom.

Appreciate any help

3 Answers

I have added the custom favicon to my swagger docs using following:

The first thing you make sure is, in your main.ts, the app is initialized with the following:

const app: NestExpressApplication = await NestFactory.create(...)

To serve static content you must initialize your app with NestExpressApplication.

The next thing is to allow the Nest application to look for public content using the following in your main.ts after initialization:

app.useStaticAssets(join(__dirname, '..', 'public'));

Also, create a public directory in your root of the application and paste your favicon.jpg file in it.

Now its time to initialize the Swagger in main.ts

SwaggerModule.setup('/v1/docs', app, document, {
    customCss: CUSTOM_STYLE,
    customSiteTitle: 'My API Documentation',
    customfavIcon: '../favicon.jpg'
});

You must give a relative path to the root of the application like ../favicon.jpg in case our main.ts is in src folder in root of the application.

Alternative solution, just host your favicon and reference it with external url

  SwaggerModule.setup('api', app, getSwaggerDocument(app), {
    ...
    customfavIcon:
      'https://[your-bucket-url].com/.../anything.png',
  });

To iterate on pravindot17's answer, now there's the @nestjs/serve-static package for hosting static files. Which avoid us from type-casting the Nest.js client and relying on our implicit assumption that we're running an Express-backed Nest.js server.

After installing the package, you hook it into your src/app.module.ts. This configuration expects that the root of your project has a /public/ folder where you store your static assets.

import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    // Host static files in ../public under the /static path.
    ServeStaticModule.forRoot({
      /**
       * Config options are documented:
       * https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts
       */
      rootPath: join(__dirname, '..', '..', 'public'),
      serveRoot: '/static',
    }),
    // ... 
})
export class AppModule {}

Now my own preference is using an absolute path rather than relative, as it makes it independent from the path we picked to host our API documentation under.

SwaggerModule.setup('/v1/docs', app, document, {
    customfavIcon: '/static/favicon.jpg'
});

One last note is that this configuration hosts static files from /static/*, this is done to prevent that API calls to non-existing endpoints show an error message to the end-user that the static file cannot be found.

Otherwise, all 404's on non-existing endpoints will look something like:

{"statusCode":404,"message":"ENOENT: no such file or directory, stat '/Users/me/my-project/public/index.html'"}
Related