Giter Site home page Giter Site logo

proxy-client-react's Introduction

What is Unleash?

Unleash is a powerful open source solution for feature management. It streamlines your development workflow, accelerates software delivery, and empowers teams to control how and when they roll out new features to end users. With Unleash, you can deploy code to production in smaller, more manageable releases at your own pace.

Feature flags in Unleash let you test your code with real production data, reducing the risk of negatively impacting your users' experience. It also enables your team to work on multiple features simultaneously without the need for separate feature branches.

Unleash is the most popular open source solution for feature flagging on GitHub. It supports 15 official client and server SDKs and over 15 community SDKs. You can even create your own SDK if you wish. Unleash is compatible with any language and framework.


Getting Started with Unleash

1. Setting Up Unleash

To get started with Unleash, you need git and docker installed on your machine.

Execute the following commands:

git clone [email protected]:Unleash/unleash.git
cd unleash
docker compose up -d

Then point your browser to localhost:4242 and log in using:

  • username: admin
  • password: unleash4all

If you'd rather run the source code in this repo directly via Node.js, see the step-by-step instructions to get up and running in the contributing guide.

2. Connect your SDK

Find your preferred SDK in our list of official SDKs and import it into your project. Follow the setup guides for your specific SDK.

If you use the docker compose file from the previous step, here's the configuration details you'll need to get going:

  • For front-end SDKs, use:
    • URL: http://localhost:4242/api/frontend/
    • clientKey: default:development.unleash-insecure-frontend-api-token
  • For server-side SDKs, use:
    • Unleash API URL: http://localhost:4242/api/
    • API token: default:development.unleash-insecure-api-token

If you use a different setup, your configuration details will most likely also be different.

Check a feature flag

Checking the state of a feature flag in your code is easy! The syntax will vary depending on your language, but all you need is a simple function call to check whether a flag is available. Here's how it might look in Java:

if (unleash.isEnabled("AwesomeFeature")) {
  // do new, flashy thing
} else {
  // do old, boring stuff
}

Run Unleash on a service?

If you don't want to run Unleash locally, we also provide easy deployment setups for Heroku and Digital Ocean:

Deploy to Heroku Deploy to DigitalOcean

Configure and run Unleash anywhere

The above sections show you how to get up and running quickly and easily. When you're ready to start configuring and customizing Unleash for your own environment, check out the documentation for getting started with self-managed deployments, Unleash configuration options, or running Unleash locally via docker.


Online demo

Try out the Unleash online demo.

The Unleash online demo


Community and help — sharing is caring

We know that learning a new tool can be hard and time-consuming. We have a growing community that loves to help out. Please don't hesitate to reach out for help.

Join Unleash on Slack

💬 Join Unleash on Slack if you want ask open questions about Unleash, feature toggling or discuss these topics in general.

💻 Create a GitHub issue if you have found a bug or have ideas on how to improve Unleash.

📚 Visit the documentation for more in-depth descriptions, how-to guides, and more.

📖 Learn more about the principles of building and scaling feature flag solutions.


Contribute to Unleash

Unleash is the largest open source feature flag solution on GitHub. Building Unleash is a collaborative effort, and we owe a lot of gratitude to many smart and talented individuals. Building it together with the community ensures that we build a product that solves real problems for real people. We'd love to have your help too: Please feel free to open issues or provide pull requests.

Check out the CONTRIBUTING.md file for contribution guidelines and the Unleash developer guide for tips on environment setup, running the tests, and running Unleash from source.

Contributors

The Unleash contributors


Features our users love

Flexibility and adaptability

Security and performance

  • Privacy by design (GDPR and Schrems II). End-user data never leaves your application.
  • Audit logs
  • Enforce OWASP's secure headers via the strict HTTPS-only mode
  • Flexible hosting options: host it on premise or in the cloud (any cloud)
  • Scale the Unleash Proxy independently of the Unleash server to support any number of front-end clients without overloading your Unleash instance

Looking for more features?

If you're looking for one of the following features, please take a look at our Pro and Enterprise plans:


Architecture

Read more in the system overview section of the Unleash documentation.


Unleash SDKs

To connect your application to Unleash you'll need to use a client SDK for your programming language.

Official server-side SDKs:

Official front-end SDKs:

The front-end SDKs connects via the Unleash Proxy in order to ensure privacy, scalability and security.

Community SDKs:

If none of the official SDKs fit your need, there's also a number of community-developed SDKs where you might find an implementation for your preferred language (such as Elixir, Dart, Clojure, and more).


Users of Unleash

Unleash is trusted by thousands of companies all over the world.

Proud Open-Source users: (send us a message if you want to add your logo here)

The Unleash logo encircled by logos for Finn.no, nav (the Norwegian Labour and Welfare Administration), Budgets, Otovo, and Amedia. The encircling logos are all connected to the Unleash logo.


Migration guides

Unleash has evolved significantly over the past few years, and we know how hard it can be to keep software up to date. If you're using the current major version, upgrading shouldn't be an issue. If you're on a previous major version, check out the Unleash migration guide!


Want to know more about Unleash?

Videos and podcasts

Articles and more

proxy-client-react's People

Contributors

6uliver avatar andreas-unleash avatar andy-edwards-nutmeg avatar demetri0 avatar dependabot[bot] avatar elisechant avatar ericledonge avatar faessler avatar fredrikoseberg avatar gabrielnastase avatar iamchanii avatar ivarconr avatar jameshartig avatar jestermaxrko avatar jtaaa avatar kenystev avatar kwasniew avatar melloware avatar nunogois avatar olav avatar sjaanus avatar smksnutmeg avatar stefanwerw avatar thomasheartman avatar tymek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

proxy-client-react's Issues

useFlagsStatus always returns false for flagsReady

Describe the bug

Hello! We recently upgraded from 3.4.0 to 3.5.0, and noticed that for some reason our feature toggles aren't working when running locally. We have a wrapper hook with the following line:

const { flagsReady, flagsError } = useFlagsStatus()

Previously flagsReady would come back as true if everything is fine, but now it only seems to be false. It's not obvious to me why though, as the 3.5.0 release only appears to contain dependency upgrades. But if I downgrade to 3.4.0 and don't change anything else, it works fine as usual. I also tried the v3.5.0-beta.0 release and found the same issue.

Strangely, it does seem to work fine in our staging deployment. But we've tried on two different machines and found the same thing.

Subscription type

Open source

Hosting type

Self-hosted

Use with next.js / SSR

Hi there,

In my next.js app, I currently use unleash-client in my server middleware and a custom implementation of unleash-proxy-client in my components. I pass down the server-side flags and use them as initial state, then initialize the proxy client in a useEffect and override the flags. This allows me to use feature flags during SSR, then continue checking them during CSRs.

I'd like to switch over to proxy-client-react, but I've run into a problem during SSR. The FlagsProvider always tries to initialize a client even if window isn't available, which results in errors while rendering. I know that I can initialize an UnleashClient in a useEffect, then prevent rendering FlagsProvider until the client has been initialized. But this would mean basically all of my app (anything rendered inside FlagsProvider) wouldn't be rendered during SSR, which results in a huge performance hit.

Ideally, FlagsProvider would also initialize the client in a useEffect to allow it to be rendered during SSR - has this been considered? React apps using SSR in production are extremely common these days, so I would've thought this is a pretty common use case.

Alternatively, is there any other way you could recommend to get around this problem?

Thanks in advance!

useFlag breaks server side

Describe the bug

Describe the bug

Our app is both SSR and client side rendered and as such we need to use both @unleash/proxy-client-react, as well as unleash-client unleash-proxy-client

TypeError: Cannot read properties of null (reading 'isEnabled')

To get this working we need to do something along these lines

import { useReactiveVar } from '@apollo/client'
import { useFlag } from '@unleash/proxy-client-react'
import { variables } from 'core/variables'
import { UnleashFlagKey } from 'types/UnleashFlagKey'

const useUnleashFlag = (flag: UnleashFlagKey) => {
  const serverFlag = useReactiveVar(variables.unleashFeatures)[flag]
  const clientFlag = useFlag(flag)
  return serverFlag || clientFlag
}

export default useUnleashFlag

However on initial server render it throws which would then mean we'd need to change this implement to have conditional hooks.

It would be preferable if it would return undefined rather than throwing

Steps to reproduce the bug

No response

Expected behavior

No response

Logs, error output, etc.

No response

Screenshots

No response

Additional context

No response

Unleash version

No response

Subscription type

No response

Hosting type

No response

SDK information (language and version)

No response

No Unit tests?

Hey we would really like to use this, but there are no tests and it is quite new so we are quite hesitant to consume it in production. I am happy to contribute some tests, would like to know your preference on testing. Jest and React Testing Library?

Can we support turning on/off metrics?

We have built a proxy for unleash and we scrape metrics differently.
https://API_HOST/feature_flags/client/metrics will return a 404 for us.
Can we make it optional to fire metrics?

State update in Context can cause hydration error #421

Describe the bug

If a project uses react@18 with lazy/Suspense it can throw a hydration error and cause the website to fully rerender on the client (bad for CLS). This is because the state inside FlagProvider gets updated. If we wrap the setFlagsError/setFlagsReady with startTransition the error will be gone.

Error message:

This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.

https://legacy.reactjs.org/docs/error-decoder.html/?invariant=421

Side note: The error will only occur if the lazy loaded component is larger and slower during load. In our production project we only encountered the error when we throttled the network speed. Google SEO bots still picked the CLS up though.

Steps to reproduce the bug

  1. Go to https://y4r4q4-9000.csb.app/
  2. Open the devtools > console
  3. Look at hydration error in the console
  • I've created a reproduction repository on codesandbox.io: https://codesandbox.io/p/sandbox/great-dawn-y4r4q4?file=%2Fsrc%2Fcomponents%2FMain.jsx%3A7%2C1-7%2C66
  • A timeout was used with lazy to simulate a large component that needs longer to load
  • Inside the reproduction repository is a modified version of @unleash/proxy-client-react package with startTransition
  • You can run yarn remove @unleash/proxy-client-react && yarn add ./@unleash/proxy-client-react && yarn clean && yarn build && yarn serve to see the version with startTransition (error is gone in console 🧙)

Expected behavior

No hydration error is shown.

Logs, error output, etc.

No response

Screenshots

image

Additional context

No response

Unleash version

3.6.0

Subscription type

None

Hosting type

Self-hosted

SDK information (language and version)

No response

Mock provider for testing

Describe the feature request

I would like to request mock provider which can be used in unit tests for components relying on unleash-client.

Background

I'm testing components which are relying on useFlag hooks. I probably can hack it with mocking useFlag function but its a very hacky approach I feel.

Solution suggestions

As mentionedSomething like https://github.com/launchdarkly/jest-launchdarkly-mock would be ideal.
Alternatively, I would like to at least ask to export FlagContext from the library so that I can write my own mock provider which I did but not able to use FlagContext:

function MockFlagProvider(children: any) {
  const context = {
    client: {} as UnleashClient,
    flagsReady: true,
    setFlagsError: () => true,
    flagsError: [],
    isEnabled: () => true,
    setFlagsReady: () => true,
    on: () => ({} as UnleashClient),
    updateContext: () => {
      return Promise.resolve();
    },
    getVariant: (_toggleName: string) => ({ name: 'test', enabled: true }),
  };
  return (
    <FlagContext.Provider value={context}>{children}</FlagContext.Provider>
  );
}

Integration with NextJS

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_

Expose setContextField from client

Describe the feature request

In the unleash-proxy-client-js documentation it is possible to update only one context property as seen in the image:
image

Although it is possible using the useUnleashClient, it would be interesting to be able to do it in a simpler way without the need to use the useUnleashClient, having direct access to the setContextField.

Background

I make use of several custom strategies, so I define several properties within the context. There are specific cases where I need to update some properties of the context, but the updateContext overwrites everything, erasing the other properties.

It is possible to do with proxy-client-react through useUnleashClient as in the example:

import { useUnleashClient } from '@unleash/proxy-client-react'

const MyApp = ({ someIdFromMyCustomStrategy }) => {
  const unleashClient = useUnleashClient();
  unleashClient.setContextField('myCustomPropName', someIdFromMyCustomStrategy);

  return <MyComponent />;
}

Although the request triggered to the proxy has the parameter duplicated:
Withou using setContextField:
https://unleash-proxy.../proxy?environment=development&appName=myApp&myCustomProp=customValue

Using setContextField:
https://unleash-proxy.../proxy?environment=development&appName=myApp&myCustomProp=customValue&properties%5BmyCustomProp%5D=newCustomValue

Solution suggestions

Using the proxy-client-react directly, could be something like:

import { useUnleashContext } from '@unleash/proxy-client-react'

const MyApp = ({ someIdFromMyCustomStrategy }) => {
  const unleashContext = useUnleashContext();
  unleashContext.setContextField('myCustomPropName', someIdFromMyCustomStrategy);

  return <MyComponent />;
}

Or even like:

import { useUnleashContext } from '@unleash/proxy-client-react'

const MyApp = ({ someIdFromMyCustomStrategy }) => {
  const unleashContext = useUnleashContext();
  unleashContext.setContextFields({
    myCustomProp: someIdFromMyCustomStrategy,
    otherCustomProp: otherValue,
  });

  return <MyComponent />;
}

Duplicate Proxy Calls

Describe the bug

Using latest React SDK I see the Proxy be query two times constantly.

image

Steps to reproduce the bug

Just run React app with proxy and watch the F12 network traffic.

Expected behavior

Only 1 call every 15 seconds

Logs, error output, etc.

No response

Screenshots

No response

Additional context

const unleashInstance: IConfig = {
	url: process.env.REACT_APP_UNLEASH_SERVER!,
	clientKey: process.env.REACT_APP_UNLEASH_KEY!,
	refreshInterval: 15,
	appName: 'clm',
	environment: process.env.REACT_APP_UNLEASH_ENV!,
	disableMetrics: true
};

Unleash version

Latest

Subscription type

Open source

Hosting type

Self-hosted

SDK information (language and version)

"@unleash/proxy-client-react": "^3.3.0",

this.toggles.find is not a function

I am using this pkg in a react-native app.

I have configured the storageProvider exactly as mentioned in the README to use AsyncStorage

I randomly notice an error in development. I took a screenshot of the error here

It seems that sometimes, this.toggles is a string when an array is expected.

I verified this logging through node_modules/@unleash/proxy-client-react/index.js. A screenshot of that is here

Previously when this bug occurred in development, the developers would uninstall/reinstall.

I confirmed that clearing AsyncStorage helps to resolve this bug without a uninstall/reinstall.

The company I work for is releasing our app to the wild next week and the fear is that this bug sneaks into production causing users to crash on app open.

Bundled for Target `node`

Describe the bug

When i try to build my react app (using [email protected]) i get the following error:

Failed to compile.

Module not found: Error: Can't resolve 'crypto' in '/***/node_modules/@unleash/proxy-client-react/dist'

(Complete logs down below)

Steps to reproduce the bug

  1. Create a new project with CRA and react-scripts@5 (Using webpack v5 is important here)
  2. Install this package (v2)
  3. Try building the react project

Expected behavior

No error ;)

Logs, error output, etc.

Failed to compile.

Module not found: Error: Can't resolve 'crypto' in '/***/node_modules/@unleash/proxy-client-react/dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
        - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "crypto": false }

Screenshots

No response

Additional context

I think the specific problem is that this library is built with target node in webpack.config.js . While experimenting i solved the problem by switching to target web (still don't completly know if this is the correct one; https://webpack.js.org/configuration/target/).
As of webpack v5 there are no polyfills for the node specific implementations (as the error message states). Because your webpack config targets node the bundler takes the wrong files from the package uuid (a dependency of unleash-proxy-client-js). Resulting in code targeting the wrong environment/platform.

IMO it would be even better to not bundle the dependencies of this lib into the package. This way my webpack installation could load the appropriate version of the uuid package. No matter what your webpack config is targeting.
Apart from that you would not need to publish new versions of this package if the proxy-client receives patch or minor updates. NPM could easily install the proxy-client version specified by this projects version constraints.

Unleash version

No response

Subscription type

No response

Hosting type

No response

SDK information (language and version)

2.0.0

Sourcemap warnings from webpack 5 (via CRA 5)

I recently upgraded my app to create-react-app v5, which uses webpack v5 internally and the source-map-loader. The new source-map-loader is spewing warnings about the sourcemaps included in unleash-proxy-client.

More specifically, what it's unhappy about is that the sourcemaps reference the source files, but those source files are not included in the bundle.

Currently there is no way to hide these warnings and the React recommendation is to reach out to library maintainers. There is an open issue discussing this.

As I understand it, the two options here are:

  1. remove sourcemaps from the distributed bundle
  2. distribute the typescript source

I'll leave that decision up to y'all, or I'm happy to work up a PR if you'd like.

Thanks!


Warning output:

Screen Shot 2022-03-02 at 10 34 02 AM

Sample sourcemap content:

Screen Shot 2022-03-02 at 10 41 39 AM

Unleash: unable to fetch feature toggles TypeError: Cannot read properties of null (reading '_location')

Describe the bug

I have a CRA --typescript project, and when I run tests I encounter Unleash: unable to fetch feature toggles TypeError: Cannot read properties of null (reading '_location') error. This error appears after I update the msw package. I think It can be because of the difference between the jest versions of unleash and msw packages. For tests use jest and react-testing-library.

This is my package.json:

"dependencies": {
  "@unleash/proxy-client-react": "^3.6.0",
  "unleash-proxy-client": "^2.5.0",
},
"devDependencies": {
    "msw": "^1.2.1",
}

Steps to reproduce the bug

  1. Install the latest MSW
  2. Install the latest Unleash packages
  3. Run tests with the custom renderWithProviders method
  4. See error log in terminal

Expected behavior

I don't have an error when running my tests

Logs, error output, etc.

console.error
    Unleash: unable to fetch feature toggles TypeError: Cannot read properties of null (reading '_location')
        at Window.get location [as location] (/Users/mikeprus/Documents/Projects/care-physician-portal-web/node_modules/jsdom/lib/jsdom/browser/Window.js:375:79)
        at FetchInterceptor.<anonymous> (/Users/mikeprus/Documents/Projects/care-physician-portal-web/node_modules/@mswjs/interceptors/src/interceptors/fetch/index.ts:50:22)
        at step (/Users/mikeprus/Documents/Projects/care-physician-portal-web/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:59:23)
        at Object.next (/Users/mikeprus/Documents/Projects/care-physician-portal-web/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:40:53)
        at fulfilled (/Users/mikeprus/Documents/Projects/care-physician-portal-web/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:31:58)

      at UnleashClient.<anonymous> (node_modules/unleash-proxy-client/src/index.ts:400:25)
      at step (node_modules/unleash-proxy-client/build/index.js:59:23)
      at Object.throw (node_modules/unleash-proxy-client/build/index.js:40:53)
      at rejected (node_modules/unleash-proxy-client/build/index.js:32:65)

Screenshots

No response

Additional context

If you need more context please let me know.

Unleash version

2.5.0

Subscription type

Pro

Hosting type

Hosted by Unleash

SDK information (language and version)

@unleash/proxy-client-react: 3.6.0

impression callback is continuously called at refreshInterval if real time updates are made

Describe the bug

I am using @unleash/proxy-client-react in a react-native app. I have setup a impression listener in a root level react component so that I can track events in our data lake

useEffect(() => {
    console.warn('SPG_UNLEASH_CLIENT_EVENT');
    unleash.on('impression', (event: any) => {
      // track event in data lake
      if (__DEV__) {
        console.log('UNLEASH_IMPRESSION', event);
      }
    });
  }, []);

I have set refetchInterval to 15

When I start the app, impressions callbacks are called as expected for each flag I try to access.

If I update a flag (say if I turn off a flag), then at the 15 sec interval that particular flag will be updated and I will see another impression event. And at each 15 sec interval the impression callback will be called even if the value has not been updated

Steps to reproduce the bug

No response

Expected behavior

The impression callback should be called on initial app load. And then it should only be called once when the value is updated

Logs, error output, etc.

No response

Screenshots

Screenshot 2023-07-24 at 4 39 00 PM

Additional context

No response

Unleash version

Unleash 5.1.8 (Open Source)

Subscription type

Open source

Hosting type

Self-hosted

SDK information (language and version)

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

Vite: Minified React error in production build

Describe the bug

This library is hit by a very common issue in Vite ESModule - CommonJS Interop. The problem is best describe in this issue: vitejs/vite#2139

Steps to reproduce the bug

  1. Use Vite and use the react template.
  2. import FlagProvider from "@unleash/proxy-client-react";
  3. Build the app npm run build && npm run preview;

Expected behavior

No response

Logs, error output, etc.

No response

Screenshots

No response

Additional context

No response

Unleash version

No response

Subscription type

No response

Hosting type

No response

SDK information (language and version)

No response

option to have useVariant update on payload.value change

Describe the feature request

useVariant only updates on name or enabled changes.
It would be useful to update if the variant payload changes as well.
Or at least the option to opt into that behavior.

Background

No response

Solution suggestions

add

        variantRef.current.payload?.value !== newVariant?.payload?.value

to
https://github.com/Unleash/proxy-client-react/blob/main/src/useVariant.ts#L22

or add an options parameter to the hook that would conditionally do that.

setUnleashContext() doesn't update useFlags() return value

Describe the bug

When I run my React app and update Unleash context using setUnleashContext() (return value from useUnleashContext()) the flags returned by useFlags() aren't updated (not re-calculated in the new context, but preserving values from the old one). If I used useFlag() hook instead, the updates propagate immediately, and even useFlags() start to return proper values.

So it seems to me there is some synchronization problem between setUnleashContext() and useFlags().

Steps to reproduce the bug

  1. Create feature toggle TestToggle with User ID strategy. Enable it for 1 user with ID 'userEnabled'.
  2. Create and run a simple component to test setUnleashContext():
    function TestComponent() {
      const flags = useFlags().map(toggle => toggle.name);
      console.log('flags:', flags);
    
      const setUnleashContext = useUnleashContext();
    
      useEffect(() => {
          setUnleashContext({ userId: 'userEnabled' });
      }, []);
    
      useEffect(() => {
          const timeout = setTimeout(() => {
              setUnleashContext({ userId: 'userDisabled' });
              console.log('Unleash context modified');
          }, 5000);
          return () => clearTimeout(timeout);
      }, []);
    
      return null;
    }
    
  3. The output in the console is:
    flags: ['TestToggle']
    Unleash context modified
    flags: ['TestToggle']  // This line actually doesn't show until I force a re-render
    

Expected behavior

I'd expect the output in the console to be:

flags: ['TestToggle']
Unleash context modified
flags: []

Additional context

useFlag() works fine

If instead of grabbing all flags using useFlags():

const flags = useFlags.map(toggle => toggle.name);

I grab only this particular flag using useFlag():

const flag = useFlag('TestToggle');

the result is correct (false after updating the context) and even useFlags() calls are updated and stop to return TestToggle. So it seems usage of useFlag() for this particular flag triggers re-calculation in new context, while usage of useFlags() does not.

Using client directly

Today I tried to achieve the same by using client directly (useUnleashClient()). The results were exactly the same - when getting all flags the results weren't up to date with the context, but when getting a single flag they did. So it seems to me the problem is within the underlying client, not the React wrapper here.

Unleash version

Unleash 4.19.3

Subscription type

Open source

Hosting type

Self-hosted

SDK information (language and version)

@unleash/proxy-client-react 3.5.0, unleash-proxy-client 2.4.0

Problems with library built-in types (TS1005)

Describe the bug

After installing the library, when using the useUnleashContext function, I am getting an error related with internal types of this library .

Steps to reproduce the bug

  1. Run npm i --save unleash-proxy-client @unleash/proxy-client-react
  2. Import useUnleashContext in any file

Expected behavior

No response

Logs, error output, etc.

TypeScript error in /Users/pedromoraisf/www/work/admission/gupy-front-admission/admission-companies/node_modules/@unleash/proxy-client-react/dist/src/FlagContext.d.ts(2,13):
'=' expected. TS1005

     1 | import React from 'react';
   > 2 | import type { UnleashClient } from 'unleash-proxy-client';
       | ^
     3 | export interface IFlagContextValue extends Pick<UnleashClient, 'on' | 'updateContext' | 'isEnabled' | 'getVariant'> {
     4 | client: UnleashClient;
     5 | flagsReady: boolean;

Screenshots

No response

Additional context

  • I'm using skipLibCheck: true in tsconfig.json
  • node_modules has in exclude option, on tsconfig.json
  • Searching on the web, i have found this page, where one person thinks the problem has to do with some type declaration in the package.json of that lib (@unleash/proxy-client-react)

Unleash version

4.10.5

Subscription type

No response

Hosting type

No response

SDK information (language and version)

No response

Conditionally render react <Route> element with useFlag

I am trying to use useFlag to conditionally render a react <Route> element, and I have the route configured to go to a Not Found page when the route doesn't match any defined <Route>, so while the flag status check is pending, the Not Found component appears on the screen for an instant and then as soon as the flag is evaluated the correct <Route> element is rendered.

My AppRouter:

const AppRouter: FunctionComponent = () => {
  const isEnabled = useFlag('my_flag');

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/app/logging" element={<LoggingApp />} />
        { isEnabled && <Route path="/app/reporting" element={<ReportingApp profileName="xxx" />} /> }
        <Route
          path="*"
          element={
            <AppTheme>
              <ErrorPage errorCode={'404'} />
            </AppTheme>
          }
        />
      </Routes>
    </BrowserRouter>
  );
};

export default AppRouter;

Is there a way to know the flags are ready? The useFlag hook only exports the enabled status and the useUnleashContext only exports the updateContext function, so I cannot really know what is going on in the client.

Any ideas?

Getting following error when trying to add in React app

Property 'storage' is missing in type '{ url: string; clientKey: string; refreshInterval: number; appName: string; environment: string; }' but required in type 'IConfig'.ts(2741)
FlagProvider.d.ts(9, 5): 'storage' is declared here.
FlagProvider.d.ts(3, 5): The expected type comes from property 'config' which is declared here on type 'IntrinsicAttributes & IFlagProvider & { children?: ReactNode; }'

import FlagProvider from '@unleash/proxy-client-react';

const config = {
url: 'https://HOSTNAME/api/proxy',
clientKey: 'PROXYKEY',
refreshInterval: 15,
appName: 'your-app-name',
environment: 'dev',
};

ReactDOM.render(
<React.StrictMode>



</React.StrictMode>,
document.getElementById('root')
);

Potential bug - React state update on a component that hasn't mounted yet

Describe the bug

Hello there,

I am using proxy-client-react in a project along with Next.js and while navigating through the pages I am getting an error React state update on a component that hasn't mounted yet, as per below screenshot:
Screenshot 2022-12-21 at 13 30 46

I had a look into my code to see if I am not doing clean up properly in the useEffects that I have but I think that's not the case.

I think I should try to use your latest version anyways.

Is this something that I should expect while using unleash with next.js?
There is no full integration with Next.js at the moment?

Thanks!

Steps to reproduce the bug

No response

Expected behavior

No response

Logs, error output, etc.

No response

Screenshots

Screenshot 2022-12-21 at 13 30 46

Additional context

No response

Unleash version

^1.0.4

Subscription type

Enterprise

Hosting type

Hosted by Unleash

SDK information (language and version)

No response

Leak in useFlag

Describe the bug

the useEffect call in useFlag registers listeners on the client but has no teardown defined. This means that over time, as components which check flag statuses are added and removed, the number of listeners will increase, gradually increasing memory use and reducing app performance (and causing react to complain about "setState called on unmounted component" whenever the flag changes after a component has unmounted).

useEffect(() => {
if (!client) return;
client.on('update', () => {
const enabled = isEnabled(name);
if (enabled !== flagRef.current) {
flagRef.current = enabled;
setFlag(!!enabled);
}
});
client.on('ready', () => {
const enabled = isEnabled(name);
setFlag(enabled);
});
}, [client]);

Steps to reproduce the bug

const Thing = () => {
  const flag = useFlag('foo');
  return null;
};

const App = () => {
  // some rough example code which will display the component for 1 second, then remove it
  const [show, setShow] = useState(true);
  useEffect(() => { setTimeout(() => setShow(false), 1000); }, []);

  return <FlagProvider config={{/*blah*/}}>{show && <Thing />}</FlagProvider>;
};

If the foo flag changes after the component disappears, a warning about calling setState on an unmounted component will appear in the console (once the client refreshes).

Expected behavior

registered listeners should be removed in useEffect's teardown

Logs, error output, etc.

No response

Screenshots

No response

Additional context

No response

Unleash version

No response

Subscription type

No response

Hosting type

No response

SDK information (language and version)

proxy-client-react

useUnleashedContext does not expose key context members

Hi 👋

As far as I can tell, this package does not currently support a way to extract the current value of all flags. This is useful for providing context for A/B testing and analytics. There also seems to be no way to access the underlying unleashed js SDK client which exposes the getAllToggles method which would suffice for the described use-case. Lmk if I'm wrong and there is already a way to access this info.

useUnleashedContext is a bit of a misnomer right now as it only returns the update function. Not sure if this was a conscious decision to avoid exposing the internal client and other context components but even having isEnabled for access to the flag context outside of hooks would be useful.

Interested to get thoughts on this and I can submit a PR if changes are justified.

Feature Request: Expose the client for direct use

I like what you've done, making feature flags accessible via hooks, however since it's tied to React Context, it's only available to components. I use redux in my app, so some of my code needs to know about feature flags other than components and hooks. I'd like to be able to use the hooks for components and access the client directly.

I think in order to not have two instances of the proxy client running in parallel (outside of some intelligence within the client to dedupe itself), the implementation of this would be to provide a pre-built client instance to the FlagProvider (optional for backwards compatibility). Also, the library will want to re-export the js client for import convenience.

If you agree with this direction, I don't mind working on a pull request. That said, I have a few things that might keep me from getting to this quickly.

Usage with next.js

Hello, apologies if this is the wrong place to post this.

We're in the process of integrating unleash with our next.js applications. We've set up proxies externally and gotten up and running. We've solved some issues with specifically fetch and localStorage not being available during SSR by extending the unleash provider with our own, like this:

// Provider.tsx

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>
  );
};
// DummyProvider.ts

export class DummyStorageProvider {
  async save() {
    return;
  }

  async get() {
    return "";
  }
}

However, this feels very hacky and I'm wondering if the unleash team has any advice to give for integrating with next.js?

Unleash: unable to fetch feature toggles TypeError: q.randomFillSync is not a function

Describe the bug

React 18.2.0
unleash/proxy-client-react: 3.3.0

I have a very simple App using Create React App and I have following your instructions exactly from here: https://docs.getunleash.io/sdks/proxy-react

AS soon I hit my page I can see the error in the console and my page does not render.

const AccountsPage = () => {
	const { flagsReady } = useFlagsStatus();
	const enabled = useFlag('account-management');
	const msgFeatureFlag = useRef<Messages>(null);

	useEffect(() => {
		if (enabled) {
			msgFeatureFlag.current?.replace({ severity: 'success', detail: 'Account Management feature flag is enabled!', sticky: true });
		} else {
			msgFeatureFlag.current?.replace({ severity: 'warn', detail: 'Account Management feature flag is disabled!', sticky: true });
		}
	}, [flagsReady, enabled]);

	return (
		<Messages ref={msgFeatureFlag} />
	);
};

Steps to reproduce the bug

Simply run a Create React App app and try and use any feature flag I can see it hit the Unleash server and gather metrics from the proxy but the client is throwing this error q.randomFillSync is not a function

image

Expected behavior

The feature flag would work.

Logs, error output, etc.

main.min.js:1 Unleash: unable to fetch feature toggles TypeError: q.randomFillSync is not a function
    at g (main.min.js:1:1)
    at j (main.min.js:1:1)
    at a.generateEventId (main.min.js:1:1)
    at a.createBaseEvent (main.min.js:1:1)
    at a.createImpressionEvent (main.min.js:1:1)
    at f.isEnabled (main.min.js:1:1)
    at p (index.browser.js:1:1)
    at index.browser.js:1:1
    at f.emit (main.min.js:1:1)
    at f.<anonymous> (main.min.js:1:1)

Screenshots

image

Unleash version

"@unleash/proxy-client-react": "^3.3.0"
"unleash-proxy-client": "^2.2.0"

Subscription type

Open source

Hosting type

Self-hosted

getAllToggles not exposed

It looks like the proxy-client-react does not implement getAllToggles method available in the unleash-proxy-client. Is this intentional or are there any plans to have that in the future?

Create a useFlags hook that enumerates all flags

Describe the feature request

Describe the feature request

We would like to report in the UI a dynamic list of all flags used
Currently we'd need to do something along the lines of

Background

const testEnabled= useFlag('rmm-test')
const test2Enabled= useFlag('rmm-test2)

const test3Enabled= useFlag('rmm-test3)

And im not sure its possibly to iterate through an array and dynamically make hooks.

Solution suggestions

whereas ideally it'd be good to return an array or record of key value pairs

const allFlags = useFlags() // {rmm-test1:true,...}

It appears

 const client = useUnleashClient()
  const a = client.getAllToggles()

does something similar so perhaps the hook can just call getAllToggles

Background

No response

Solution suggestions

No response

useFlagsStatus hook breaks the page.

I would like to use this hook for delaying component render untill flags are fetched. But it breaks the page complaining that object destruction const { flagsReady, flagsError } = useContext(FlagContext); while FlagContext is set to null initially.

flagsReady boolean not set

I'm running an SPA using a local instance of the unleashed proxy as detailed in the documentation, connecting to the unleashed cloud test instance.
https://app.unleash-hosted.com/demo/api/

The first time I enter my application, i.e. with a clear cache, the flags load and the flagsReady flag correctly is set to true.

However, if I refresh my SPA, the flagsReady flag is not set to true.
Clearing the local cache and refreshing, fixes the issue.

I can see the successful network request
image

But the state in the hook indicates the flags are not loaded.

image

Props of FlagProvider is not exported

Describe the bug

We want to have our own "FlagProvider" and we want to extend the original props, in case you guys add some properties to it, the interface will be up to date. The problem "IFlagProvider" is not exported.

Steps to reproduce the bug

No response

Expected behavior

No response

Logs, error output, etc.

No response

Screenshots

No response

Additional context

No response

Unleash version

3.4.0

Subscription type

Enterprise

Hosting type

Hosted by Unleash

SDK information (language and version)

[email protected]

Support for React 18

Describe the feature request

We want to use Unleash in a project which uses React 18 and are seeing the following messages in the console. Is there any plans to upgrade to latest React version?

react-dom.development.js:86 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
[...]
react-dom.development.js:86 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

Thanks.

Background

No response

Solution suggestions

No response

Optionally only start unleash client if created via config

Currently the FlagProvider always starts the client when it is mounted. I propose that it should only start the client if the client was created in FlagProvider via config passed through props. The creator of the client would be responsible for starting and stopping the client independent of the FlagProvider mounting.

One use case is delaying starting the client until custom properties of the unleash context are set. In order to get the initial query for flags to use these custom properties we would need to delay mounting the FlagProvider otherwise properties set after mounting will have to wait for the next interval to kick in. A cleaner solution might be to allow the creator of the client to handle starting and stopping.

In order to maintain backwards compatibility, this behaviour can be added behind a boolean prop on FlagProvider like startClient.

I've created a PR with a possible solution. Interested to hear any feedback.

React : Getting require is not defined error when importing @unleash/proxy-client-react

Describe the bug

Installed @unleash/proxy-client-react and tried to import it in our project.

Used below line and did npm start.

import { FlagProvider } from '@unleash/proxy-client-react';

In browser, noticed below logs in dev console.

Uncaught ReferenceError: require is not defined
at eval (eval at (app.bundle.js:16177:2), :1:744)
at eval (eval at (app.bundle.js:16177:2), :1:5008)
at Object. (app.bundle.js:16177:2)
at webpack_require (vendor.75009cd30bee87d51b12.js:551:30)
at fn (vendor.75009cd30bee87d51b12.js:99:20)
at eval (eval at (app.bundle.js:5896:2), :49:25)
at Object. (app.bundle.js:5896:2)
at webpack_require (vendor.75009cd30bee87d51b12.js:551:30)
at fn (vendor.75009cd30bee87d51b12.js:99:20)
at Object. (app.bundle.js:6:19)

Steps to reproduce the bug

No response

Expected behavior

No response

Logs, error output, etc.

Uncaught ReferenceError: require is not defined
    at eval (eval at <anonymous> (app.bundle.js:16177:2), <anonymous>:1:744)
    at eval (eval at <anonymous> (app.bundle.js:16177:2), <anonymous>:1:5008)
    at Object.<anonymous> (app.bundle.js:16177:2)
    at __webpack_require__ (vendor.75009cd30bee87d51b12.js:551:30)
    at fn (vendor.75009cd30bee87d51b12.js:99:20)
    at eval (eval at <anonymous> (app.bundle.js:5896:2), <anonymous>:49:25)
    at Object.<anonymous> (app.bundle.js:5896:2)
    at __webpack_require__ (vendor.75009cd30bee87d51b12.js:551:30)
    at fn (vendor.75009cd30bee87d51b12.js:99:20)
    at Object.<anonymous> (app.bundle.js:6:19)

Screenshots

No response

Additional context

No response

Unleash version

Gitlab Unleash

Subscription type

Open source

Hosting type

None

SDK information (language and version)

react

handle HMR gracefully

when using this library, when HMR reloads, I see double requests on the network tab. and when it reloads another time, I see triple requests.

This should not be happening.

regarding the documentation for using the custom activation strategy

I am struggling to update the context in case of using a custom activation strategy. I went through the documentation and did not find any examples there. There exists one example for Node though. It was mentioned that clients provide the abstraction for using the custom activation strategies, but I could not figure out how. If there are any pointers for the same would be greatly helpful. For now, I am using existing strategies with different values to match my need.

Unleash created infinite loop when proxy server is down

Describe the bug

Unleash FlagProvider accepts: startClient, config.

We are passing "startClient={false}" until we have the proxy server setted up.
The problem is that even when passing "startClient" false Unleash still tries to access the server and infinity (caused infinite loop in our app & to crush)

Steps to reproduce the bug

Wrap your app with the following:

    <FlagProvider
      startClient={false}
      config={{
        url: 'http://localhost:3000',
        clientKey: 'secret-key',
        appName: 'App',
        refreshInterval: 1000 * 60 * 15,
      }}
    >
      <App />
    </FlagProvider>

Reproduction

Expected behavior

Allow passing "maxRetries" in the config. Or at least add in your code "retryInterval" option

Logs, error output, etc.

No response

Screenshots

Screen Shot 2022-11-16 at 10 04 48

Additional context

No response

Unleash version

No response

Subscription type

Enterprise

Hosting type

Hosted by Unleash

SDK information (language and version)

(Typescript) "@unleash/proxy-client-react": "^3.4.0", "unleash-proxy-client": "^2.3.0",

ChainAlert: npm package release (3.0.0) has no matching tag in this repo

Dear @unleash/proxy-client-react maintainers,
Thank you for your contribution to the open-source community.

This issue was automatically created to inform you a new version (3.0.0) of @unleash/proxy-client-react was published without a matching tag in this repo.

As part of our efforts to fight software supply chain attacks, we would like to verify this release is known and intended, and not a result of an unauthorized activity.

If you find this behavior legitimate, kindly close and ignore this issue. Read more

badge

`unleash-proxy-client` version constraint too tight

Describe the feature request

Currently, we cannot update unleash-proxy-client to v2.0.2 because the peerDependency in this package only allows v2.0.1 and nothing else:

"peerDependencies": {
    "unleash-proxy-client": "2.0.1"
  }

Would it be possible to support a version constraint for the whole major of v2 like:

"peerDependencies": {
    "unleash-proxy-client": "^2.0.1"
  }

Background

We try to keep up with most of the new versions released by third-party dependencies we are using. But currently, our automated upgrade process (we are using renovate by the way ;) ) is not able to upgrade because of this output:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: @unleash/[email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/unleash-proxy-client
npm ERR!   unleash-proxy-client@"2.0.2" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer unleash-proxy-client@"2.0.1" from @unleash/[email protected]
npm ERR! node_modules/@unleash/proxy-client-react
npm ERR!   @unleash/proxy-client-react@"3.1.0" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/unleash-proxy-client
npm ERR!   peer unleash-proxy-client@"2.0.1" from @unleash/[email protected]
npm ERR!   node_modules/@unleash/proxy-client-react
npm ERR!     @unleash/proxy-client-react@"3.1.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 

Solution suggestions

As described previously it would be helpful if we could get a widen version constraint for unleash-proxy-client. Otherwise, you would have to release a new version with every release of unleash-proxy-client.

Integration with NextJS

Describe the bug

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

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

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

Unleash version

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

Subscription type

Pro

Hosting type

Hosted by Unleash

SDK information (language and version)

No response

Yarn berry: pnp incompatibility

Describe the bug

We are getting the following error when trying to migrate to yarn pnp (which no longer supports implicit dependencies like flat node_modules does):

ERROR in ../../../.yarn/cache/@unleash-proxy-client-react-npm-1.0.4-06a181db73-957ee588a0.zip/node_modules/@unleash/proxy-client-react/dist/index.js 1:20854-20870
Module not found: Error: Can’t resolve ‘react’ in ‘User/dev/project/.yarn/cache/@unleash-proxy-client-react-npm-1.0.4-06a181db73-957ee588a0.zip/node_modules/@unleash/proxy-client-react/dist’

Steps to reproduce the bug

  1. start a yarn pnp project
  2. add this package

Expected behavior

I think this issue is just because react & react-dom are listed asdevDependencies instead of a peerDependencies

Logs, error output, etc.

No response

Screenshots

No response

Additional context

No response

Unleash version

No response

Subscription type

No response

Hosting type

No response

SDK information (language and version)

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.