How to Serve Static Files in NestJS

Updated: January 1, 2024 By: Guest Contributor Post a comment

Introduction

Learn to efficiently serve static resources like images, JavaScript, and CSS in a NestJS application with focused examples guiding you from the basics to advanced configurations.

Getting Started with NestJS

NestJS is a modern, progressive Node.js framework for building efficient and scalable server-side applications. It is built with and fully supports TypeScript but still enables developers to code in pure JavaScript.

To serve static files, like images, CSS, and JavaScript, with NestJS, you need to first set up a basic server:

$ npm i -g @nestjs/cli
$ nest new project-name

After installing the CLI and creating a new project, you can then proceed to serve static files.

Serving Static Files: Basic Approach

To start serving static files, let’s install the required module:

$ npm install --save @nestjs/serve-static

Then import ServeStaticModule in your application module:

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

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'public'),
    }),
  ],
})
export class AppModule {}

With this, any file inside the ‘public’ directory will be served directly.

Custom Routes for Static Files

If you wish to serve files on a specific route, you’d adjust the configuration:

imports: [
  ServeStaticModule.forRoot({
    rootPath: join(__dirname, '..', 'static'),
    serveRoot: '/my-static',
  }),
],

Now, your static files will be accessible through http://localhost:3000/my-static.

Serving Multiple Static Assets

NestJS also allows you to serve multiple static directories. Each with their options:

imports: [
  ServeStaticModule.forRoot([
    {
      rootPath: join(__dirname, '..', 'public'),
    },
    {
      rootPath: join(__dirname, '..', 'files'),
      serveRoot: '/files',
    },
  ]),
],

This serves files from both ‘public’ and ‘files’ directories under different routes.

Advanced Configurations

Beyond basic file serving, NestJS’s static module includes advanced configurations such as setting cache control, defining custom headers, or excluding certain paths. For instance, to set a maximum cache live:

imports: [
  ServeStaticModule.forRoot({
    rootPath: join(__dirname, '..', 'public'),
    maxAge: 60 * 60000,  // Maximum age in milliseconds
  }),
],

Similarly, to exclude paths:

imports: [
  ServeStaticModule.forRoot({
    rootPath: join(__dirname, '..', 'public'),
    exclude: ['/api*'],
  }),
],

Now, all routes starting with ‘/api’ will bypass static treatment.

Serving Single Page Applications (SPA)

For SPAs like Angular or React, you’d often want your index.html to be served for any unmatched routes. NestJS can handle this as well:imports: [ ServeStaticModule.forRoot({ // Other configurations serveStaticOptions: { index: false, redirect: false }, }), ],

Then, within your main application controller, you can capture those routes and return the index.html file:

@Controller('*')
class ViewController {
  @Get()
  root(@Res() response: Response) {
    response.sendFile(join(__dirname, '..', 'public', 'index.html'));
  }
}

Deployment and Production Tips

Before deploying your application, remember to compile your TypeScript to JavaScript, bundle your frontend application appropriately, and verify that all static files are correctly placed in your ‘public’ or ‘static’ directories. It’s also a good idea to examine the impact of caching and HTTP headers on the user experience and SEO.

Make sure to also consider other web server settings, reverse proxies, and content delivery networks (CDN) for serving your static files in a production environment.

Conclusion

Serving static files in NestJS is straightforward with the right module and configuration. Whether you’re building a simple website or an intricate Single Page Application, NestJS provides the tools necessary for an efficient and scalable static file delivery system. Always validate your setup before going into production to ensure the best performance and user experience.