NestJs: multiple views directory

Viewed 4100

I am developing an MVC app using nestJs framework, and I used the hbs template-engine.

According to the documentation I have to use this configuration to make nestjs able to serve views:

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

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}

This configuration assumes that all views are located in one directory (views) but what if every module has its own views?

2 Answers

Since v5.7.0

You can set an array of directories:

app.setBaseViewsDir([
  join(__dirname, '..', 'users/views'), 
  join(__dirname, '..', 'books/views'),
]);

Before v5.7.0

In express, you can set an array of base path directories:

A directory or an array of directories for the application's views. If an array, the views are looked up in the order they occur in the array.

However, the typings in nest.js do not allow for an array, see issue. I've created a pull request, that will change that.

Until the pull request is merged, you can do:

app.setBaseViewsDir([
    join(__dirname, '..', 'users/views'), 
    join(__dirname, '..', 'books/views'),
  ] as any);

As soon as the pull request is merged, you can remove the as any.

I'm assuming you have an app structure similar to this:

src
  main.ts
  /users
       users.controller.ts
       /views
         my-view.hbs
  /books
       books.controller.ts
       /views
         my-view.hbs

Then you can set the base view dir to src:

app.setBaseViewsDir(__dirname);

And reference the view with its relative path in your controllers:

@Controller('users')
export class UsersController {

  @Render('users/views/my-view')
           ^^^^^^^^^^^^^^^^^^^
  @Get()
  async getMyView() {
Related