# Cloudflare

By implementing a reverse proxy using Cloudflare Workers, you're serving Didomi's SDK and API assets through your own domain.

* Enhance performance by leveraging Cloudflare's edge caching.
* Maintain brand consistency and reduce reliance on third-party domains.
* Potentially improve compliance with privacy regulations by controlling SDK delivery.

This setup involves configuring a Cloudflare Worker to proxy requests to Didomi's CDN, ensuring proper handling of headers and caching as per Didomi's [guidelines](https://developers.didomi.io/cmp/web-sdk/custom-domain/self-hosting).

This guide explains how to configure Cloudflare Workers to create a reverse proxy that serves the Didomi Consent notice from your own domain. Two implementation options are available based on requirements:

[Choose your implementation](#choose-your-implementation)

[Implementation guide](#implementation-guide)

## Choose your implementation

### Option A: Use a subdomain

To implement a reverse proxy on a subdomain, you will first create a Cloudflare Worker with simple routing logic, then configure route triggers to activate the Worker for your domain. The Worker directly proxies `/api/*` and `/*` requests to Didomi's servers without URL transformation.

<figure><img src="/files/c8AEojik2BUJqRgtyfpY" alt=""><figcaption></figcaption></figure>

* **Customer Usage**: `/api/*` and `/*` paths directly
* **Architecture**: Cloudflare Worker with direct routing
* **Implementation**: Simple path routing with minimal URL transformation

### Option B: Use the main domain

To implement a reverse proxy on the main domain, you will first create a Cloudflare Worker that handles URL transformation (with (`/consent`), then configure a route trigger for `/consent/*` paths. The Worker removes the `/consent/` prefix before proxying requests to Didomi's servers.

<figure><img src="/files/gL5z0kMlm6IDCJgYJyh4" alt=""><figcaption></figcaption></figure>

* **Customer Usage**: `/consent/*` prefix for all CMP requests
* **Architecture**: Cloudflare Worker with URL transformation
* **Implementation**: URL rewriting and advanced processing

### Domain vs Subdomain Trade-offs

When implementing a reverse proxy for the Didomi SDK and its API events, you need to choose between using your main domain or a dedicated subdomain. This choice has important implications for Safari's cookie restrictions.

For more information, see this [trade-off matrix](/api-and-platform/domains/reverse-proxy.md#domain-vs-subdomain-implementation) to select the implementation that suits your requirements.

## Implementation guide

[Option A: Use a subdomain](#option-a-use-a-subdomain-1)

[Option B: Use the main domain](#option-b-use-the-main-domain-1)

### Option A: Use a subdomain

#### Step 1: Create Cloudflare Worker

* In the left-hand sidebar, click on **Workers & Pages**.
* Click on **Create** and then **Hello world** (to start from scratch)
* In the **Name** field, enter `didomi-direct-proxy` (or any name you want)
* Click on **Deploy** and then **Edit code**
* Enter the following [code](https://github.com/didomi/boilerplate-cloudflare-reverse-proxy-didomi-cmp/blob/main/index.js) (`index.js`) and click on **Deploy**

The `index.js` file enables the Cloudflare Worker to:

* Proxy SDK requests from `/*` to `https://sdk.privacy-center.org/`.
* Proxy API requests from `/api/*` to `https://api.privacy-center.org/`.
* Remove cookies and sets the `X-Forwarded-For` header with the client's IP.
* Return a 404 response for other paths.

#### Step 2: Create Route Triggers

{% hint style="warning" %}
*Direct path routing* option, which occupies the main path, works only with a subdomain dedicated to the Didomi CMP.
{% endhint %}

* Navigate to your domain and click on **Workers Routes**
* Click on **Add route**
* Add two routes:

  **Route 1: SDK Route**

  ```
  YOUR_SUB_DOMAIN_NAME/*
  ```

  **Route 2: API Route**

  ```
  YOUR_SUB_DOMAIN_NAME/api/*
  ```
* Select the worker `didomi-direct-proxy` for both routes and **Save**

### Option B: Use the main domain

#### Step 1: Create a Cloudflare Worker

*A Worker is a serverless function that executes custom code at Cloudflare's edge, allowing you to intercept and modify HTTP requests and responses for tasks like proxying, caching, or rewriting content.*

* In the left-hand sidebar, click on **Workers & Pages**.\
  ![](/files/wUhsC5xvHaqnWT0OwCi9)
* Click on **Create** and then **Hello world** (to start from scratch)\
  ![](/files/Zy4v9npABFBgEXwcjkrN)
* In the **Name** field, enter `didomi-consent-loader`
* Click on **Deploy** and then **Edit code**\
  ![](/files/xjqbn4VZFy8fyuHuw05h)
* Enter the following code and click on **Deploy**\
  ![](/files/055ISYo8rDy4sqz3bGCm)

This [script](https://github.com/didomi/boilerplate-cloudflare-reverse-proxy-didomi-cmp/blob/main/index.js):

* Proxies SDK requests from `/consent/` to `https://sdk.privacy-center.org/`.
* Proxies API requests from `/consent/api` to `https://api.privacy-center.org/`.
* Removes cookies and sets the `X-Forwarded-For` header with the client's IP.
* Returns a 404 response for other paths.

```jsx
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const path = url.pathname;
    const clientIP = request.headers.get("CF-Connecting-IP") || "";

    // Define base URLs
    const sdkBase = "<https://sdk.privacy-center.org>";
    const apiBase = "<https://api.privacy-center.org>";

    // Determine if the request is for the SDK or API
    const isSDKRequest = path.startsWith("/consent/") && !path.startsWith("/consent/api");
    const isAPIRequest = path.startsWith("/consent/api");

    if (isSDKRequest) {
      // Construct the target URL for the SDK
      const targetPath = path.replace("/consent", "");
      const targetURL = new URL(sdkBase + targetPath);
      targetURL.search = url.search;

      // Prepare headers
      const headers = new Headers(request.headers);
      headers.delete("Cookie");
      headers.set("X-Forwarded-For", clientIP);

      // Fetch from Didomi's CDN
      const response = await fetch(targetURL.toString(), {
        method: request.method,
        headers: headers
      });

      // Clone and return the response
      return new Response(response.body, {
        status: response.status,
        statusText: response.statusText,
        headers: response.headers
      });
    }

    if (isAPIRequest) {
      // Construct the target URL for the API
      const targetPath = path.replace("/consent/api", "");
      const targetURL = new URL(apiBase + targetPath);
      targetURL.search = url.search;

      // Prepare headers
      const headers = new Headers(request.headers);
      headers.delete("Cookie");
      headers.set("X-Forwarded-For", clientIP);

      // Fetch from Didomi's API
      const response = await fetch(targetURL.toString(), {
        method: request.method,
        headers: headers,
        body: request.body
      });

      // Clone and return the response
      return new Response(response.body, {
        status: response.status,
        statusText: response.statusText,
        headers: response.headers
      });
    }

    // Return 404 for other requests
    return new Response("Not found", { status: 404 });
  }
};

```

#### 2. Create a Route trigger

*A Trigger, specifically a Route in this context, defines the URL pattern that determines when your Worker should run; it connects your Worker to specific paths on your domain, ensuring it activates only for matching requests.*

* Navigate to your domain and click on **Workers Routes**\
  ![](/files/VwCvs2UGyl4gcgOW6LhX)
* Click on Add route\
  ![](/files/csXlwmkDbegpPQTjlBN5)
* Enter the route (or *URL pattern that determines when your Worker should run)*

  ```jsx
  YOUR_DOMAIN_NAME/consent/*
  ```

  ![](/files/VYKF9eHukAIea8h3pMeB)
* Select the worker `didomi-consent-loader` and **Save**

***

### Troubleshooting

#### Common Issues

**404 Not Found**

* Verify Worker routes are configured correctly
* Check if request path matches expected patterns
* Ensure Worker is deployed and active

**Worker Errors**

* Check Cloudflare dashboard for Worker logs
* Verify Worker code syntax is correct
* Ensure proper error handling in Worker

**CMP Not Loading**

* Verify `didomiConfig` paths match your routing option
* Check that API\_KEY and NOTICE\_ID are correct
* Ensure HTTPS is used for all requests

**CORS Issues**

* Cloudflare Workers handle CORS automatically
* Verify response headers are forwarded correctly
* Check if additional CORS headers are needed

#### Debug Steps

1. **Check Worker Logs** in Cloudflare dashboard
2. **Test direct URLs** to verify routing works
3. **Verify DNS** points to Cloudflare
4. **Check browser console** for JavaScript errors
5. **Test with curl** to isolate issues

***

{% hint style="success" %}
After setting up your reverse proxy, update your Didomi SDK snippet to use your own domain instead of `privacy-center.org`. This ensures that the Didomi assets are served from your configured domain.

For more information, see the guide to [serving Didomi assets from your domain](/cmp/web-sdk/serve-didomi-assets-from-your-domain.md#configure-the-sdk).
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.didomi.io/api-and-platform/domains/reverse-proxy/implementation-guides/cloudflare.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
