connectkit icon indicating copy to clipboard operation
connectkit copied to clipboard

[BUG] Not compatible with Wagmi persistence with cookies

Open 0x3dev opened this issue 1 year ago • 8 comments

Describe the bug

When trying to implement the steps outlined in Wagmi SSR page, specifically Persistence using Cookies, NextJS throws this error:

Error: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function eval node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/framer-motion/dist/es/context/LazyContext.mjs (3:32) (rsc)/./node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/framer-motion/dist/es/context/LazyContext.mjs

To reproduce

Create a new project with npm create wagmi --template next and add connectkit to it. The error will show at first run.

Additional context

If we don't pass the initialState like this, const initialState = cookieToInitialState( getConfig(), headers().get("cookie") );

The error is gone, so it seems the method getDefaultConfig from connectkit doesn't support SSR.

0x3dev avatar Jul 06 '24 09:07 0x3dev

I have run into the same issue after attempting to implement the SSR guide on the wagmi docs. I came looking for this after noticing a recurring issue whereby the current wallet seems to persist after calling disconnect() with the UI or wagmi, leading to a Metamask error when you try to connect the same or another wallet again. Only when the page is fully refreshed can you connect again. I assumed this issue lies in some incomplete configuration for Next.js, which is why i have added this here to the SSR implementation issues.

This is currently observable in your docs too here. You can follow these steps to reproduce: (1) Connect with MM (2) Disconnect (without page refresh) (3) Connect again with MM (4) MM error (5) Refresh page and connect with MM succeeds.

See demo below:

https://github.com/family/connectkit/assets/16241905/b6114847-e401-47c6-9f12-d3ad66b8c1b1

sazzouz avatar Jul 07 '24 21:07 sazzouz

Confirming I'm having the same issue.

seeARMS avatar Aug 13 '24 21:08 seeARMS

Confirming I'm having the same issue.

Hello, you need to add 'use client' at the top of your page (where connectKit is included/imported) as shown below

pr1 pr2

I'm waiting you to pay the bounty please, here's my address: 0xBbA4Ef1F2749Bb679e35c357D26217761a061B73, thank you

BenraouaneSoufiane avatar Aug 15 '24 05:08 BenraouaneSoufiane

Hello @0x3dev!

After investigating, it appears that this error is related to framer-motion, a dependency of ConnectKit. Even though getDefaultConfig itself doesn't directly use framer-motion, importing from ConnectKit causes framer-motion to be initialized in a server context where it's not compatible.

Interestingly, when I create a local version of getDefaultConfig that doesn't import from ConnectKit, the error doesn't occur. This suggests that the issue is specifically related to how ConnectKit's dependencies are being loaded or initialized in an SSR context.

Below is the code that is server-side rendered and causing the issue:

const initialState = cookieToInitialState(
  getConfig(),
  headers().get("cookie")
);

Some Workarounds

  1. Pass a normal config created through createConfig imported from wagmi into this server-rendered code and use a ConnectKit default config in WagmiProvider.
export function getConfig() {
  const config = createConfig(
    getDefaultConfig({
      // Your dApp's chains
      chains: [mainnet],
      transports: {
        // RPC URL for each chain
        [mainnet.id]: http(
          `https://eth-mainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`
        ),
      },

      // Required API Keys
      walletConnectProjectId: "WalletConnect Project Id",

      // Required App Info
      appName: "Your App Name",

      // Optional App Info
      appDescription: "Your App Description",
      appUrl: "https://family.co", // your app's url
      appIcon: "https://family.co/logo.png", // your app's icon, no bigger than 1024x1024px (max. 1MB)
      ssr: true,
      storage: createStorage({
        storage: cookieStorage,
      }),
    })
  );

  return config;
}

export function getWagmiConfig() {
  return createConfig({
    chains: [mainnet],
    ssr: true,
    storage: createStorage({
      storage: cookieStorage,
    }),
    transports: {
      [mainnet.id]: http(),
    },
  });
}
  1. Implement the getDefaultConfig method locally. Refer to this example.

sahilkakwani9 avatar Aug 17 '24 14:08 sahilkakwani9

Wow nice discovery @sahilkakwani9! Thanks for investigating this, definitely weird that framer-motion is causing this issue.

We've internally discussed removing framer-motion now that view transitions and other similar tech are now more widely supported. Might be ideal for us to fast track that update now knowing this is an issue 🤔

lochie avatar Aug 17 '24 15:08 lochie

It not depends on the connectKit even on the wagmi, it depends on the framework, how to get rendered, it's not a bug @seeARMS although you've marked the bounty as completed, nothing received

BenraouaneSoufiane avatar Aug 17 '24 16:08 BenraouaneSoufiane

Just wanted to flag that I finally got around to implementing @sahilkakwani9's workaround. It works great and removes the exception thrown in the OP, but unfortunately it also prevents users from using the MetaMask Chrome extension -- it always prompts them to use their phone to sign in with Metamask. Setting ssr: false with no other changes fixes this.

Presumably there's an issue with extension detection when it's first server-rendered?

seeARMS avatar Sep 30 '24 23:09 seeARMS

hi, @sahilkakwani9 thanks a lot for workaround with cookies storage, but I'd like to ask something, do you still have an issue to see empty space instead of wallet account when you refresh the page. with only Wagmi it worked well but when I added connectKit and using your workaround now it blinks on refresh

ArmmGh avatar Nov 08 '24 07:11 ArmmGh