rainbow-me / rainbowkit

The best way to connect a wallet 🌈 🧰
https://rainbowkit.com
MIT License
2.44k stars 665 forks source link

[bug] No QueryClient set, use QueryClientProvider to set one #1883

Closed Kaldrogh closed 7 months ago

Kaldrogh commented 7 months ago

Is there an existing issue for this?

RainbowKit Version

2.0.2

wagmi Version

2.5.12

Current Behavior

An error is thrown immediatly when starting my app. I've made extensive searches throught the web to figure out what is going on, with no luck.

Expected Behavior

To work.

Steps To Reproduce

Unable to figure out why this error keeps being thrown as i've checked for hours almost everything. I've done extensive searches accross the web to try to find a workaround, with no luck

image

{ "name": "my-app", "version": "2.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "export": "next export", "lint": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\"", "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"", "build:icons": "tsc -b src/iconify-bundle && node src/iconify-bundle/bundle-icons-react.js" }, "dependencies": { "@casl/ability": "6.3.3", "@casl/react": "3.1.0", "@emotion/cache": "11.10.5", "@emotion/react": "11.10.6", "@emotion/server": "11.10.0", "@emotion/styled": "11.10.6", "@faker-js/faker": "^8.0.2", "@iconify/react": "4.1.0", "@moralisweb3/next": "^2.23.2", "@mui/lab": "^5.0.0-alpha.169", "@mui/material": "^5.15.14", "@mui/system": "^5.15.14", "@mui/x-data-grid": "^7.0.0", "@mui/x-date-pickers": "^7.0.0", "@popperjs/core": "2.11.6", "@rainbow-me/rainbowkit": "^2.0.2", "@tanstack/query-core": "^5.28.6", "@tanstack/react-query": "^5.28.6", "@tanstack/react-query-devtools": "^5.28.6", "@types/dompurify": "^3.0.2", "@types/draft-convert": "^2.1.4", "@types/draftjs-to-html": "^0.8.1", "@types/jsonwebtoken": "^9.0.1", "@types/lodash": "^4.14.194", "@types/numeral": "^2.0.5", "@types/react-dom": "^18.2.8", "@types/react-lines-ellipsis": "^0.15.2", "@types/uuid": "^9.0.2", "@types/webextension-polyfill": "^0.10.7", "@uploadthing/react": "^6.0.2", "@upstash/ratelimit": "^0.4.4", "@vercel/analytics": "^1.0.2", "apexcharts": "^3.42.0", "apexcharts-clevision": "^3.28.5", "axios": "^1.6.2", "bootstrap-icons": "1.10.3", "chart.js": "^4.4.0", "cleave.js": "1.6.0", "clipboard-copy": "4.0.1", "clsx": "1.2.1", "date-fns": "2.29.3", "dompurify": "^3.0.3", "draft-js": "^0.11.7", "draftjs-to-html": "^0.9.1", "embla-carousel-react": "^8.0.0-rc15", "embla-carousel-wheel-gestures": "^8.0.0-rc05", "emoji-picker-react": "^4.4.9", "ethers": "^6.11.1", "jose": "^4.14.0", "jsonwebtoken": "^9.0.0", "lodash": "^4.17.21", "mongoose": "^8.0.3", "moralis": "^2.23.2", "nanoid": "^4.0.2", "next": "^14.1.4", "next-auth": "^4.24.5", "nprogress": "0.2.0", "numeral": "^2.0.6", "react": "^18.2.0", "react-apexcharts": "^1.4.1", "react-chrono": "^2.2.0", "react-countdown": "^2.3.5", "react-datepicker": "4.10.0", "react-dom": "18.2.0", "react-draft-wysiwyg": "^1.15.0", "react-dropzone": "^14.2.3", "react-error-boundary": "^4.0.8", "react-hook-form": "^7.43.9", "react-hot-toast": "^2.4.1", "react-lines-ellipsis": "^0.15.3", "react-multi-carousel": "^2.8.4", "react-perfect-scrollbar": "1.5.8", "react-popper": "^2.3.0", "react-swipeable-views": "^0.14.0", "react-transition-group": "^4.4.5", "recharts": "^2.12.3", "stylis": "4.1.3", "stylis-plugin-rtl": "2.1.1", "swr": "^2.2.5", "uploadthing": "^6.0.4", "uuid": "^9.0.0", "viem": "^2.8.16", "wagmi": "^2.5.12", "yup": "^1.3.2", "zod": "^3.22.2" }, "devDependencies": { "@iconify/iconify": "^3.1.1", "@iconify/json": "^2.2.195", "@iconify/tools": "^4.0.2", "@iconify/types": "^2.0.0", "@iconify/utils": "^2.1.22", "@tanstack/eslint-plugin-query": "^5.28.6", "@types/cleave.js": "1.4.7", "@types/d3-color": "^3.1.0", "@types/draft-js": "0.11.10", "@types/node": "18.15.3", "@types/nprogress": "0.2.0", "@types/payment": "2.1.4", "@types/prismjs": "1.26.0", "@types/react": "^18.2.24", "@types/react-datepicker": "^4.15.1", "@types/react-draft-wysiwyg": "1.13.4", "@types/react-swipeable-views": "^0.13.1", "@typescript-eslint/eslint-plugin": "^7.3.1", "@typescript-eslint/parser": "^7.3.1", "eslint": "^8.57.0", "eslint-config-next": "^14.1.4", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "prettier": "^3.2.5", "typescript": "^5.4.3" } }

App.ts:

import { ReactNode } from 'react'
import { HydrationBoundary, QueryClient, QueryClientProvider } from '@tanstack/react-query'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
import Head from 'next/head'
import { Router } from 'next/router'
import NProgress from 'nprogress'
import type { EmotionCache } from '@emotion/cache'
import { CacheProvider } from '@emotion/react'
import themeConfig from 'src/configs/themeConfig'
import { Toaster } from 'react-hot-toast'
import ThemeComponent from 'src/@core/theme/ThemeComponent'
import UserLayout from 'src/layouts/UserLayout'
import AuthGuard from 'src/layouts/components/auth/UserAuthGuard'
import Spinner from 'src/layouts/components/spinner'
import { SessionProvider } from 'next-auth/react'
import { SettingsConsumer, SettingsProvider } from 'src/@core/context/settingsContext'
import ReactHotToast from 'src/@core/styles/libs/react-hot-toast'
import { createEmotionCache } from 'src/@core/utils/create-emotion-cache'
import 'react-perfect-scrollbar/dist/css/styles.css'
import { RainbowKitProvider, darkTheme, getDefaultConfig } from '@rainbow-me/rainbowkit'
import '@rainbow-me/rainbowkit/styles.css'
import { WagmiProvider, http } from 'wagmi'
import { arbitrum, bsc } from 'wagmi/chains'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import 'src/iconify-bundle/icons-bundle-react'
import '../../styles/globals.css'
import { UsernameProvider } from '../contexts/UsernameContext'
import { Analytics } from '@vercel/analytics/react'

type ExtendedAppProps = AppProps & {
Component: NextPage
emotionCache: EmotionCache
}

type GuardProps = {
authGuard: boolean
children: ReactNode
}

const clientSideEmotionCache = createEmotionCache()

const wagmiConf = getDefaultConfig({
appName: MyProject',
projectId: 'xxx',
chains: [arbitrum, bsc],
transports: {
[arbitrum.id]: http(),
[bsc.id]: http()
},
ssr: true
})

if (themeConfig.routingLoader) {
Router.events.on('routeChangeStart', () => {
NProgress.start()
})
Router.events.on('routeChangeError', () => {
NProgress.done()
})
Router.events.on('routeChangeComplete', () => {
NProgress.done()
})
}

const queryClient = new QueryClient()

const Guard = ({ children, authGuard }: GuardProps) => {
if (!authGuard) {
return <>{children}</>
} else {
return <AuthGuard fallback={}>{children}
}
}

const App = (props: ExtendedAppProps) => {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props

const contentHeightFixed = Component.contentHeightFixed ?? false
const getLayout =
Component.getLayout ?? (page => {page})

const setConfig = Component.setConfig ?? undefined
const authGuard = Component.authGuard ?? true

return (

 <CacheProvider value={emotionCache}>
      <Head>
        <title>Title</title>
        <meta
          name='description'
          content='Content'
        />
        <meta
          name='keywords'
          content='keyword'
        />
        <meta name='viewport' content='initial-scale=1, width=device-width' />
      </Head>

  <WagmiProvider config={wagmiConf}>
    <SessionProvider session={pageProps.session}>
      <RainbowKitProvider modalSize='wide' theme={darkTheme()}>
        <QueryClientProvider client={queryClient}>
          <HydrationBoundary state={pageProps.dehydratedState}>
            <UsernameProvider>
              <SettingsProvider {...(setConfig ? { pageSettings: setConfig() } : {})}>
                <SettingsConsumer>
                  {({ settings }) => {
                    return (
                      <ThemeComponent settings={settings}>
                        <Guard authGuard={authGuard}>{getLayout(<Component {...pageProps} />)}</Guard>
                        <ReactHotToast>
                          <Toaster
                            position={settings.toastPosition}
                            toastOptions={{ className: 'react-hot-toast' }}
                          />
                        </ReactHotToast>
                      </ThemeComponent>
                    )
                  }}
                </SettingsConsumer>
              </SettingsProvider>
            </UsernameProvider>
            <Analytics />
            <ReactQueryDevtools />
          </HydrationBoundary>
        </QueryClientProvider>
      </RainbowKitProvider>
    </SessionProvider>
  </WagmiProvider>
</CacheProvider>
)
}

export default App

Link to Minimal Reproducible Example (CodeSandbox, StackBlitz, etc.)

No response

Anything else?

No response

magiziz commented 7 months ago

@Kaldrogh Thanks for raising this issue. I see you use a lot of custom logic outside of your <App /> component like Component.getLayout and others. This error happens if you're using any of the wagmi hooks outside of the <QueryClientProvider /> component.

Is this the case on your end ? Also if you try to remove <RainbowKitProvider /> will the issue persist ? Cleaning your browser cache may i also help.

Kaldrogh commented 7 months ago

@Kaldrogh Thanks for raising this issue. I see you use a lot of custom logic outside of your <App /> component like Component.getLayout and others. This error happens if you're using any of the wagmi hooks outside of the <QueryClientProvider /> component.

Is this the case on your end ? Also if you try to remove <RainbowKitProvider /> will the issue persist ? Cleaning your browser cache may i also help.

Thanks a lot for your help!

If i remove the <RainbowKitProvider, it starts to work normally as before.

I also try to enclose my variables initialization within the WagmiProvider scope, with no luck. I even try to enclose them within the RainbowKitProvider one and clear the cache, but it doesn't change anything.

Working version:

  <WagmiProvider config={wagmiConf}>
        {(() => {
          const contentHeightFixed = Component.contentHeightFixed ?? false
          const getLayout =
            Component.getLayout ?? (page => <UserLayout contentHeightFixed={contentHeightFixed}>{page}</UserLayout>)

          const setConfig = Component.setConfig ?? undefined
          const authGuard = Component.authGuard ?? true

          return (
            <QueryClientProvider client={queryClient}>
              <HydrationBoundary state={pageProps.dehydratedState}>
                <SessionProvider session={pageProps.session}>
                  <UsernameProvider>
                    <SettingsProvider {...(setConfig ? { pageSettings: setConfig() } : {})}>
                      <SettingsConsumer>
                        {({ settings }) => (
                          <ThemeComponent settings={settings}>
                            <Guard authGuard={authGuard}>{getLayout(<Component {...pageProps} />)}</Guard>
                            <ReactHotToast>
                              <Toaster
                                position={settings.toastPosition}
                                toastOptions={{ className: 'react-hot-toast' }}
                              />
                            </ReactHotToast>
                          </ThemeComponent>
                        )}
                      </SettingsConsumer>
                    </SettingsProvider>
                  </UsernameProvider>
                  <Analytics />
                  <ReactQueryDevtools />
                </SessionProvider>
              </HydrationBoundary>
            </QueryClientProvider>
          )
        })()}
      </WagmiProvider>

Non working version:

      <WagmiProvider config={wagmiConf}>
        {(() => {
          const contentHeightFixed = Component.contentHeightFixed ?? false
          const getLayout =
            Component.getLayout ?? (page => <UserLayout contentHeightFixed={contentHeightFixed}>{page}</UserLayout>)

          const setConfig = Component.setConfig ?? undefined
          const authGuard = Component.authGuard ?? true

          return (
            <QueryClientProvider client={queryClient}>
              <HydrationBoundary state={pageProps.dehydratedState}>
                <SessionProvider session={pageProps.session}>
                  <RainbowKitProvider modalSize='wide' theme={darkTheme()}>
                    <UsernameProvider>
                      <SettingsProvider {...(setConfig ? { pageSettings: setConfig() } : {})}>
                        <SettingsConsumer>
                          {({ settings }) => (
                            <ThemeComponent settings={settings}>
                              <Guard authGuard={authGuard}>{getLayout(<Component {...pageProps} />)}</Guard>
                              <ReactHotToast>
                                <Toaster
                                  position={settings.toastPosition}
                                  toastOptions={{ className: 'react-hot-toast' }}
                                />
                              </ReactHotToast>
                            </ThemeComponent>
                          )}
                        </SettingsConsumer>
                      </SettingsProvider>
                    </UsernameProvider>
                    <Analytics />
                    <ReactQueryDevtools />
                  </RainbowKitProvider>
                </SessionProvider>
              </HydrationBoundary>
            </QueryClientProvider>
          )
        })()}
      </WagmiProvider>

Also non working version:

 <WagmiProvider config={wagmiConf}>
        <QueryClientProvider client={queryClient}>
          <HydrationBoundary state={pageProps.dehydratedState}>
            <SessionProvider session={pageProps.session}>
              <RainbowKitProvider modalSize='wide' theme={darkTheme()}>
                {(() => {
                  const contentHeightFixed = Component.contentHeightFixed ?? false
                  const getLayout =
                    Component.getLayout ??
                    (page => <UserLayout contentHeightFixed={contentHeightFixed}>{page}</UserLayout>)

                  const setConfig = Component.setConfig ?? undefined
                  const authGuard = Component.authGuard ?? true

                  return (
                    <UsernameProvider>
                      <SettingsProvider {...(setConfig ? { pageSettings: setConfig() } : {})}>
                        <SettingsConsumer>
                          {({ settings }) => (
                            <ThemeComponent settings={settings}>
                              <Guard authGuard={authGuard}>{getLayout(<Component {...pageProps} />)}</Guard>
                              <ReactHotToast>
                                <Toaster
                                  position={settings.toastPosition}
                                  toastOptions={{ className: 'react-hot-toast' }}
                                />
                              </ReactHotToast>
                            </ThemeComponent>
                          )}
                        </SettingsConsumer>
                      </SettingsProvider>
                    </UsernameProvider>
                  )
                })()}
                <Analytics />
                <ReactQueryDevtools />
              </RainbowKitProvider>
            </SessionProvider>
          </HydrationBoundary>
        </QueryClientProvider>
      </WagmiProvider>
magiziz commented 7 months ago

@Kaldrogh This works for me:

import "@/styles/globals.css";
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query";
import type { AppProps } from "next/app";
import "@rainbow-me/rainbowkit/styles.css";
import { getDefaultConfig } from "@rainbow-me/rainbowkit";
import { WagmiProvider } from "wagmi";
import { mainnet, polygon, optimism, arbitrum, base } from "wagmi/chains";
import { QueryClient } from "@tanstack/react-query";
import { SessionProvider } from "next-auth/react";

const queryClient = new QueryClient();

const config = getDefaultConfig({
  appName: "My RainbowKit App",
  projectId: "YOUR_PROJECT_ID",
  chains: [mainnet, polygon, optimism, arbitrum, base],
  ssr: true, // If your dApp uses server side rendering (SSR)
});

export default function App({ Component, pageProps }: AppProps) {
  return (
    <WagmiProvider config={config}>
      {(() => {
        return (
          <QueryClientProvider client={queryClient}>
            <HydrationBoundary state={pageProps.dehydratedState}>
              <SessionProvider session={pageProps.session}>
                <RainbowKitProvider modalSize="wide" theme={darkTheme()}>
                  <Component {...pageProps} />
                </RainbowKitProvider>
              </SessionProvider>
            </HydrationBoundary>
          </QueryClientProvider>
        );
      })()}
    </WagmiProvider>
  );
}

Of course i don't have access to all of your other providers, but can you share a small reproducible example via CodeSandbox or Github repo ?

Kaldrogh commented 7 months ago

@Kaldrogh This works for me:

import "@/styles/globals.css";
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query";
import type { AppProps } from "next/app";
import "@rainbow-me/rainbowkit/styles.css";
import { getDefaultConfig } from "@rainbow-me/rainbowkit";
import { WagmiProvider } from "wagmi";
import { mainnet, polygon, optimism, arbitrum, base } from "wagmi/chains";
import { QueryClient } from "@tanstack/react-query";
import { SessionProvider } from "next-auth/react";

const queryClient = new QueryClient();

const config = getDefaultConfig({
  appName: "My RainbowKit App",
  projectId: "YOUR_PROJECT_ID",
  chains: [mainnet, polygon, optimism, arbitrum, base],
  ssr: true, // If your dApp uses server side rendering (SSR)
});

export default function App({ Component, pageProps }: AppProps) {
  return (
    <WagmiProvider config={config}>
      {(() => {
        return (
          <QueryClientProvider client={queryClient}>
            <HydrationBoundary state={pageProps.dehydratedState}>
              <SessionProvider session={pageProps.session}>
                <RainbowKitProvider modalSize="wide" theme={darkTheme()}>
                  <Component {...pageProps} />
                </RainbowKitProvider>
              </SessionProvider>
            </HydrationBoundary>
          </QueryClientProvider>
        );
      })()}
    </WagmiProvider>
  );
}

Of course i don't have access to all of your other providers, but can you share a small reproducible example via CodeSandbox or Github repo ?

Thanks again for helping me, i've tried to remove almost everything, enclose all my variables initialization within wagmi scope, but it doesn't change anything.

The only way to get an other error message (but not a working app unfortunately :( ) is by enclosing wagmi inside rainbowKit:

const App = (props: ExtendedAppProps) => {
  const { emotionCache = clientSideEmotionCache, pageProps } = props

  return (
    <CacheProvider value={emotionCache}>
      <Head>
      </Head>
      <RainbowKitProvider modalSize='wide' theme={darkTheme()}>
        <WagmiProvider config={config}>
          <QueryClientProvider client={queryClient}>
            <HydrationBoundary state={pageProps.dehydratedState}>
              <SessionProvider session={pageProps.session}>
                <UsernameProvider>
                  {(() => {
                    const contentHeightFixed = props.Component.contentHeightFixed ?? false
                    const getLayout =
                      props.Component.getLayout ??
                      (page => <UserLayout contentHeightFixed={contentHeightFixed}>{page}</UserLayout>)

                    const setConfig = props.Component.setConfig ?? undefined
                    const authGuard = props.Component.authGuard ?? true

                    return (
                      <SettingsProvider {...(setConfig ? { pageSettings: setConfig() } : {})}>
                        <SettingsConsumer>
                          {({ settings }) => (
                            <ThemeComponent settings={settings}>
                              <Guard authGuard={authGuard}>{getLayout(<props.Component {...pageProps} />)}</Guard>
                              <ReactHotToast>
                                <Toaster
                                  position={settings.toastPosition}
                                  toastOptions={{ className: 'react-hot-toast' }}
                                />
                              </ReactHotToast>
                            </ThemeComponent>
                          )}
                        </SettingsConsumer>
                      </SettingsProvider>
                    )
                  })()}
                </UsernameProvider>

                <Analytics />
                <ReactQueryDevtools />
              </SessionProvider>
            </HydrationBoundary>
          </QueryClientProvider>
        </WagmiProvider>
      </RainbowKitProvider>
    </CacheProvider>
  )
}

Which throws this error:

image

Otherwise, with this enclosure hierarchy, i get the same error message as before:

const App = (props: ExtendedAppProps) => {
  const { emotionCache = clientSideEmotionCache, pageProps } = props

  return (
    <CacheProvider value={emotionCache}>
      <Head>
      </Head>
      <WagmiProvider config={config}>
        <QueryClientProvider client={queryClient}>
          <HydrationBoundary state={pageProps.dehydratedState}>
            <RainbowKitProvider modalSize='wide' theme={darkTheme()}>
              <SessionProvider session={pageProps.session}>
                <UsernameProvider>
                  {(() => {
                    const contentHeightFixed = props.Component.contentHeightFixed ?? false
                    const getLayout =
                      props.Component.getLayout ??
                      (page => <UserLayout contentHeightFixed={contentHeightFixed}>{page}</UserLayout>)

                    const setConfig = props.Component.setConfig ?? undefined
                    const authGuard = props.Component.authGuard ?? true

                    return (
                      <SettingsProvider {...(setConfig ? { pageSettings: setConfig() } : {})}>
                        <SettingsConsumer>
                          {({ settings }) => (
                            <ThemeComponent settings={settings}>
                              <Guard authGuard={authGuard}>{getLayout(<props.Component {...pageProps} />)}</Guard>
                              <ReactHotToast>
                                <Toaster
                                  position={settings.toastPosition}
                                  toastOptions={{ className: 'react-hot-toast' }}
                                />
                              </ReactHotToast>
                            </ThemeComponent>
                          )}
                        </SettingsConsumer>
                      </SettingsProvider>
                    )
                  })()}
                </UsernameProvider>

                <Analytics />
                <ReactQueryDevtools />
              </SessionProvider>
            </RainbowKitProvider>
          </HydrationBoundary>
        </QueryClientProvider>
      </WagmiProvider>
    </CacheProvider>
  )
}

image

It's pretty hard to give a minimal reproduction example as i have a quite complex app...

And my wagmi.config.ts use for the WagmiProvider config prop:

import { getDefaultConfig } from '@rainbow-me/rainbowkit'
import { arbitrum, bsc } from 'wagmi/chains'

export const projectId = process.env.NEXT_PUBLIC_PROJECT_ID

if (!projectId) throw new Error('Project ID is not defined')

const metadata = {
  name: 'My Project',
  description: 'This is my project',
  url: process.env.NEXTAUTH_URL,
  icons: ['/public/images/logo/project.svg']
}

const chains = [arbitrum, bsc] as const
export const config = getDefaultConfig({
  chains,
  projectId,
  appName: metadata.name,
  appDescription: metadata.description,
  appIcon: metadata.icons[0],
  appUrl: metadata.url,
  ssr: true
})

If i remove RainbowKitProvider, it works right out of the box.

Anyway, i'm having a hard time figuring out with an other React Query context would be created as everything is enclosed inside the Wagmi and React Query scope, i was using react query before without having any issues.

Kaldrogh commented 7 months ago

Even when removing everything, clearing the cache, i'm getting the same error:

const App = props => {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <HydrationBoundary state={props.pageProps.dehydratedState}>
          <RainbowKitProvider modalSize='wide' theme={darkTheme()}>
            <props.Component {...props.pageProps} />
          </RainbowKitProvider>
        </HydrationBoundary>
      </QueryClientProvider>
    </WagmiProvider>
  )
}

image

magiziz commented 7 months ago

@Kaldrogh Can you please share a small reproducible example ? I can't see your code right now and how you compute your layouts / components. If you could share a CodeSandbox link or a GitHub code repo that'd be awesome, since we have with-next and with-next-app project examples and they work completely fine.

Kaldrogh commented 7 months ago

@Kaldrogh Can you please share a small reproducible example ? I can't see your code right now and how you compute your layouts / components. If you could share a CodeSandbox link or a GitHub code repo that'd be awesome, since we have with-next and with-next-app project examples and they work completely fine.

Thanks! I can give you access to a private repo so you can try it out on your side, i just need an e-mail address to invite you.

Otherwise, it's nearly impossible to build a reproducible example given the complexity of the app...

magiziz commented 7 months ago

@Kaldrogh I would love to do that, but i would like to keep this as simple as possible. Your project might be big and for us to debug this we would love to just have a simple reproducible example. We don't know if your project might include libraries that blocks TanStack react query from being used or cached.

Would you be able to do that for now ?

Kaldrogh commented 7 months ago

@Kaldrogh I would love to do that, but i would like to keep this as simple as possible. Your project might be big and for us to debug this we would love to just have a simple reproducible example. We don't know if your project might include libraries that blocks TanStack react query from being used or cached.

Would you be able to do that for now ?

I'll try to simplify as much as possible the github repo i wanted to invite you on.

But i don't think that it is related to a library blocking react-query as i'm using react query everywhere inside my app for caching purpose for a very long time, and i never had any issue at all, i can see my cached queries inside the react query tool, as well as the cached entries for wagmi.

As soon as i try to enclose my app with the rainbowkit, it stops working immediatly and throws the no QueryClient error. If i remove it, wagmi and react-query work perfectly fine again.

magiziz commented 7 months ago

@Kaldrogh Got it. Yeah this could be maybe conflicting peer dependencies with wagmi and viem probably, but can you just provide a small reproducible example instead of inviting me to a whole github repo project ?

Like i know you're facing this issue, but giving a small reproducible example would be the best since we don't want to go over the whole codebase project.

Kaldrogh commented 7 months ago

@Kaldrogh Got it. Yeah this could be maybe conflicting peer dependencies with wagmi and viem probably, but can you just provide a small reproducible example instead of inviting me to a whole github repo project ?

Like i know you're facing this issue, but giving a small reproducible example would be the best since we don't want to go over the whole codebase project.

Here you go, i've reproduced the error in a fresh and new repo:

https://github.com/Kaldrogh/RainbowKit-Test

Kaldrogh commented 7 months ago

The problem seems to be directly correlated to the next.config.js file which have been copied and pasted from my main app.

Kaldrogh commented 7 months ago

The problem comes from this experimental parameter:

experimental: { esmExternals: false, },

Once removed, it starts working normally, with a "ReferenceError: localStorage is not defined" thrown tho.

magiziz commented 7 months ago

@Kaldrogh Yeah i can see the error now 🙏

When doing esmExternals: false next.js won't recognise RainbowKitProvider as esm module and we're also using peer dependencies such as wagmi and viem+ on top of wagmi we're using @tanstack/react-query which is why the webpack / builds might throw an error here.

If you have conflicts between different esm modules in your project you can also try doing esmExternals: 'loose' which may correct some errors when building your app. Here is the docs for reference.

If you're getting localStorage error you need to add ssr: true to your getDefaultConfig function i see you have it specified as false at the moment.

magiziz commented 7 months ago

@Kaldrogh Any updates ?

Kaldrogh commented 7 months ago

@Kaldrogh Any updates ?

Sorry for replying late, i was busy.

After setting esmExternal to 'loose', it seems to work like a charm again! But i'll have to check everything more thoroughtly as i'm also using a library called uploadthing which required to set esmExternals to 'false'.

Anyway, thank you very much for your help!

magiziz commented 7 months ago

All good. Feel free to raise another issue if you encounter any other bugs 🙏