> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare

<View title="Developer" />

<View title="Federal docs">
  <Danger>
    **This integration is not available in federal environments**

    To learn more, read <a href="/docs/home/infrastructure/federal">LaunchDarkly in federal environments</a>.
  </Danger>
</View>

<View title="EU docs">
  <Danger>
    **This integration is not available in LaunchDarkly's European Union (EU) instance**

    To learn more, read <a href="/docs/home/infrastructure/eu">LaunchDarkly in the European Union (EU)</a>.
  </Danger>
</View>

<Note>
  **The Cloudflare integration is available to customers on select plans**

  The Cloudflare integration is only available to customers on select plans. To learn more, [read about our pricing](https://launchdarkly.com/pricing/). To upgrade your plan, [contact Sales](https://launchdarkly.com/contact-sales/).
</Note>

This topic explains how to use LaunchDarkly's Cloudflare integration. This integration enables flag evaluation within Cloudflare Workers by writing the latest flag data from the configured environment directly to your Workers KV. To learn more about Cloudflare Workers KV, read [How KV Works](https://developers.cloudflare.com/workers/learning/how-kv-works).

<Note>
  **This integration requires LaunchDarkly's Cloudflare SDK**

  You must install and configure the Cloudflare SDK in your Cloudflare Worker to use this integration. To learn more, read [Cloudflare SDK](/docs/sdk/edge/cloudflare).
</Note>

You can use the Cloudflare integration to bootstrap your application with the latest client-side feature flags. This eliminates the initial remote call to LaunchDarkly, providing zero-latency client-side feature flags with no flash of original content or shift in content layout. The Cloudflare integration also enables flag evaluations within a Worker.

## Create a Cloudflare Worker with the LaunchDarkly Cloudflare SDK

<Note>
  **Cloudflare Workers KV size limits**

  Cloudflare Workers enforce KV size limits that might be smaller than your LaunchDarkly flag data in a given environment.

  To learn more, read about [KV limits](https://developers.cloudflare.com/workers/platform/limits#kv-limits).
</Note>

To create a new Cloudflare Worker project with the LaunchDarkly Cloudflare SDK using the LaunchDarkly Cloudflare Worker template:

1. Install [Wrangler](https://developers.cloudflare.com/workers/get-started/guide#2-install-the-workers-cli), the Workers CLI.

2. Authenticate Wrangler:

   <CodeGroup>
     ```bash title="Console" lines wrap theme={null}
     wrangler login
     ```
   </CodeGroup>

To learn more about the `wrangler login` command, read [`login`](https://developers.cloudflare.com/workers/cli-wrangler/commands#login).

3. Create a new project using the LaunchDarkly Cloudflare Worker template. Replace `my-project` with the name of the project you wish to create:

   <CodeGroup>
     ```bash title="Console" lines wrap theme={null}
     wrangler generate my-project https://github.com/launchdarkly/launchdarkly-cloudflare-worker-template
     ```
   </CodeGroup>

To learn more about the `wrangler generate` command, read [`generate`](https://developers.cloudflare.com/workers/cli-wrangler/commands#generate).

4. Add your Cloudflare account ID to your `wrangler.toml` file:

   <CodeGroup>
     ```toml title="wrangler.toml" lines wrap theme={null}
     account_id = "<YOUR_CLOUDFLARE_ACCOUNT_ID>"
     ```
   </CodeGroup>

If you do not know your Cloudflare account ID, use the command `wrangler whoami`.

5. Create a new Cloudflare Workers KV namespace:

   <CodeGroup>
     ```bash title="Console" lines wrap theme={null}
     wrangler kv:namespace create "LD_KV"
     ```
   </CodeGroup>

Wrangler responds with the namespace ID of the newly created namespace.

6. Add the `nodejs_compat` flag to `wrangler.toml`. This is required because the Cloudflare SDK uses `node:events`, which needs to be enabled:

   <CodeGroup>
     ```toml title="wrangler.toml" lines wrap theme={null}
     compatibility_flags = [ "nodejs_compat" ]
     ```
   </CodeGroup>

   To learn more, read [Node.js compatibility](https://developers.cloudflare.com/workers/runtime-apis/nodejs/#enable-nodejs-with-workers).

7. Bind your Worker with the new KV namespace by adding the code Wrangler returned in step 5 to the `kv_namespaces` array in your Worker's `wrangler.toml` file:

   <CodeGroup>
     ```toml title="wrangler.toml" lines wrap theme={null}
     kv_namespaces = [
       { binding = "LD_KV", id="<LD_KV NAMESPACE ID>" }
     ]
     ```
   </CodeGroup>

8. (Optional) If you intend to use `wrangler dev` for local development, you can also create a preview namespace:

   <CodeGroup>
     ```bash title="Console" lines wrap theme={null}
     wrangler kv:namespace create "LD_KV" --preview
     ```
   </CodeGroup>

Wrangler responds with the updated IDs for your `kv_namespaces` array. Replace the existing array entry created above with the value returned by Wrangler.

<CodeGroup>
  ```toml title="wrangler.toml" lines wrap theme={null}
  kv_namespaces = [
     {binding = "LD_KV", id="<LD_KV NAMESPACE ID>", preview_id = "<LD_KV NAMESPACE PREVIEW ID>"}
  ]
  ```
</CodeGroup>

Each LaunchDarkly Cloudflare integration only populates one KV namespace. If you are using a preview KV namespace, it will require its own integration. To learn more, read [Configure the LaunchDarkly Cloudflare integration](#configure-the-launchdarkly-cloudflare-integration).

9. (Optional) If you set up a preview namespace, you may run your worker locally:

   <CodeGroup>
     ```bash title="Console" lines wrap theme={null}
     wrangler dev
     ```
   </CodeGroup>

To learn more about the `wrangler dev` command, read [`dev`](https://developers.cloudflare.com/workers/cli-wrangler/commands#dev).

10. Publish your Worker to Cloudflare:

    <CodeGroup>
      ```bash title="Console" lines wrap theme={null}
      wrangler publish
      ```
    </CodeGroup>

To learn more about the `wrangler publish` command, read [`publish`](https://developers.cloudflare.com/workers/cli-wrangler/commands#publish).

Your worker is running, but flag data will not be synced to your namespace until you set up the LaunchDarkly Cloudflare integration. To learn how, read [Configure the LaunchDarkly Cloudflare integration](#configure-the-launchdarkly-cloudflare-integration).

## Configure the LaunchDarkly Cloudflare integration

For a Cloudflare integration to work, it needs a Cloudflare API token. To create a Cloudflare API token read [Creating API tokens](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/). Your token needs to have **Account - Workers KV Storage:Edit** permissions.

You can create and manage Cloudflare integrations on the **Integrations** page. To create a new Cloudflare integration for your environment:

1. In LaunchDarkly, click the **gear** icon in the left sidebar to view Organization settings.
2. Click **Integrations** and find "Cloudflare."
3. Click **Add integration**. A "Create Cloudflare configuration" panel appears.
4. (Optional) Enter a name for the integration.
5. Choose an environment from the **Environment** menu.
6. Enter your Cloudflare **Account ID**. You can find this on the Worker home in Cloudflare, in the right sidebar.
7. Enter your **KV Namespace** ID.
8. Enter your API token generated from Cloudflare.
9. Click **Save configuration**.

You can evaluate flags using the flag data that is set up to write to your Worker KV using the [Cloudflare SDK](/docs/sdk/edge/cloudflare).

## Use the Cloudflare integration to bootstrap feature flags

You can use the LaunchDarkly Cloudflare integration with Workers Sites to serve HTML injected with feature flags for bootstrapping client-side SDKs. To learn more about Workers Sites, read [Cloudflare's documentation](https://developers.cloudflare.com/workers/platform/sites).

To serve HTML injected with feature flags:

<CodeGroup>
  ```js title="index.js" maxLines=0 expandable lines wrap theme={null}
  const { getAssetFromKV } = require('@cloudflare/kv-asset-handler')
  const { init } = require('@launchdarkly/cloudflare-server-sdk')

  let ldClient

  const initLdClient = () => {
    if (!ldClient) {
      // LD_CLIENT_SIDE_ID and LD_KV are runtime variables that the Workers runtime provides to your code.
      // For more information read https://developers.cloudflare.com/workers/platform/environment-variables
      ldClient = init(LD_CLIENT_SIDE_ID, LD_KV)
      return ldClient.waitForInitialization()
    }

    return Promise.resolve()
  }

  class FlagsStateInjector {
    async element(element) {
      // fetch all flag values for client-side SDKs as evaluated for an anonymous context
      // use a more appropriate context key if needed
      const context = { kind: 'user', key: 'example-context-key', anonymous: true }
      const allFlags = await ldClient.allFlagsState(context)
      element.append(`<script>window.ldFlags = ${JSON.stringify(allFlags)}</script>`, { html: true })
    }
  }

  addEventListener('fetch', event => {
    event.respondWith(handleRequest(event))
  })

  async function handleRequest(event) {
    const [response] = await Promise.all([getAssetFromKV(event), initLdClient()])
    const acceptHeader = event.request.headers.get('accept')

    if (acceptHeader && acceptHeader.includes('text/html')) {
      return new HTMLRewriter().on('head', new FlagsStateInjector()).transform(response)
    }

    return response
  }
  ```
</CodeGroup>

This uses `HTMLRewriter` to inject a script tag into the head of your document that saves your set of feature flags to `window.ldFlags`. To learn more about `HTMLRewriter`, read [Cloudflare's documentation](https://developers.cloudflare.com/workers/runtime-apis/html-rewriter).

These flag values can then be used to bootstrap your client-side SDK. For example, if you are using the React Web SDK:

<CodeGroup>
  ```js title="App.js" lines wrap theme={null}
  import React from 'react';
  import { useFlags, withLDProvider } from 'launchdarkly-react-client-sdk';

  const App = () => {
    ...
  };

  export default withLDProvider({
    clientSideID: 'example-client-side-id',
    options: {
      bootstrap: window.ldFlags
    }
  })(App);
  ```
</CodeGroup>

To learn more about bootstrapping client-side feature flags from the server, read [Bootstrap using server-rendered content](/docs/guides/flags/static-sites#bootstrap-using-server-rendered-content).

## Troubleshooting

If you encounter a `4xx` error when trying to access the Cloudflare integration, it usually means the request was invalid or access is restricted. To learn how to resolve these errors, read the LaunchDarkly Knowledge Base article [Troubleshooting Cloudflare Integration 4XX error codes](https://support.launchdarkly.com/hc/en-us/articles/29712089258011-Troubleshooting-Cloudflare-Integration-4XX-error-codes).
