apollo-client-devtools icon indicating copy to clipboard operation
apollo-client-devtools copied to clipboard

"Could not find client" connectToDevTools option is deprecated

Open AlexiaAcevedo opened this issue 8 months ago • 8 comments

Intended outcome:

I am trying to configure my apolloClient so that I can use Apollo Client DevTools. However, connectToDevTools option is now deprecated.

devtools: {
    enabled: true,
  },

Should be the new option passed into the client object as per ApolloClient Docs

Actual outcome:

Ultimately, devTools cannot find the client even when I set if I set

if (typeof window !== 'undefined') {
  ;(window as any).__APOLLO_CLIENT__ = apolloClient
}

Making the extension unusable.

Image

How to reproduce the issue:

To reproduce the issue, update to versions mentioned below and Apollo Client (Web) - v3. I am running 3.12.8. Download extension and try to configure your application.

Desktop (please complete the following information):

  • OS: macOS 14.6.1 (23G93)
  • Browser: Chrome
  • Browser version: 128.0.6613.120
  • Extension version: 4.19.13

AlexiaAcevedo avatar May 07 '25 19:05 AlexiaAcevedo

While it is deprecated, it should not have stopped working.

Is there a specific version of Apollo Client that worked for you in the past and a specific version where it starts breaking?

phryneas avatar May 08 '25 09:05 phryneas

I'm getting the same error. It was working for me on May 3rd, but now it's not.

(Running "@apollo/client": "^3.13.8" both when it was working last week and now that it's not)

Using Brave and Chrome browsers, neither work.

Both window.APOLLO_CLIENT && window.APOLLO_DEVTOOLS_GLOBAL_HOOK.ApolloClient return the Apollo client, but even when I click 'retry' on the dev tools screen, it can't find it.

Here is my client setup from when I know the client tools were working:

import { ApolloClient, InMemoryCache, createHttpLink, defaultDataIdFromObject } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import { onError } from "@apollo/client/link/error";
import { fromPromise } from "@apollo/client/link/utils";
import { getCurrentTokens, refreshAccessToken} from "../auth/authService";
import { AuthTokens } from "../../types/auth";

// Create the http link
const httpLink = createHttpLink({
  uri: "https://api.devii.io/query",
});

// Add auth headers
const authLink = setContext(async (_, { headers }) => {
  // Get the token
  const tokens = await getCurrentTokens();
  
  return {
    headers: {
      ...headers,
      authorization: tokens ? `Bearer ${tokens.accessToken}` : "",
    }
  };
});

// Define error handling link for token refresh
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
  // Handle 401 Unauthorized errors from the network
  if (networkError && 'statusCode' in networkError && networkError.statusCode === 401) {
    // Try to refresh the token
    return fromPromise(
      getCurrentTokens().then(tokens => {
        if (!tokens) {
          throw new Error('No refresh token available');
        }
        
        // Return the promise with new tokens
        return refreshAccessToken(tokens.refreshToken);
      })
    ).flatMap((newTokens: AuthTokens) => {
      // Modify the operation context with new token
      const oldHeaders = operation.getContext().headers || {};
      operation.setContext({
        headers: {
          ...oldHeaders,
          authorization: `Bearer ${newTokens.accessToken}`,
        },
      });
      
      // Retry the request
      return forward(operation);
    });
  }
});

// Create the Apollo client
export const client = new ApolloClient({
  link: errorLink.concat(authLink.concat(httpLink)),
  cache: new InMemoryCache({
    dataIdFromObject(responseObject) {
      switch (responseObject.__typename) {
        case 'user_pipeline_status': return `user_pipeline_status:${responseObject.user_id}:${responseObject.pipeline_id}`;
        default: return defaultDataIdFromObject(responseObject);
      }
    }
  })
});

And my layout.tsx (expo app)

import React, { useMemo } from 'react';
import { Stack } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import { AuthProvider } from '../services/auth/AuthContext';
import { ThemeProvider, useTheme } from '../services/theme/ThemeContext';
import { ThemeToggle } from '../components/ThemeToggle';
import { ApolloProvider } from '@apollo/client';
import { client } from '../services/apollo/client';
import { PaperProvider, MD3DarkTheme, MD3LightTheme } from 'react-native-paper';

// This component applies the theme to the root navigator
function ThemedNavigator() {
  ...
}

export default function RootLayout() {
  return (
    <ThemeProvider>
      <AuthProvider>
        <ApolloProvider client={client}>
          <ThemedNavigator />
        </ApolloProvider>
      </AuthProvider>
    </ThemeProvider>
  );
}

jase-k avatar May 08 '25 10:05 jase-k

Seeing the same issue in Apollo Client Devtools 4.19.13

Both window.APOLLO_CLIENT && window.APOLLO_DEVTOOLS_GLOBAL_HOOK.ApolloClient return the Apollo client, but they no longer show connectToDevTools within the object (its value is set to true in my code).

The window object does show devtools: { enabled: true, },

NoamaanNadeem avatar May 08 '25 15:05 NoamaanNadeem

@jase-k thats odd. We haven't published a release in almost a month and the last one just updated error messages.

Would you be willing to perhaps run our test app in this repo and see if you're seeing the same issue? I'm unable to reproduce with our test app.

git clone https://github.com/apollographql/apollo-client-devtools.git
npm run install:dev
nmp run start:dev

This should open an app at localhost:3000 with some colors. Are you able to connect to this one?

jerelmiller avatar May 08 '25 15:05 jerelmiller

Interestingly.... I'm able to connect to my local app again today and I didn't make any changes since yesterday. Unfortunately, I'm not able to reproduce the issue I was having

jase-k avatar May 09 '25 09:05 jase-k

Sometimes browser extensions can get hung up and restarting the browser already helps - maybe that was the case here? :)

phryneas avatar May 09 '25 09:05 phryneas

Something that the devtools doesn't do super well yet is handle extension updates by the browser (which usually happens in the background) so if the extension happens to update while you have devtools open, the messaging is broken between the extension and the web page,

Unfortunately this one is a bit difficult to fix (I've tried a few times and the browser completely replaces the scripts that were listening to the old background script, so I can't tell the old scripts to display a message). That could have been what happened here. Usually closing and reopening devtools (to reload the extension's scripts) and refreshing the current page (to reload the content scripts injected on the page) help a lot. As @phryneas said, that could have been what happened here.

jerelmiller avatar May 13 '25 14:05 jerelmiller

@phryneas Seems that you were right in my case as well. I tried to reinstall but that didn't worked. After rebooting the browser ( Opera on Mac ) it's working again.

ebisbe avatar Jun 30 '25 15:06 ebisbe