From 86c6e0ce162d5fdbc76eef058f0aa018dd428da3 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Thu, 23 Jul 2026 10:10:42 -0600 Subject: [PATCH 1/3] Prevent setTimeout from firing if we can't match devtools user agent --- src/core/ApolloClient.ts | 43 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/core/ApolloClient.ts b/src/core/ApolloClient.ts index cbde11446b2..b6eaeedf22d 100644 --- a/src/core/ApolloClient.ts +++ b/src/core/ApolloClient.ts @@ -1169,33 +1169,34 @@ export class ApolloClient { */ if (!hasSuggestedDevtools && __DEV__) { hasSuggestedDevtools = true; + + const ua = window.navigator.userAgent; + let url: string | undefined; + + if (typeof ua === "string") { + if (ua.indexOf("Chrome/") > -1) { + url = + "https://chrome.google.com/webstore/detail/" + + "apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm"; + } else if (ua.indexOf("Firefox/") > -1) { + url = + "https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/"; + } + } + if ( window.document && window.top === window.self && - /^(https?|file):$/.test(window.location.protocol) + /^(https?|file):$/.test(window.location.protocol) && + url ) { setTimeout(() => { if (!(window as any).__APOLLO_DEVTOOLS_GLOBAL_HOOK__) { - const nav = window.navigator; - const ua = nav && nav.userAgent; - let url: string | undefined; - if (typeof ua === "string") { - if (ua.indexOf("Chrome/") > -1) { - url = - "https://chrome.google.com/webstore/detail/" + - "apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm"; - } else if (ua.indexOf("Firefox/") > -1) { - url = - "https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/"; - } - } - if (url) { - invariant.log( - "Download the Apollo DevTools for a better development " + - "experience: %s", - url - ); - } + invariant.log( + "Download the Apollo DevTools for a better development " + + "experience: %s", + url + ); } }, 10000); } From 78bed77f158f19944ad4e6f1dcc93f2e38c9db03 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Thu, 23 Jul 2026 10:20:17 -0600 Subject: [PATCH 2/3] Add changeset --- .changeset/lemon-fireants-build.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/lemon-fireants-build.md diff --git a/.changeset/lemon-fireants-build.md b/.changeset/lemon-fireants-build.md new file mode 100644 index 00000000000..5c78fd215ca --- /dev/null +++ b/.changeset/lemon-fireants-build.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Prevent the `setTimeout` in `connectToDevtools` that shows the devtools suggestion from firing when the user agent does not match Chrome or Firefox. This check was previously done inside the `setTimeout` which meant the timer was scheduled for environments where we'd never show the message anyways. For test environments, this could cause flaky tests when that `setTimeout` outlived the tests and ran after any virtual DOM was torn down and removed. From 588ab4b02ee9fb35f50cdbbd07dc8045f7f149bb Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Thu, 23 Jul 2026 10:42:53 -0600 Subject: [PATCH 3/3] Capture window in a variable --- src/core/ApolloClient.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/ApolloClient.ts b/src/core/ApolloClient.ts index b6eaeedf22d..45289b17a39 100644 --- a/src/core/ApolloClient.ts +++ b/src/core/ApolloClient.ts @@ -1169,8 +1169,9 @@ export class ApolloClient { */ if (!hasSuggestedDevtools && __DEV__) { hasSuggestedDevtools = true; + const win = window; - const ua = window.navigator.userAgent; + const ua = win.navigator.userAgent; let url: string | undefined; if (typeof ua === "string") { @@ -1185,13 +1186,13 @@ export class ApolloClient { } if ( - window.document && - window.top === window.self && - /^(https?|file):$/.test(window.location.protocol) && + win.document && + win.top === win.self && + /^(https?|file):$/.test(win.location.protocol) && url ) { setTimeout(() => { - if (!(window as any).__APOLLO_DEVTOOLS_GLOBAL_HOOK__) { + if (!(win as any).__APOLLO_DEVTOOLS_GLOBAL_HOOK__) { invariant.log( "Download the Apollo DevTools for a better development " + "experience: %s",