Skip to content

Commit 501a33b

Browse files
authored
Prevent setTimeout from firing if we can't match devtools user agent (#13349)
Fixes #13344 The `connectToDevtools` method inside `ApolloClient` runs a `setTimeout` then checks the `window.navigator.userAgent` to see if it matches a supported platform before logging the message. As #13344 points out, this can be problematic in test environments since that `setTimeout` can linger. Even worse is when that `setTimeout` outlives the virtual DOM construction so `window` doesn't exist anymore which could cause crashes. This fix checks `window.navigator.userAgent` outside the `setTimeout` and prevents it from scheduling if we're in a non Chrome/Firefox environment. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Apollo DevTools extension prompts by displaying them only in supported browser contexts. * Prevented unnecessary extension suggestions in embedded frames and unsupported protocols. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 4bb6df7 commit 501a33b

2 files changed

Lines changed: 31 additions & 24 deletions

File tree

.changeset/lemon-fireants-build.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/client": patch
3+
---
4+
5+
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.

src/core/ApolloClient.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,33 +1169,35 @@ export class ApolloClient {
11691169
*/
11701170
if (!hasSuggestedDevtools && __DEV__) {
11711171
hasSuggestedDevtools = true;
1172+
const win = window;
1173+
1174+
const ua = win.navigator.userAgent;
1175+
let url: string | undefined;
1176+
1177+
if (typeof ua === "string") {
1178+
if (ua.indexOf("Chrome/") > -1) {
1179+
url =
1180+
"https://chrome.google.com/webstore/detail/" +
1181+
"apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm";
1182+
} else if (ua.indexOf("Firefox/") > -1) {
1183+
url =
1184+
"https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/";
1185+
}
1186+
}
1187+
11721188
if (
1173-
window.document &&
1174-
window.top === window.self &&
1175-
/^(https?|file):$/.test(window.location.protocol)
1189+
win.document &&
1190+
win.top === win.self &&
1191+
/^(https?|file):$/.test(win.location.protocol) &&
1192+
url
11761193
) {
11771194
setTimeout(() => {
1178-
if (!(window as any).__APOLLO_DEVTOOLS_GLOBAL_HOOK__) {
1179-
const nav = window.navigator;
1180-
const ua = nav && nav.userAgent;
1181-
let url: string | undefined;
1182-
if (typeof ua === "string") {
1183-
if (ua.indexOf("Chrome/") > -1) {
1184-
url =
1185-
"https://chrome.google.com/webstore/detail/" +
1186-
"apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm";
1187-
} else if (ua.indexOf("Firefox/") > -1) {
1188-
url =
1189-
"https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/";
1190-
}
1191-
}
1192-
if (url) {
1193-
invariant.log(
1194-
"Download the Apollo DevTools for a better development " +
1195-
"experience: %s",
1196-
url
1197-
);
1198-
}
1195+
if (!(win as any).__APOLLO_DEVTOOLS_GLOBAL_HOOK__) {
1196+
invariant.log(
1197+
"Download the Apollo DevTools for a better development " +
1198+
"experience: %s",
1199+
url
1200+
);
11991201
}
12001202
}, 10000);
12011203
}

0 commit comments

Comments
 (0)