Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

SSR route redirects drop the query string on relative `redirectTo`

Ouverte
#34,298 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@bschaeublin y travaille déjà.

Depuis le 9/10/2026.

  • #34299 par @bschaeublin — ouverte

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
45/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
express, nodejs, typescript
Domaine
backend, web-dev

Piste de recherche

Start in packages/angular/ssr/src/app.ts around lines 168-176, where the 302 Location is built from the stored redirectTo and url.search is never read. The reporter notes that redirectTo is already absolute by then, so the code must keep track of whether the redirect was relative, and the router's recognize.ts keeps the original query for relative redirects. Done means the relative case returns the query in Location, the absolute case is unchanged, and the curl command from the report shows /search/results?q=x.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

area: @angular/ssr
Command

other

Is this a regression?
  • Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was

No response

Description

When a request matches a route with a string redirectTo, @angular/ssr answers with a 302 built from the route config, without running the router. For a relative redirectTo, the query string of the request is dropped.

The Angular router keeps it: a relative redirect only rewrites the matched segments and continues with the rest of the URL. So /search?q=x with { path: '', redirectTo: 'results' } under search ends up at /search/results?q=x with in-app navigation, but at /search/results on a full page load (direct link, reload, link from an email).

For absolute redirects the router drops the query as well, so these already agree.

Minimal Reproduction
npx @angular/[email protected] new repro-app --ssr --defaults
cd repro-app

src/app/app.routes.ts:

import { Component } from '@angular/core';
import { Routes } from '@angular/router';

@Component({ template: 'Results page' })
class Results {}

export const routes: Routes = [
  {
    path: 'search',
    children: [
      { path: '', redirectTo: 'results', pathMatch: 'full' },
      { path: 'results', component: Results },
    ],
  },
];

src/app/app.routes.server.ts (server rendering, so the request reaches the redirect handling instead of a prerendered redirect page):

import { RenderMode, ServerRoute } from '@angular/ssr';

export const serverRoutes: ServerRoute[] = [{ path: '**', renderMode: RenderMode.Server }];
npx ng build
NG_ALLOWED_HOSTS=localhost PORT=4000 node dist/repro-app/server/server.mjs
curl -si 'localhost:4000/search?q=x' | grep -i '^location'

Expected: location: /search/results?q=x (where the router navigates). Actual: location: /search/results.

Exception or Error
$ curl -si 'localhost:4000/search?q=x' | head -3
HTTP/1.1 302 Found
X-Powered-By: Express
location: /search/results
Your Environment
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI       : 22.2.2
Angular           : 22.2.2
Node.js           : 24.18.0
Package Manager   : npm 11.16.0
Operating System  : linux x64

┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package                   │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build            │ 22.2.2            │ ^22.2.2           │
│ @angular/cli              │ 22.2.2            │ ^22.2.2           │
│ @angular/common           │ 22.2.2            │ ^22.2.0           │
│ @angular/compiler         │ 22.2.2            │ ^22.2.0           │
│ @angular/compiler-cli     │ 22.2.2            │ ^22.2.0           │
│ @angular/core             │ 22.2.2            │ ^22.2.0           │
│ @angular/forms            │ 22.2.2            │ ^22.2.0           │
│ @angular/platform-browser │ 22.2.2            │ ^22.2.0           │
│ @angular/platform-server  │ 22.2.2            │ ^22.2.0           │
│ @angular/router           │ 22.2.2            │ ^22.2.0           │
│ @angular/ssr              │ 22.2.2            │ ^22.2.2           │
│ rxjs                      │ 7.8.2             │ ~7.8.0            │
│ typescript                │ 6.0.3             │ ~6.0.2            │
└───────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?

app.ts#L168-L176 builds Location from the stored redirectTo and never uses url.search. By then redirectTo has already been resolved to an absolute path, so whether it was relative is no longer known.

Router side: for a relative redirect, recognize.ts keeps only the segments of the new tree and continues with the original URL tree, so the query is kept. An absolute redirect throws AbsoluteRedirect(newTree), whose query comes from redirectTo only. Render-time redirects (guards, router.navigate) already keep the query (#31883).

I have a fix with tests and will open a PR for it.

Not browser specific. Seen with the default Express server.ts generated by ng new --ssr; the redirect comes from AngularNodeAppEngine.handle(), not from Express itself.

Langage dominant
TypeScript
Étoiles
27k
Forks
11.8k
Merge moyen
1 j 1 h
PR mergées (30 j)
161

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de angular/angular-cli

Toutes les issues de angular/angular-cli

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.