Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Fix "window not found" error for SSR / NextJS apps #41

Open
DoubleOTheven opened this issue Apr 6, 2023 · 3 comments
Open

Fix "window not found" error for SSR / NextJS apps #41

DoubleOTheven opened this issue Apr 6, 2023 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@DoubleOTheven
Copy link
Contributor

Feature Request

Currently users must dynamically import useink because extensionJS requires window to be in scope. This does not work on SSR. Life would be so much better if we did not have to lazy load...

Suggestion

To anyone willing to pick this up, please offer suggestions in the chat here.

@felixpolimec
Copy link

felixpolimec commented Apr 12, 2023

@DoubleOTheven would a Context that wraps and exposes useink be sufficient?
I have not looked into if possible to work around this via extensionJS

Here a pseudo/workable code that should direct the conversation towards a working solution.

I use this on a rather complicated landscape of apps and libs, and it works quite well.

import { createContext, FC, useEffect, useState } from 'react';

declare type UseInkType = typeof import('useink/types/mod');

interface IUseInkContext extends React.HTMLAttributes<'div'>, UseInkType {}

export const UseInkContext = createContext<IUseInkContext>(
  {} as IUseInkContext
);

export const UseInkContextProvider: FC<
  React.HTMLAttributes<'div'> & { dapp: string; provider: string }
> = ({ children, dapp, provider }) => {
  const [useInkInstance, setUseInkInstance] = useState<UseInkType | null>(null);
  useEffect(() => {
    const init = async () => {
      const useinkLibrary = await import('useink');

      setUseInkInstance(useinkLibrary);
    };
    init();
  }, []);

  if (!useInkInstance) {
    // FIXME: This is a workaround to avoid SSR errors (e.g. "window is not defined") until useink is available
    // Fix using this context is to move the context as far down the render pipeline as possible.
    return <></>;
  }

  const InternalUseInkProvider = useInkInstance.UseInkProvider;

  return (
    <UseInkContext.Provider value={useInkInstance}>
      <InternalUseInkProvider
        config={{
          // Name that shows in the wallet extensions that connect
          dappName: dapp,

          // The chain
          // ex.: providerUrl: 'wss://rococo-contracts-rpc.polkadot.io',
          providerUrl: provider,
        }}
      >
        {children}
      </InternalUseInkProvider>
    </UseInkContext.Provider>
  );
};

@peetzweg peetzweg added the bug Something isn't working label Apr 12, 2023
@DoubleOTheven DoubleOTheven self-assigned this Apr 16, 2023
@DoubleOTheven
Copy link
Contributor Author

@felixpolimec There are rules of hooks. One of them is that the must be called on every render. If you have an if statement that returns if a condition if false then any hooks after this will break that rule. talisman-connect might have a solution to this. I'm currently working on integrating it to useink

@0xLucca
Copy link

0xLucca commented May 22, 2023

Hi there! Any updates on this fix?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants