diff --git a/packages/angular/build/src/utils/index-file/augment-index-html.ts b/packages/angular/build/src/utils/index-file/augment-index-html.ts index 30d5f30d2b..7a30770fa4 100644 --- a/packages/angular/build/src/utils/index-file/augment-index-html.ts +++ b/packages/angular/build/src/utils/index-file/augment-index-html.ts @@ -65,17 +65,8 @@ export interface FileInfo { export async function augmentIndexHtml( params: AugmentIndexHtmlOptions, ): Promise<{ content: string; warnings: string[]; errors: string[] }> { - const { - loadOutputFile, - files, - entrypoints, - sri, - deployUrl = '', - lang, - baseHref, - html, - imageDomains, - } = params; + const { loadOutputFile, files, entrypoints, sri, deployUrl, lang, baseHref, html, imageDomains } = + params; const warnings: string[] = []; const errors: string[] = []; @@ -117,7 +108,7 @@ export async function augmentIndexHtml( let scriptTags: string[] = []; for (const [src, isModule] of scripts) { - const attrs = [`src="${deployUrl}${src}"`]; + const attrs = [`src="${generateUrl(src, deployUrl)}"`]; // This is also need for non entry-points as they may contain problematic code. if (isModule) { @@ -141,7 +132,7 @@ export async function augmentIndexHtml( let headerLinkTags: string[] = []; let bodyLinkTags: string[] = []; for (const src of stylesheets) { - const attrs = [`rel="stylesheet"`, `href="${deployUrl}${src}"`]; + const attrs = [`rel="stylesheet"`, `href="${generateUrl(src, deployUrl)}"`]; if (crossOrigin !== 'none') { attrs.push(`crossorigin="${crossOrigin}"`); @@ -157,7 +148,7 @@ export async function augmentIndexHtml( if (params.hints?.length) { for (const hint of params.hints) { - const attrs = [`rel="${hint.mode}"`, `href="${deployUrl}${hint.url}"`]; + const attrs = [`rel="${hint.mode}"`, `href="${generateUrl(hint.url, deployUrl)}"`]; if (hint.mode !== 'modulepreload' && crossOrigin !== 'none') { // Value is considered anonymous by the browser when not present or empty @@ -303,6 +294,19 @@ function generateSriAttributes(content: string): string { return `integrity="${algo}-${hash}"`; } +function generateUrl(value: string, deployUrl: string | undefined): string { + if (!deployUrl) { + return value; + } + + // Skip if root-relative, absolute or protocol relative url + if (/^((?:\w+:)?\/\/|data:|chrome:|\/)/.test(value)) { + return value; + } + + return `${deployUrl}${value}`; +} + function updateAttribute( tag: { attrs: { name: string; value: string }[] }, name: string, diff --git a/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts b/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts index 61aaa0674e..7ea16ab612 100644 --- a/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts +++ b/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts @@ -398,6 +398,46 @@ describe('augment-index-html', () => { `); }); + it(`should not add deploy URL to hints with an absolute URL`, async () => { + const { content, warnings } = await augmentIndexHtml({ + ...indexGeneratorOptions, + deployUrl: 'https://localhost/', + hints: [{ mode: 'preload', url: 'http://example.com/y?b=2' }], + }); + + expect(warnings).toHaveSize(0); + expect(content).toEqual(oneLineHtml` + +
+