Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJs redirect without response usage

Is it possible to make a redirect from a Nest controller without the usage of the @Response object?

For now I know that we can only do this via direct @Response object injection into the route handler.

like image 431
QuestionAndAnswer Avatar asked Oct 20 '25 14:10

QuestionAndAnswer


2 Answers

You can write a RedirectInterceptor:

@Injectable()
export class RedirectInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    const response = context.switchToHttp().getResponse();
    response.redirect('redirect-target');
    return stream$;
  }
}

Then use it in your controller like this:

@Get('user')
@UseInterceptors(RedirectInterceptor)
getUser() {
  // will be redirected.
}

It is important not to return anything from your controller, otherwise you will get the following error: Can't set headers after they are sent.

If needed the RedirectInterceptor can be dynamic as well:

@Injectable()
export class RedirectInterceptor implements NestInterceptor {
  constructor(private readonly target: string) {}
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  intercept(context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    const response = context.switchToHttp().getResponse();
    response.redirect(this.target);
                      ^^^^^^^^^^^
    return stream$;
  }
}

and then in the controller:

@UseInterceptors(new RedirectInterceptor('redirect-target'))
like image 99
Kim Kern Avatar answered Oct 22 '25 02:10

Kim Kern


(a bit of a different implementation to another answer here...)

I created a RedirectError which can be thrown more dynamically than a decorator

import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { Response } from 'express';

export class RedirectError extends Error {
  constructor(public readonly status: number, public readonly url: string) {
    super();
  }
}

@Catch(RedirectError)
export class RedirectFilter implements ExceptionFilter {
  public catch(exception: RedirectError, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    return response.redirect(exception.status, exception.url);
  }
}

and then in main.ts set it:

  app.useGlobalFilters(new RedirectFilter());

and finally to use it:

throw new RedirectError(302, '/some-target');
like image 43
Alon Burg Avatar answered Oct 22 '25 04:10

Alon Burg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!