Search code examples
expressrouternestjs

NestJS - Default (wildcard) route?


In my Angular app, if I load the home page / and then navigate to, say, /products, it works fine (it's a lazy-loaded module). But if now I reload the page, the browser makes a GET /products call to the server, which results in a 404.

The solution is to send index.html and the Angular app is back on rails. So in Express I do app.all("*", (req,res) => { res.sendFile("index.html") }) and it works.

How to do the same thing in Nest?

There is a @All decorator, but each controller in a given component handles a subroute, for instance @Controller("cats") will match /cats routes, so if I add @All in this controller, it will match only /cats/*, not *.

Must I really create a whole separate module with a controller, just for this? That's what I did

@Controller() // Matches "/"
export class GenericController {

    @All() // Matches "*" on all methods GET, POST...
    genericFunction(){
        console.log("Generic route reached")
    }
}

And in my main module :

@Module({
    imports: [
        ItemsModule, // Other routes like /items
        GenericModule, // Generic "*" route last
    ],
})

It works, but it seems overkill. Is this the way to go or is there a simpler trick?


Solution

  • So, will be best to use global-scoped exception filter.

    async function bootstrap() {
      const app = await NestFactory.create(ApplicationModule);
      app.useGlobalFilters(new NotFoundExceptionFilter());
      await app.listen(3000);
    }
    bootstrap();
    

    NotFoundExceptionFilter:

    import { ExceptionFilter, Catch, NotFoundException } from '@nestjs/common';
    import { HttpException } from '@nestjs/common';
    
    @Catch(NotFoundException)
    export class NotFoundExceptionFilter implements ExceptionFilter {
        catch(exception: HttpException, host: ArgumentsHost) {
            const ctx = host.switchToHttp();
            const response = ctx.getResponse();
            // here return `index.html`
        }
    }
    

    Maybe it will not work, will test later