-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React Routing #38
Comments
So I haven't actually tried this before, but messed around and think I found a solution. You will want to create your own global ExceptionFilter that passes the request and response to Next rather than handling it in Nest. I was able to get it working with the following code. Some things to keep in mind is that this will pass on all of your NotFoundExceptions to Next, depending on your use case this should probably be fine. Also it will route based on the filesystem path, if you have a some route /test it resolves to Let me know if this works for you! import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
Inject,
NotFoundException,
} from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { RenderModule, RenderService, RequestHandler } from 'nest-next';
import Next from 'next';
import 'reflect-metadata';
import { AppModule } from './application.module';
// Additional global filter to pass 404 errors onto next rather than
// handling in nest.
@Catch(NotFoundException)
export class NextPageFilter implements ExceptionFilter {
private requestHandler?: RequestHandler;
constructor(@Inject() private readonly renderService: RenderService) {
this.requestHandler = this.renderService.getRequestHandler();
}
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const res = ctx.getResponse();
const req = ctx.getRequest();
if (this.requestHandler) {
return this.requestHandler(req, res);
}
// the requestHandler technically should always be defined if the nest-next
// was correctly setup - rethrow just in case
throw exception;
}
}
async function bootstrap() {
const dev = process.env.NODE_ENV !== 'production';
const app = Next({ dev });
await app.prepare();
const server = await NestFactory.create(AppModule);
const renderer = server.get(RenderModule);
renderer.register(server, app);
const service = server.get(RenderService);
server.useGlobalFilters(new NextPageFilter(service));
await server.listen(3000);
}
bootstrap(); |
Could you try updating the code for that filter to call the request handler like Also I just wanted to confirm two things:
|
Good point! For (1) above, the order mattered - I was incorrectly setting it before it registered. Once it hit the filter, now seeing: |
I can confirm it's when using fastify. |
Solved the issue by returning this on NextPageFilter:
|
ah yeah, I forgot that fastify modifies the req and res. I believe that you can also do
That is how we handled it in render.filter.ts FWIW. |
This is exactly my use-case, I was actually surprised that it isn't the default. Do you think this could be included and enabled via an option? I used your solution and it works, except when NestJS is reloading with its incremental compilation, I got this error :
For the error to disappear, I need to delete the Maybe there is a conflict between the RenderModule and the NextPageFilter? Because I am calling |
@jgoux I think that should be possible. Just to clarify, you want all the requests that Nest thinks are 404s to be handled by Next's request handler? The only problem that I could see with this, is even if you throw a NotFoundException it would still be forwarded to nextjs. If we were to go this route I think it would resolve #47 and #48. Also I believe that calling Next tries to start the server, so the exception being thrown is probably because it sees something using the port. Can I ask why you're calling it from NextPageFilter? |
@kyle-mccarthy Sorry I meant I'm callling it from both So it seems to start the Next.js compilation twice in parallel. If we use the NextPageFilter approach, should we do anything special to the AppModule? import path from "path";
import { Module } from "@nestjs/common";
import { RenderModule } from "nest-next";
import Next from "next";
import { AppController } from "./app.controller";
import { PrismaService } from "./prisma/prisma.service";
@Module({
imports: [
RenderModule.forRootAsync(
Next({
dev: process.env.NODE_ENV !== "production",
dir: path.resolve(__dirname, "../../web"),
}),
{
viewsDir: null,
}
),
],
controllers: [AppController],
providers: [PrismaService],
})
export class AppModule {} If I omit to import RenderModule in this file, I got this error :
for the line Sorry it's maybe obvious but I'm beginning with NestJS ^^
Yes this is exactly what I want. :) |
@jgoux Oh yeah so this issue is a little older and uses the deprecated bootstrapping method - you don't need to call it in your bootstrap file anymore. See https://github.com/kyle-mccarthy/nest-next/blob/master/examples/basic/src/main.ts Also to follow up on my question, are you wanting to have all 404s be handled by next instead of nest handling it? This is a feature I would definitely be open to adding, and it could be controlled through an option like you suggested. |
Yes I don't mind having next handling all the 404s. What could be the downside? As a total outsider I really thought this was the default behaviour, and that you could add specific Nest handlers as you go. Just to be sure, following the modern bootstraping approach, is this the correct way to register the NextPageFilter? Or can it be moved to AppModule as well? async function bootstrap() {
const server = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);
const service = server.get(RenderService);
server.useGlobalFilters(new NextPageFilter(service));
await server.listen(3000);
} |
That is correct, since you need to provide the RenderService for your filter. And I don't really see any issue with passing the request to next when nest 404s, I will look into providing that option. |
This is awesome, thanks a lot for your answers and your work on this library! The NestJS ecosystem really seems great. 😄 |
Any chance you can provide an example project for this ? |
@jgoux @dayrim I've made the updates that will allow for you passthrough requests that 404 to next. It's currently on the next branch and you can preview it by doing a I've still got to update the main docs, but there are only two changes required to get started.
Both of those are highlighted in the example's ApplicationModule. As a side note, I couldn't think of a great name for the option so I took a pretty literal approach. LMK if you think there is a name that better describes the feature. |
Thanks for the change, I'll test it soon! Is there any way to support For the naming, maybe |
@jgoux I actually think that should be possible by omitting step 1 from my previous comment. The only reason I actually did that is so that next knows it should look in the |
@jgoux Did you have an opportunity to try this out? If it works for your use case, I can merge this and deploy a new version. |
@kyle-mccarthy No sorry I was on another subject. I'll try it this week and let you know. Thanks again for your patience. |
@kyle-mccarthy I'm getting the following error:
Any idea how I can get this working? Thanks |
@twigs67 hey thanks for checking this out - I just want to make sure that you have the right version installed since this currently isn't mastered. Did you add |
@kyle-mccarthy I did not. Sorry about that - should have read a bit more. Thanks! |
@twigs67 no problem at all - I actually do want to master this ASAP but have been awaiting feedback. If it works for your use case and works how you'd expect let me know and I'll master it + deploy a new version. |
@kyle-mccarthy yes, it did work for me. However, I had to remove |
@kyle-mccarthy do you plan on releasing Edit: I did not have to remove the |
@ralls done! just deployed v10 to npm |
@kyle-mccarthy Thank you! 👍 |
Is it possible to filter which 404 reponses are passed through to next? I would like to prevent my 404 api responses from rendering an error page. |
I usually like to do my research and spend a lot of time doing so before reaching out for help but I'm at a dead end. I must be having tunnel vision at this point but either way here goes.
I understand the reason for handling routes in Nest and routing them to Next but I'm actually looking for Next to handle anything not defined in Nest. I don't know if this is the correct use case but here's an example none the less.
In pages/, I create a file called index.tsx and in nest I add to the AppController a Get('') and Render('Index'). This loads on localhost:3000. In this index.tsx file, I create a link to redirect the user to a new page called Profile (). Clicking on this link for Profile, it successfully routes the user however when I refresh, Nest kicks in and throws an error.
Is there a solution for this?
In conclusion, if I go to
/asadd
, a non existent route in Nest, I would like to see the Next 404 error page and not the Nest stack trace page.The text was updated successfully, but these errors were encountered: