mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(docs-infra): ignore external links when mapping navigation items to routes
When navigation items contain external URLs (e.g. https:// links for documentation or third-party resources), mapNavigationItemsToRoutes previously registered them as Angular Router route definitions. In recent versions of @angular/build, the static prerender worker asserts that discovered routes do not return empty content during SSG prerendering, causing production builds and CI adev-deploy to fail on these routes. This change filters out external links in mapNavigationItemsToRoutes so only valid internal application paths are registered as Angular routes.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
load("//adev/shared-docs:defaults.bzl", "ts_project")
|
||||
load("//adev/shared-docs:defaults.bzl", "ts_project", "zoneless_web_test_suite")
|
||||
|
||||
package(default_visibility = ["//visibility:private"])
|
||||
|
||||
@@ -21,3 +21,20 @@ ts_project(
|
||||
"//adev/shared-docs/providers",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "test_lib",
|
||||
testonly = True,
|
||||
srcs = glob(
|
||||
["*.spec.ts"],
|
||||
),
|
||||
deps = [
|
||||
":utils",
|
||||
"//adev/shared-docs/interfaces",
|
||||
],
|
||||
)
|
||||
|
||||
zoneless_web_test_suite(
|
||||
name = "test",
|
||||
deps = [":test_lib"],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {NavigationItem} from '../interfaces/index';
|
||||
import {isExternalLink, mapNavigationItemsToRoutes} from './navigation.utils';
|
||||
|
||||
describe('navigation.utils', () => {
|
||||
describe('isExternalLink', () => {
|
||||
it('should return true for http and https links', () => {
|
||||
expect(isExternalLink('http://example.com')).toBeTrue();
|
||||
expect(isExternalLink('https://example.com')).toBeTrue();
|
||||
expect(isExternalLink('https://github.com/angular/angularfire#readme')).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return false for internal relative or absolute paths', () => {
|
||||
expect(isExternalLink('guide/signals')).toBeFalse();
|
||||
expect(isExternalLink('/guide/signals')).toBeFalse();
|
||||
expect(isExternalLink('overview')).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapNavigationItemsToRoutes', () => {
|
||||
it('should map internal navigation items to routes and ignore external links', () => {
|
||||
const items: NavigationItem[] = [
|
||||
{
|
||||
label: 'Overview',
|
||||
path: 'overview',
|
||||
},
|
||||
{
|
||||
label: 'AngularFire',
|
||||
path: 'https://github.com/angular/angularfire#readme',
|
||||
},
|
||||
{
|
||||
label: 'Google Maps',
|
||||
path: 'https://github.com/angular/components/tree/main/src/google-maps#readme',
|
||||
},
|
||||
{
|
||||
label: 'Guide',
|
||||
path: 'guide/components',
|
||||
},
|
||||
];
|
||||
|
||||
const routes = mapNavigationItemsToRoutes(items, {});
|
||||
|
||||
expect(routes.length).toBe(2);
|
||||
expect(routes.map((r) => r.path)).toEqual(['overview', 'guide/components']);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -96,7 +96,10 @@ export const mapNavigationItemsToRoutes = (
|
||||
additionalRouteProperties: Partial<Route>,
|
||||
): Route[] =>
|
||||
navigationItems
|
||||
.filter((route): route is NavigationItem & {path: string} => Boolean(route.path))
|
||||
.filter(
|
||||
(route): route is NavigationItem & {path: string} =>
|
||||
Boolean(route.path) && !isExternalLink(route.path!),
|
||||
)
|
||||
.map((navigationItem) => {
|
||||
const route = {
|
||||
path: navigationItem.path,
|
||||
|
||||
Reference in New Issue
Block a user