Skip to content

Commit 2c4613a

Browse files
JeanMecheatscott
authored andcommitted
fix(common): Don't run preconnect assertion on the server. (#56213)
The `window` global is patched by domino on the server but the value of `window.location.href` isn't a valid base. Before this change `getUrl()` would throw when running in devmode on the server. Fixes #56207 PR Close #56213
1 parent e5e1f49 commit 2c4613a

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

packages/common/src/directives/ng_optimized_image/lcp_image_observer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Injectable,
1212
OnDestroy,
1313
ɵformatRuntimeError as formatRuntimeError,
14+
PLATFORM_ID,
1415
} from '@angular/core';
1516

1617
import {DOCUMENT} from '../../dom_tokens';
@@ -19,6 +20,7 @@ import {RuntimeErrorCode} from '../../errors';
1920
import {assertDevMode} from './asserts';
2021
import {imgDirectiveDetails} from './error_helper';
2122
import {getUrl} from './url';
23+
import {isPlatformBrowser} from '../../platform_id';
2224

2325
interface ObservedImageState {
2426
priority: boolean;
@@ -46,9 +48,10 @@ export class LCPImageObserver implements OnDestroy {
4648
private observer: PerformanceObserver | null = null;
4749

4850
constructor() {
51+
const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
4952
assertDevMode('LCP checker');
5053
const win = inject(DOCUMENT).defaultView;
51-
if (typeof win !== 'undefined' && typeof PerformanceObserver !== 'undefined') {
54+
if (isBrowser && typeof PerformanceObserver !== 'undefined') {
5255
this.window = win;
5356
this.observer = this.initPerformanceObserver();
5457
}
@@ -107,6 +110,7 @@ export class LCPImageObserver implements OnDestroy {
107110
}
108111

109112
updateImage(originalSrc: string, newSrc: string) {
113+
if (!this.observer) return;
110114
const originalUrl = getUrl(originalSrc, this.window!).href;
111115
const img = this.images.get(originalUrl);
112116
if (img) {

packages/common/src/directives/ng_optimized_image/preconnect_link_checker.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
Injectable,
1212
InjectionToken,
1313
ɵformatRuntimeError as formatRuntimeError,
14-
ɵRuntimeError as RuntimeError,
14+
PLATFORM_ID,
1515
} from '@angular/core';
1616

1717
import {DOCUMENT} from '../../dom_tokens';
@@ -20,6 +20,7 @@ import {RuntimeErrorCode} from '../../errors';
2020
import {assertDevMode} from './asserts';
2121
import {imgDirectiveDetails} from './error_helper';
2222
import {extractHostname, getUrl} from './url';
23+
import {isPlatformServer} from '../../platform_id';
2324

2425
// Set of origins that are always excluded from the preconnect checks.
2526
const INTERNAL_PRECONNECT_CHECK_BLOCKLIST = new Set(['localhost', '127.0.0.1', '0.0.0.0']);
@@ -56,6 +57,7 @@ export const PRECONNECT_CHECK_BLOCKLIST = new InjectionToken<Array<string | stri
5657
@Injectable({providedIn: 'root'})
5758
export class PreconnectLinkChecker {
5859
private document = inject(DOCUMENT);
60+
private readonly isServer = isPlatformServer(inject(PLATFORM_ID));
5961

6062
/**
6163
* Set of <link rel="preconnect"> tags found on this page.
@@ -102,9 +104,9 @@ export class PreconnectLinkChecker {
102104
* @param originalNgSrc ngSrc value
103105
*/
104106
assertPreconnect(rewrittenSrc: string, originalNgSrc: string): void {
105-
if (!this.window) return;
107+
if (this.isServer) return;
106108

107-
const imgUrl = getUrl(rewrittenSrc, this.window);
109+
const imgUrl = getUrl(rewrittenSrc, this.window!);
108110
if (this.blocklist.has(imgUrl.hostname) || this.alreadySeen.has(imgUrl.origin)) return;
109111

110112
// Register this origin as seen, so we don't check it again later.

packages/common/test/directives/ng_optimized_image_spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,9 @@ describe('Image directive', () => {
13601360
it(
13611361
'should log a warning if there is no preconnect link for a priority image',
13621362
withHead('', () => {
1363+
// The warning is only logged on the client
1364+
if (!isBrowser) return;
1365+
13631366
setupTestingModule({imageLoader});
13641367

13651368
const consoleWarnSpy = spyOn(console, 'warn');
@@ -1398,6 +1401,9 @@ describe('Image directive', () => {
13981401
it(
13991402
"should log a warning if there is a preconnect, but it doesn't match the priority image",
14001403
withHead('<link rel="preconnect" href="http://angular.io">', () => {
1404+
// The warning is only logged on the client
1405+
if (!isBrowser) return;
1406+
14011407
setupTestingModule({imageLoader});
14021408

14031409
const consoleWarnSpy = spyOn(console, 'warn');
@@ -1422,6 +1428,9 @@ describe('Image directive', () => {
14221428
withHead(
14231429
'<link rel="preload" href="https://angular.io/assets/images/logos/angular/angular.svg" as="image">',
14241430
() => {
1431+
// The warning is only logged on the client
1432+
if (!isBrowser) return;
1433+
14251434
setupTestingModule({imageLoader});
14261435

14271436
const consoleWarnSpy = spyOn(console, 'warn');

0 commit comments

Comments
 (0)