rainbow-me / rainbowkit

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

[bug] <Cannot read properties of undefined (reading 'toLowerCase')> Navigator undefined in getBrowser #2036

Closed 0xAskar closed 3 weeks ago

0xAskar commented 3 weeks ago

Is there an existing issue for this?

RainbowKit Version

2.1.2

wagmi Version

2.9.10

Current Behavior

The problem is that after migrating and following the migration guides to the 2.x rainbow wallet, and the same for wagmi and viem, I'm getting a weird problem where the navigator in the node_modules/@rainbow-me/rainbowkit/dist/index.js is not being recognized, such that the function, getBrowser() has a problem when navigator.userAgent.toLowercase() is called because navigator is an empty Object (I console.log'ed it and it showed that).

If I just return normally with an if statement checking if its empty, my code runs as functioned. But I assume you shouldn't be changing the node modules for rainbow kits. So any idea why this is happening?

So, please see the full error below:

image
function getBrowser() {
  if (typeof navigator === "undefined")
    return "Browser" /* Browser */;
  const ua2 = navigator.userAgent.toLowerCase();
  ...

I've attached my app.js below

import React from "react";
import { GlobalPriceProvider } from "../context/GlobalPriceContext";
import "../styles/globals.css";
import Router from 'next/router';
import { NextUIProvider } from "@nextui-org/react";
import dotenv from "dotenv";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import "@rainbow-me/rainbowkit/styles.css";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { SpeedInsights } from '@vercel/speed-insights/next';
import { Analytics } from "@vercel/analytics/react";
import {
  getDefaultConfig,
  RainbowKitProvider,
  darkTheme
} from "@rainbow-me/rainbowkit";
import { WagmiProvider, http } from 'wagmi';
import { CompModalProvider } from "context/CompModalContext";
import {
  RainbowKitSiweNextAuthProvider,
} from "@rainbow-me/rainbowkit-siwe-next-auth";
import { SessionProvider } from "next-auth/react";
import { mainnet, polygon, optimism, arbitrum, base } from "wagmi/chains";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import Sidebar from "@/components/UI/layouts/Sidebar";
import { AccountInfoProvider } from "context/AccountInfoContext";

const config = getDefaultConfig({
  appName: 'DegenzFinance',
  projectId: "hidden",
  chains: [mainnet],
  ssr: true, // If your dApp uses server side rendering (SSR)
});

const queryClient = new QueryClient()

const Disclaimer = ({ Text, Link }) => (
  <Text>
    By connecting your wallet, you agree to the Degenz.Finance{' '}
    <Link href="/tos">Terms of Service</Link> and
    acknowledge you have read and understand the {' '}
    <Link href="/privacy">Privacy Policy</Link>. An account shall be created when you sign in. 
  </Text>
);

const getSiweMessageOptions = () => ({
  statement:
    "Verify wallet ownership on Degenz.Finance. By signing, an account is created, and you agree to the Terms of Service and Privacy Policy",
});
NProgress.configure({ showSpinner: false });

Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());

dotenv.config()
function App({ Component, pageProps }) {
  return (
    <>
    <SpeedInsights />
    <Analytics />
    <NextUIProvider>
    <main className="dark text-foreground bg-background">   
     <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <SessionProvider refetchInterval={0} session={pageProps.session}>
          <RainbowKitSiweNextAuthProvider
            getSiweMessageOptions={getSiweMessageOptions}
          >
            <RainbowKitProvider

              modalSize="wide"
              initialChain={1}
              appInfo={{ appName: "Degenz.Finance", disclaimer: Disclaimer }}
              theme={darkTheme({
                accentColor: '#5A40FF',
                accentColorForeground: 'white',
                borderRadius: 'large',
                fontStack: 'system',
                fontWeight:"400",
                overlayBlur: 'small',
                })}
              >
              <AccountInfoProvider>
              <GlobalPriceProvider>
                <CompModalProvider>
                    <main className="flex grow bg-background">
                        <Component {...pageProps} />
                    </main>
                    <ToastContainer 
                      autoClose={2000}
                      theme="dark"
                      position="top-left"
                      pauseOnHover={false}
                    />

                </CompModalProvider>
              </GlobalPriceProvider>
              </AccountInfoProvider>
            </RainbowKitProvider>
          </RainbowKitSiweNextAuthProvider>
        </SessionProvider>
      </QueryClientProvider>
    </WagmiProvider>
    </main>
    </NextUIProvider>
    </>
  );
}

export default App;
magiziz commented 3 weeks ago

@0xAskar What browser are you using ? Can you share a small reproducible example ?

0xAskar commented 3 weeks ago

@magiziz I used both Firefox and Chrome. I can perhaps release a reproducible example a bit later in the day. But, I don't seem to problem disrupt functionality in production, just in developing.

Would it make sense to add just error handling that ensures Navigator isn't an empty object as well. Would it be possible to update the library to have that in the getBrowser function?

magiziz commented 3 weeks ago

@0xAskar Yeah i'll get that fixed, but it's hard for me to debug if i can't reproduce this on my end. Whenever you have time can you just link a small reproducible example here ? I can't seem to get that error in the console for some reason.

0xAskar commented 3 weeks ago

@magiziz hey mate, i just added a reproducible example by stripping down every file or component in my project and just keeping the bare mimium. the package json is mostly the same. Also, if you're going to fix it by just adding another clause in the if, could I do that lol? I have never publicly fixed a bug on an open sourced project and would love to learn how.

I don't know if there is a better way but i made a public repo, let me know if you get the problem, because i still do with this stripped down repo https://github.com/0xAskar/RainbowKitNavBug

magiziz commented 3 weeks ago

@0xAskar I can't seem to reproduce this locally on chrome. I only see the next-auth errors and not the navigator.userAgent error.

image

If you want to fix this you're welcome to open a PR, but this should be an easy fix i just can't seem to reproduce this on my end.

0xAskar commented 3 weeks ago

@magiziz Hey, so just to check my sanity, I deleted the reprod. example and recloned it, installed the libraries, and re-ran. I still get the same error. I assume this is just some local error but still pops up due to lack of error handling if the object is empty.

anyways, i created the pull request, lmk if anything needs to change and we can update it. That would make developing much easier to do, because rn i have to amend the index file within the rainbowkit modules myself

magiziz commented 3 weeks ago

@0xAskar Thanks! I'll take a look 👍