Reputation: 452
I'm started to learning MEAN stack and when I went to Express I saw that existed a extra layer in the express framework that is called NestJS. It had all what I wanted and it had an Angular-like syntax so was perfect to me.
But every new step is a nightmare documentation isn't usefull at all. Now I'm fighting with the framework to achieve to serve images and dont use the API for this kind of calls.
I tried all that I found on Internet, for example:
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as bodyParser from 'body-parser';
import * as express from 'express';
import { join } from 'path';
import { NestExpressApplication } from '@nestjs/platform-express';
declare const module: any;
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
app.enableCors({
origin: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
});
//I tried this 2 options (https://docs.nestjs.com/techniques/mvc) (https://whatthecode.dev/serve-static-files-with-nest-js/)
app.use('/resources', express.static(process.cwd() + '\\resources'));
app.useStaticAssets(join(__dirname, '..', '\\public'));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
//console.log(process.cwd());
await app.listen(3000);
if (module.hot) {
module.hot.accept();
module.hot.dispose(() => app.close());
}
}
bootstrap();
I tried to put it in the app.module as this (it worked but is always looking for an index.html not images):
import { AnimalsModule } from './animals/animals.module';
import { SpeciesModule } from './species/species.module';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { BreedModule } from './breed/breed.module';
import { StateModule } from './state/state.module';
import { PhotoModule } from './photo/photo.module';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'), // <-- path to the static files
}),
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '',
database: 'nest',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
AnimalsModule,
SpeciesModule,
BreedModule,
StateModule,
AuthModule,
UsersModule,
PhotoModule,
],
})
//It seems that ignores this register and just uses the method signature options
@Module({
imports: [MulterModule.register({
dest: './resources/tmp',
limits: { fieldSize: 25 * 1024 * 1024 * 1024, fileSize: 25 * 1024 * 1024 * 1024 }
})],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
How the hell I can serve images or files and avoid the api routing?
Thanks to all.
Upvotes: 34
Views: 64761
Reputation: 1
use this in main.ts
app.enableCors({
origin: ['https://phish-orcin.vercel.app', 'http://localhost:3000','https://phish-orcin.vercel.app/', 'http://localhost:3000/'],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
allowedHeaders: ['Content-Type', 'Authorization'],
});
// Use helmet with Cross-Origin-Resource-Policy header
app.use(
helmet({
crossOriginResourcePolicy: { policy: 'cross-origin' }, // Allow cross-origin resources
}),
);
//app.module
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
serveRoot: '/', // Serve images from /images path
}),
Upvotes: 0
Reputation: 5410
My issue is resolve with i use like that :).
if you want to access your folder as different name then you can use like that.
Here my actual folder path is => assets/product_images/flower4.jpg
now i want to access like that => staticAssets/product_images/flower4.jpg
so using the above code i able to access my images using staticAssets/product_images/flower4.jpg this url
Upvotes: 1
Reputation: 21
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', '/uploads/public'),
serveStaticOptions: { index: false },
}),
],
})
export class AppModule {}
This will serve images from /dist/uploads/public/
You can access the files or images from, http://localhost:3000/x.jpg
Upvotes: 2
Reputation: 1161
To serve static files, including images, in a NestJS application, you can use the express.static
middleware provided by the Express framework, which is integrated into NestJS. Here's how you can set it up:
Create a folder in your project's directory to store your public images. For example, you can create a folder named public
at the root level of your project.
Move your images into the public
folder. You can organize them into subdirectories if necessary.
Open the main.ts
(or main.js
) file in the root directory of your NestJS application.
Import the express
module from the @nestjs/platform-express
package and the join function from the path module.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import * as express from 'express';
import { join } from 'path';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// Add the following code
app.use('/static', express.static(join(__dirname, '..', 'public')));
await app.listen(3000);
}
bootstrap();
In the code above, we're telling the application to serve static files from the public folder when the URL starts with /static
. You can change the /static
part to any URL prefix you desire.
You can access your public images using the URL pattern: http://localhost:3000/static/image.jpg
Upvotes: 0
Reputation: 85
In app.module.ts
:
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, ".."),
renderPath: "public",
}),
],
})
export class AppModule {}
rootPath
- Static files root directory. Default: "client"
renderPath
- Path to render static app (concatenated with the serveRoot value). Default: * (wildcard - all paths).
(https://www.npmjs.com/package/@nestjs/serve-static)
rootPath
to project root directory and renderPath
to your static files.Upvotes: 1
Reputation: 41
you can move to root directory, if your upload folder is in rootdir then put the path of folder in renderPath like this.
ServeStaticModule.forRoot({
rootPath: join(__dirname, '../../'),
renderPath: '/uploads',
})
Upvotes: 4
Reputation: 23
I had the same issue. I also struggled with this issue for a very long time. For example: you have uploads folder for picture. In App.module you need use it:
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'client'),
}),
localhost:3000/picture.png
if i use without 'client' folder, my picture is
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..'),
}),
localhost:3000/client/picture.png
Upvotes: 2
Reputation: 222
The main method of document nest using the module is as follows:
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'upload'), // path to the static files image
}),
But if you get the error for searching the index.html
, you can use this method, which I also used
main.ts
import * as express from 'express';
app.use(express.static(join(__dirname, '../upload')))
Upvotes: 0
Reputation: 5066
Separate module solution, then import it into AppModule.
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { resolve } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot(
(() => {
const publicDir = resolve('./public/files/');
const servePath = '/files';
return {
rootPath: publicDir,
// serveRoot - if you want to see files on another controller,
// e.g.: http://localhost:8088/files/1.png
serveRoot: servePath,
exclude: ['/api*'],
};
})()
),
],
})
export class PublicModule {}
Upvotes: 2
Reputation: 6760
There are two ways to serve static content in NestJs
. Either use 1
OR 2
.
1.Using ServeStaticModule
in app.module.ts
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { mainModule } from 'process'
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
}),
],
})
export class AppModule {}
2.Using NestExpressApplication
in main.ts [Even by default Nest Js uses Express only]
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(
AppModule,
);
app.useStaticAssets(join(__dirname, '..', 'public'));
await app.listen(3000);
}
bootstrap();
Upvotes: 9
Reputation: 764
You can use express static module in nest js too.
// ...imports
import * as express from 'express';
import { join } from 'path';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// serve static assets from the client/dist folder, change this to the correct path for your project
app.use(express.static(join(process.cwd(), '../client/dist/')));
//... you config
await app.listen(process.env.PORT);
}
bootstrap();
Credit to : https://whatthecode.dev/serve-static-files-with-nest-js/
Upvotes: -1
Reputation: 653
Use the useStaticAssets()
method (the ServeStaticModule
is for serving static content like SPAs).
So as a minimal example, your main.ts
should look like the following):
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
await app.listen(3000);
}
In the above example your assets are served from the root of your application (e.g. http://localhost:3000/example.png
.
You can also pass options to the method in oder to configure the path from which the assets are served:
app.useStaticAssets(join(__dirname, '..', 'public'), {
prefix: '/public/',
});
In this example your path is prefixed with public
(e.g. http://localhost:3000/public/example.png
)
Upvotes: 36
Reputation: 2723
The idea of @pzabrocki brings me to the following minimal working repository: https://gitlab.com/hadrien-toma/nest-static-files
To play with it:
git clone https://gitlab.com/hadrien-toma/nest-static-files
yarn install
yarn run start
Then the my-file.json
is served at http://localhost:3333/my-file.json
.
Upvotes: 0
Reputation: 9
add this to main.ts replace "uploads" with your directory name app.use('/uploads',express.static(join(process.cwd(), 'uploads')));
Upvotes: 0
Reputation: 297
This is what I've done:
in app.module.ts
import { ServeStaticModule } from '@nestjs/serve-static/dist/serve-static.module';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
}),
],
})
Then I created "public" dir on the same level as "src", "dir" etc.
The file is available at: https://my-url/file.jpg
Upvotes: 27