Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with NextJS #86

Closed
codebyshennan opened this issue Oct 14, 2022 · 5 comments
Closed

Integration with NextJS #86

codebyshennan opened this issue Oct 14, 2022 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@codebyshennan
Copy link

Describe the bug

I've tried to set-up Unleash on an existing NextJS repository, following the steps in the quickstart guide:

without creating a custom-server, as denoted here, is there another way to configure a nextjs app to accept unleash flags?

Steps to reproduce the bug

function MyApp({ Component, pageProps }) {
  return (
    <GoogleReCaptchaProvider reCaptchaKey='xxx'>
      <FlagProvider config={unleashConfig}>
        <QueryClientProvider client={reactQueryClient}>
         // ... rest of code
         )}

The unleash configs are as follows:

const UNLEASH_DEV = {
  url: 'https://us.app.unleash-hosted.com/xxx/api/development/proxy',
  key: 'xxx'
}

const UNLEASH_PROD = {
  url: 'https://us.app.unleash-hosted.com/xxx/api/production/proxy',
  key: 'xxx'
}

const unleashConfig = {
  url:
    process.env.NEXT_PUBLIC_NODE_ENV === 'development'
      ? UNLEASH_DEV.url
      : UNLEASH_PROD.url,
  clientKey:
    process.env.NEXT_PUBLIC_NODE_ENV === 'development'
      ? UNLEASH_DEV.key
      : UNLEASH_PROD.key,
  refreshInterval: 15,
  appName: 'xxx',
  environment:
    process.env.NEXT_PUBLIC_NODE_ENV === 'development'
      ? 'development'
      : 'production'
}

export default unleashConfig

Expected behavior

No response

Logs, error output, etc.

without using any hooks yet e.g. `useFlags`, this is the current error message on server start:


Unleash failed to resolve "fetch" ReferenceError: window is not defined
    at resolveFetch (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:99:24)
    at new UnleashClient (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:115:540)
    at u (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/@unleash/proxy-client-react/dist/index.js:1:1241)
    at renderWithHooks (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5658:16)
    at renderIndeterminateComponent (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5731:15)
    at renderElement (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5946:7)
    at renderNodeDestructiveImpl (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6104:11)
    at renderNodeDestructive (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6076:14)
    at renderContextProvider (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5920:3)
    at renderElement (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6017:11)
ReferenceError: window is not defined
    at LocalStorageProvider.get (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:62:24)
    at UnleashClient.<anonymous> (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:307:63)
    at step (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:59:23)
    at Object.next (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:40:53)
    at /Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:34:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:30:12)
    at UnleashClient.resolveSessionId (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:300:16)
    at UnleashClient.<anonymous> (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:242:55)
    at step (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:59:23)
Unleash: You must either provide your own "fetch" implementation or run in an environment where "fetch" is available.
ReferenceError: window is not defined
    at LocalStorageProvider.<anonymous> (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:50:21)
    at step (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:33:23)
    at Object.next (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:14:53)
    at /Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:4:12)
    at LocalStorageProvider.save (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:44:16)
    at UnleashClient.<anonymous> (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:312:59)
    at step (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:59:23)
    at Object.next (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:40:53)
ReferenceError: window is not defined
    at LocalStorageProvider.get (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/storage-provider-local.js:62:24)
    at UnleashClient.<anonymous> (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:247:59)
    at step (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:59:23)
    at Object.next (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:40:53)
    at fulfilled (/Users/wongshen.nan/Desktop/circles/faber/app/node_modules/unleash-proxy-client/build/index.js:31:58)


### Screenshots

_No response_

### Additional context

_No response_

### Unleash version

@unleash/proxy-client-react": "^3.3.1

### Subscription type

_No response_

### Hosting type

_No response_

### SDK information (language and version)

_No response_
@codebyshennan codebyshennan added the bug Something isn't working label Oct 14, 2022
@andreas-unleash
Copy link
Contributor

Hi @wongshennan , thanks for creating the issue, I will bring it up with the team and get back to you

@thomasheartman
Copy link
Contributor

Hey, @wongshennan 🙋🏼 Thanks for opening the issue:

I think the base issue at hand here is that Next tries to initialize the client during its server-side rendering. However, window.fetch is not available in that context. Instead, you need to provide the client with an alternate fetch implementation, such as node-fetch. You'll also need to provide a replacement storage provider. This is best explained in #40 (where the following example is listed):

const UnleashProvider: typeof FlagProvider = ({ config = {}, children }) => {
  // To prevent from throwing during SSR, pass a dummy storage provider
  const storageProvider = isNode
    ? new DummyStorageProvider()
    : window.localStorage;

  // Similarly, pass a dummy fetch provider
  const fetchProvider = isNode ? fetch : undefined;

  return (
    <FlagProvider
      config={{
        storageProvider,
        fetch: fetchProvider,
        url: process.env["UNLEASH_URL"],
        clientKey: process.env["UNLEASH_CLIENT_KEY"],
        refreshInterval: 15,
        appName: process.env["APP_NAME"],
        environment: process.env["APP_ENV"],
        ...config,
      }}
    >
      {children}
    </FlagProvider>
  );
};

If I'm correct, then that should solve your issue here. But you might also want to consider whether creating an unleash client on every request is the right way to go or not. Doing it this way will delay rendering as the client needs to be constructed and fetch toggles.

Instead, you might want to consider alternate approaches. For instance:

Does that help? ☺️

@BkSouX
Copy link

BkSouX commented Jan 2, 2023

would be great to have a better integration with NextJS 👍

@Tymek Tymek self-assigned this Jan 19, 2023
@Tymek
Copy link
Member

Tymek commented Jan 19, 2023

Probably fixed with Unleash/unleash-proxy-client-js#134
Make sure you're on unleash-proxy-client v2.4.1.

@BkSouX agree. I'm working on it.

@Tymek
Copy link
Member

Tymek commented Jan 23, 2023

@Tymek Tymek closed this as completed Jan 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

No branches or pull requests

5 participants