Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions packages/angular/ssr/src/routes/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { AngularAppManifest } from '../manifest';
import { stripIndexHtmlFromURL } from '../utils/url';
import { stripIndexHtmlFromURL, stripMatrixParams } from '../utils/url';
import { extractRoutesAndCreateRouteTree } from './ng-routes';
import { RouteTree, RouteTreeNodeMetadata } from './route-tree';

Expand Down Expand Up @@ -85,8 +85,10 @@ export class ServerRouter {
match(url: URL): RouteTreeNodeMetadata | undefined {
// Strip 'index.html' from URL if present.
// A request to `http://www.example.com/page/index.html` will render the Angular route corresponding to `http://www.example.com/page`.
const { pathname } = stripIndexHtmlFromURL(url);
let { pathname } = stripIndexHtmlFromURL(url);
pathname = stripMatrixParams(pathname);
pathname = decodeURIComponent(pathname);

return this.routeTree.match(decodeURIComponent(pathname));
return this.routeTree.match(pathname);
}
}
24 changes: 24 additions & 0 deletions packages/angular/ssr/src/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,27 @@ export function buildPathWithParams(toPath: string, fromPath: string): string {

return joinUrlParts(...resolvedParts);
}

const MATRIX_PARAMS_REGEX = /;[^/]+/g;

/**
* Removes Angular matrix parameters from a given URL path.
*
* This function takes a URL path string and removes any matrix parameters.
* Matrix parameters are parts of a URL segment that start with a semicolon `;`.
*
* @param pathname - The URL path to remove matrix parameters from.
* @returns The URL path with matrix parameters removed.
*
* @example
* ```ts
* stripMatrixParams('/path;param=value'); // returns '/path'
* stripMatrixParams('/path;param=value/to;p=1/resource'); // returns '/path/to/resource'
* stripMatrixParams('/path/to/resource'); // returns '/path/to/resource'
* ```
*/
export function stripMatrixParams(pathname: string): string {
// Use a regular expression to remove matrix parameters.
// This regex finds all occurrences of a semicolon followed by any characters
return pathname.includes(';') ? pathname.replace(MATRIX_PARAMS_REGEX, '') : pathname;
}
27 changes: 27 additions & 0 deletions packages/angular/ssr/test/utils/url_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
joinUrlParts,
stripIndexHtmlFromURL,
stripLeadingSlash,
stripMatrixParams,
stripTrailingSlash,
} from '../../src/utils/url';

Expand Down Expand Up @@ -181,4 +182,30 @@ describe('URL Utils', () => {
}).toThrowError(`Invalid toPath: The string must start with a '/'. Received: 'details'`);
});
});

describe('stripMatrixParams', () => {
it('should remove a single matrix parameter', () => {
expect(stripMatrixParams('/path;param=value')).toBe('/path');
});

it('should remove multiple matrix parameters in the same segment', () => {
expect(stripMatrixParams('/path;p1=v1;p2=v2')).toBe('/path');
});

it('should remove matrix parameters from multiple segments', () => {
expect(stripMatrixParams('/path;p1=v1/to;p2=v2/resource')).toBe('/path/to/resource');
});

it('should not modify a path without matrix parameters', () => {
expect(stripMatrixParams('/path/to/resource')).toBe('/path/to/resource');
});

it('should handle a root path with matrix parameters', () => {
expect(stripMatrixParams('/;p1=v1')).toBe('/');
});

it('should handle an empty string', () => {
expect(stripMatrixParams('')).toBe('');
});
});
});