$ sudo npm install @nestjs/cli -g
$ npx nest new nest_app
> npm
$ npm run start:dev
http://192.168.34.10:3000/
hello worldと表示されている
$ npm install ejs
nest-cli.json
{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
  	"assets": ["**/*.ejs"]
  }
}
main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';
import { join } from 'path'
async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.useStaticAssets(join(__dirname, '..', 'public'))
  app.setBaseViewsDir(join(__dirname, '..', 'views'))
  app.setViewEngine('ejs')
  
  await app.listen(3000);
}
bootstrap();
views/index.ejs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><%= title %></title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> </head> <body> <h1 class="bg-primary text-white p-2"><%= header %></h1> <div class="container py-2"> <h2 class="mb-3"><%= title %></h2> <div class="alert alert-primary"> <%= message %> </div> </div> </body> </html>
src/app.controller.ts
import { Controller, Get, Render } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
  @Get()
  @Render('index')
  root(){
  	return {
  		title: 'Nest sample app',
  		header: 'Nest.js',
  		message: 'Hello world!'
  	}
  }
}

index.ejs
<body>
  <h1 class="bg-primary text-white p-2"><%= title %></h1>
  <div class="container py-2">
  	<h2 class="mb-3"><%= msg %></h2>
  	<div class="alert alert-primary">
  		  <form method="post" action="/">
            <div class="mb-2">
              <label>ID:</label>
              <input type="text" name="id" class="form-control">
            </div>
            <div class="mb-2">
              <label>password:</label>
              <input type="password" name="pass" class="form-control">
            </div>
            <div>
              <input type="submit" value="送信" class="btn btn-info">
            </div>
        </form>
  	</div>
  </div>
</body>
src/app.controller.ts
import { Controller, Get, Post, Body, Render } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
  @Get('/')
  @Render('index')
  root(){
  	return {
  		title: 'Nest app',
  		msg: 'send form:'
  	}
  }
  @Post('/')
  @Render('index')
  send(@Body() form:any){
  	return {
  		title: 'Nest form',
  		msg: JSON.stringify(form)
  	}
  }
}

### Ajax
app.controller.ts
  @Post('/')
  send(@Body() form:any){
  	return form
  }
index.ejs
  <script src="index.js"></script>
</head>
<body>
  <h1 class="bg-primary text-white p-2"><%= title %></h1>
  <div class="container py-2">
  	<h2 class="mb-3"><%= msg %></h2>
  	<div class="alert alert-primary">
            <div class="mb-2">
              <label>ID:</label>
              <input type="text" name="id" class="form-control">
            </div>
            <div class="mb-2">
              <label>password:</label>
              <input type="password" name="pass" class="form-control">
            </div>
            <div>
              <input type="submit" value="送信" class="btn btn-info">
            </div>
  	</div>
  </div>
</body>
public/index.ts
import { Controller, Get, Post, Body, Render } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
  @Get('/')
  @Render('index')
  root(){
  	return {
  		title: 'Nest app',
  		msg: 'send form:'
  	}
  }
  @Post('/')
  send(@Body() form:any){
  	return form
  }
}
なんか上手く動いていないような気がするが…