Search code examples
javascriptexpressnestjs

How to serve static files on nestjs?


I have a nestjs project, in the root of the site there is an uploads folder, there are files of different extensions there. How should I process them?

http://localhost:7777/uploads/audio/85/0.mp3 http://localhost:7777/uploads/movie/85/0.mp4

When I do this I get an error:

{ "statusCode": 404, "message": "ENOENT: no such file or directory, stat 'G:\myproject\uploads\index.html'" }

In App.module I did everything as in the nest documentation:

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


@Module({
   imports: [
     ServeStaticModule.forRoot({
       rootPath: join(__dirname, '../../../', 'uploads'),
     }),
     UsersModule

Main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './App/app.module';
import { ConfigService } from '@nestjs/config';
import { ValidationPipe } from '@nestjs/common';


async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);
  const port = configService.get('PORT'); 
  app.enableCors();
  app.useGlobalPipes(new ValidationPipe()); 
  await app.listen(port);
}
bootstrap();

Solution

  • Since it looks inside uploads folder already, it might be trying to look for uploads inside uploads if you know what I mean.

    So, you can explicitly mention it as a URL prefix like this

    @Module({
      imports: [
        ServeStaticModule.forRoot({
          rootPath: join(__dirname, '..', '..', 'uploads'),
          // Tell NestJS to serve the files under ~/uploads/
          serveRoot: '/uploads/',
        }),
      ],
    })
    export class AppModule {}
    

    Update

    I ran the repository you mentioned in comments and added a console log. Looks like it's trying to access uploads under the dist folder. This might be your other issue.

    debug

    Update 2

    I managed to get it working on the repository you added in the comments, by 2 things:

    • Adding a 3rd .. to account for the dist folder
    • More importantly: moving the code to run in a factory method

    Like this:

        ServeStaticModule.forRootAsync({
          useFactory: () => {
            const uploadsPath = join(__dirname, '..', '..', '..', 'uploads');
            return [
              {
                rootPath: uploadsPath,
                serveRoot: '/uploads/',
              },
            ];
          },
        }),
    

    Result:

    Success