Beginner Guide: Optimizely Web Experimentation Reverse Proxy with Cloudflare Workers and Vercel

Public-safe edition

This version has been sanitised for public documentation. Replace every value in [BRACKETS] with your own environment-specific value when following the guide.

Do not publish: real domains, project IDs, account IDs, email addresses, IP addresses, internal URLs, customer names, screenshots containing account information, API tokens, cookies, access tokens, or private configuration.

Last verified: 31 July 2026
Level: Beginner
Goal: Learn how to route Optimizely Web Experimentation requests through a first-party Cloudflare Worker hostname while keeping your Next.js website hosted on Vercel.

Public documentation placeholder legend

PlaceholderReplace with
[YOUR_DOMAIN]Your own domain, e.g. example.com
[YOUR_SNIPPET_ID]Your Optimizely Web Experimentation snippet/project identifier
[YOUR_ACCOUNT_ID]Your Optimizely account ID
[YOUR_PROJECT_ID]Your Optimizely project ID
[YOUR_WORKERS_SUBDOMAIN]Your Cloudflare Workers workers.dev subdomain
[YOUR_VERCEL_PREVIEW_URL]Your exact Vercel preview URL, only if needed
[CLOUDFLARE_EDGE_ADDRESS]A runtime network address, if you choose to document one; normally omit it

Tip: For a public tutorial, it is usually better to use placeholders even for values that are technically non-secret. This prevents readers from accidentally treating the author's environment as a copy-and-paste configuration.

1. What you are building

Your main website will remain on Vercel:

Visitor
https://[YOUR_DOMAIN]
Vercel

Optimizely requests will use a separate hostname connected to a Cloudflare Worker:

Visitor's browser
   ├── GET https://edge.[YOUR_DOMAIN]/js/YOUR_PROJECT_ID.js
   │          │
   │          ▼
   │     Cloudflare Worker
   │          │
   │          ▼
   │     https://cdn.optimizely.com/js/YOUR_PROJECT_ID.js
   └── POST https://edge.[YOUR_DOMAIN]/v1/events
         Cloudflare Worker
         https://logx.optimizely.com/v1/events

The Worker has a simple job:

  1. Receive a request from the visitor's browser.
  2. Send that request to the correct Optimizely service.
  3. Return Optimizely's response to the browser.

This is called a reverse proxy because the browser communicates with your hostname, while the proxy communicates with Optimizely on the browser's behalf.


2. What this guide does not build

This guide does not:

  • move your Next.js website from Vercel to Cloudflare;
  • place a Cloudflare Worker in front of your entire website;
  • use Next.js rewrites as the Optimizely proxy;
  • configure Optimizely Edge Delivery;
  • guarantee that every privacy browser or extension will allow Optimizely;
  • replace your cookie-consent or privacy implementation.

Using a first-party hostname can reduce the likelihood of simple domain-list blocking. It is not a guarantee against every filtering technique.

You must continue to respect the visitor's consent choice. A reverse proxy changes the network route; it must not be used to bypass consent.

How to use this guide

Complete the steps in order. Every step contains a Success check. Do not continue to the next phase until that check passes.

Use these three milestones:

Milestone 1: The snippet loads through the temporary workers.dev address.
Milestone 2: The snippet loads through edge.[YOUR_DOMAIN].
Milestone 3: Browser events POST through edge.[YOUR_DOMAIN]/v1/events.

When something fails, troubleshoot the current milestone only. Do not change DNS, Next.js, and Optimizely settings at the same time.


3. Four terms to understand first

Origin

The server that owns the original resource.

In this guide:

  • the snippet origin is cdn.optimizely.com;
  • the event origin is logx.optimizely.com;
  • your website origin is [YOUR_DOMAIN].

Reverse proxy

A server that receives a browser request and forwards it to another server.

Your Cloudflare Worker will be the reverse proxy.

Worker

JavaScript code that runs on Cloudflare's network when a request reaches its assigned address.

Custom Domain

A hostname, such as edge.[YOUR_DOMAIN], that Cloudflare connects directly to a Worker. Cloudflare creates the required DNS record and certificate for the hostname.


4. The two Optimizely request types

Do not treat the setup as one large change. It has two separate parts.

PartBrowser requestPurpose
Snippet deliveryGET requestDownloads the Optimizely JavaScript and configuration
Event trackingPOST requestSends experiment decisions and conversions to Optimizely

You will make snippet delivery work first. You will configure event tracking only after the snippet works.


5. Hostnames used in this guide

HostnamePurposeWhat manages it
[YOUR_DOMAIN]Your main Next.js websiteVercel
edge.[YOUR_DOMAIN]Optimizely reverse-proxy endpointCloudflare Worker Custom Domain

edge.[YOUR_DOMAIN] is used instead of a hostname containing the word optimizely. This may reduce simple hostname-based filtering, but it does not guarantee that the requests will never be blocked.

A Worker Custom Domain is not the same as manually creating a normal CNAME and switching on the orange-cloud icon. Cloudflare creates and manages the DNS record when you attach the Custom Domain to the Worker.


Phase 1: Prepare the setup

Step 1: Leave your working Vercel website unchanged

Goal

Protect your working website while you learn.

What to do

Do not change the existing DNS record that currently makes this address work:

https://[YOUR_DOMAIN]

Do not add a Worker route to the main domain.

Do not use proxy.[YOUR_DOMAIN] for this exercise.

Why

The Optimizely proxy does not need to sit in front of your complete Vercel application. Keeping the Worker on a separate hostname isolates your experiment from the main website.

Vercel also warns that placing a reverse proxy in front of an entire Vercel project can affect firewall visibility and client-IP handling. This guide avoids that architecture.

Success check

Open:

https://[YOUR_DOMAIN]

Your website should load as it did before.

Do not continue if the main website is already broken. Fix the existing website first.


Step 2: Collect your Optimizely information

Goal

Find the identifiers you will need later.

What to do

In Optimizely Web Experimentation, open:

Settings → Implementation

Find your current project snippet. A standard snippet looks similar to this:

<script src="https://cdn.optimizely.com/js/123456789.js"></script>

Record the number before .js:

Project/snippet ID: 123456789

Also record:

Account ID: [YOUR_ACCOUNT_ID]
Project ID: [YOUR_PROJECT_ID]

The account ID is normally available under:

Account Settings → Plan

Why

  • The snippet ID identifies the JavaScript file that your browser must download.
  • Optimizely Support will need the account ID and project ID when you request the event-tracking-host change.

Success check

You should have these values written down:

Snippet URL:
Snippet or project ID:
Account ID:
Project ID:

Never install two Optimizely project snippets on the same page at the same time.


Phase 2: Build the Cloudflare Worker

Step 3: Create a basic Worker

Goal

Create the Cloudflare application that will become the reverse proxy.

What to do

In Cloudflare:

  1. Open Workers & Pages.
  2. Select Create application.
  3. Select Create Worker or the Hello World starting option shown in your dashboard.
  4. Name the Worker:
optimizely-proxy
  1. Deploy the starter Worker.
  2. Open the new Worker and select Edit Code.

Cloudflare should provide a temporary address similar to:

https://optimizely-proxy.[YOUR_WORKERS_SUBDOMAIN].workers.dev

Why

The temporary workers.dev address lets you test the code before connecting your own hostname.

Success check

Open the temporary Worker address. You should receive the starter response without an error.


Step 4: Replace the starter code with the proxy code

Goal

Teach the Worker where to send snippet requests and event requests.

What to do

Delete the starter Worker code and replace it with the following. You do not need to memorise every line before you begin; the four behaviours are explained immediately after the code.

const OPTIMIZELY_CDN = "https://cdn.optimizely.com";
const OPTIMIZELY_EVENTS = "https://logx.optimizely.com/v1/events";

// Only these websites may send browser event requests through the Worker.
const ALLOWED_ORIGINS = new Set([
  "https://[YOUR_DOMAIN]",
  "https://www.[YOUR_DOMAIN]",
  // Add your exact Vercel preview URL here only when you need to test it.
  // "https://your-project.vercel.app",
  // Add localhost only when you need local testing.
  // "http://localhost:3000",
]);

function isAllowedOrigin(origin) {
  return origin !== null && ALLOWED_ORIGINS.has(origin);
}

function addCorsHeaders(headers, origin) {
  if (!isAllowedOrigin(origin)) {
    return;
  }

  headers.set("Access-Control-Allow-Origin", origin);

  const currentVary = headers.get("Vary");
  headers.set(
    "Vary",
    currentVary ? `${currentVary}, Origin` : "Origin"
  );
}

function copyRequestHeaders(request) {
  const headers = new Headers(request.headers);

  // These cookies belong to your site and should not be forwarded to Optimizely.
  headers.delete("Cookie");

  // Do not forward credentials that may belong to your own application.
  headers.delete("Authorization");

  // Cloudflare sets the correct upstream Host value from the destination URL.
  headers.delete("Host");

  return headers;
}

export default {
  async fetch(request) {
    const incomingUrl = new URL(request.url);
    const origin = request.headers.get("Origin");

    try {
      // A. Answer the browser's CORS permission check for event requests.
      if (
        request.method === "OPTIONS" &&
        incomingUrl.pathname === "/v1/events"
      ) {
        if (!isAllowedOrigin(origin)) {
          return new Response("Origin not allowed", { status: 403 });
        }

        const headers = new Headers();
        addCorsHeaders(headers, origin);
        headers.set("Access-Control-Allow-Methods", "POST, OPTIONS");
        headers.set(
          "Access-Control-Allow-Headers",
          request.headers.get("Access-Control-Request-Headers") ||
            "Content-Type"
        );
        headers.set("Access-Control-Max-Age", "86400");

        return new Response(null, {
          status: 204,
          headers,
        });
      }

      // B. Forward all GET and HEAD paths to Optimizely's CDN.
      if (request.method === "GET" || request.method === "HEAD") {
        const upstreamUrl = new URL(
          incomingUrl.pathname + incomingUrl.search,
          OPTIMIZELY_CDN
        );

        const upstreamResponse = await fetch(upstreamUrl, {
          method: request.method,
          headers: copyRequestHeaders(request),
        });

        return new Response(upstreamResponse.body, {
          status: upstreamResponse.status,
          statusText: upstreamResponse.statusText,
          headers: upstreamResponse.headers,
        });
      }

      // C. Forward only POST /v1/events to Optimizely's event service.
      if (
        request.method === "POST" &&
        incomingUrl.pathname === "/v1/events"
      ) {
        if (!isAllowedOrigin(origin)) {
          return new Response("Origin not allowed", { status: 403 });
        }

        const upstreamResponse = await fetch(OPTIMIZELY_EVENTS, {
          method: "POST",
          headers: copyRequestHeaders(request),
          body: request.body,
        });

        const responseHeaders = new Headers(upstreamResponse.headers);
        addCorsHeaders(responseHeaders, origin);

        return new Response(upstreamResponse.body, {
          status: upstreamResponse.status,
          statusText: upstreamResponse.statusText,
          headers: responseHeaders,
        });
      }

      // D. Reject methods and event paths that this proxy does not need.
      return new Response("Not found", { status: 404 });
    } catch (error) {
      console.error("Optimizely proxy error", error);
      return new Response("Upstream proxy error", { status: 502 });
    }
  },
};

Select Deploy.

Why this code is structured this way

The code has four main behaviours:

GET or HEAD any path
→ Send it to cdn.optimizely.com using the same path
OPTIONS /v1/events
→ Answer the browser's cross-origin permission check
POST /v1/events
→ Send it to logx.optimizely.com/v1/events
Anything else
→ Return 404

Optimizely's reverse-proxy guidance specifies a wildcard GET route for the CDN. This is why the Worker preserves the complete path instead of allowing only /js/ and /public/.

The destination host is hard-coded. A visitor cannot use this Worker to choose an arbitrary external website.

The Worker removes Cookie before forwarding requests because cookies scoped to .[YOUR_DOMAIN] might otherwise be sent to edge.[YOUR_DOMAIN]. A direct browser request to cdn.optimizely.com would not receive those first-party cookies.

Why CORS is needed

These are different browser origins:

https://[YOUR_DOMAIN]
https://edge.[YOUR_DOMAIN]

They use different hostnames. The browser may therefore send an OPTIONS request before allowing the event POST. The CORS code permits only the website origins listed in ALLOWED_ORIGINS.

Success check

Cloudflare should show the new Worker version as deployed.


Step 5: Test snippet delivery on the temporary Worker address

Goal

Confirm the Worker can retrieve your real Optimizely snippet before changing DNS or Next.js.

What to do

Open this URL, replacing both placeholders:

https://optimizely-proxy.[YOUR_WORKERS_SUBDOMAIN].workers.dev/js/[YOUR_SNIPPET_ID].js

Example shape:

https://optimizely-proxy.example.workers.dev/js/123456789.js

Why

The request should follow this path:

Your browser
→ workers.dev address
→ Cloudflare Worker
→ cdn.optimizely.com

Testing here isolates the Worker from your custom-domain and Next.js configuration.

Success check

You should see minified JavaScript in the browser.

In Chrome DevTools → Network, the request should have:

Status: 200
Content-Type: JavaScript

Stop here if you receive 404, 500, 502, or a Cloudflare error. Do not connect the custom domain until this test works.


Phase 3: Connect your hostname to the Worker

Step 6: Check for an existing DNS record

Goal

Prevent a hostname conflict.

What to do

In Cloudflare, open:

[YOUR_DOMAIN] → DNS → Records

Search for:

edge

If a record already exists for edge.[YOUR_DOMAIN], remove it only when you are certain that it is not being used by another service.

Why

Cloudflare cannot create a Worker Custom Domain on a hostname that already has a conflicting CNAME record.

Success check

There should be no existing DNS record using edge.[YOUR_DOMAIN].


Step 7: Add the Worker Custom Domain

Goal

Give the Worker a first-party hostname under your domain.

What to do

Open:

Workers & Pages
→ optimizely-proxy
→ Settings
→ Domains & Routes
→ In domains search for chabu.chabu.com domain
→ Once found click next,you will see an option to enter a subdomain.
→ Enter only edge. ths will eventually be edge.[YOUR_DOMAIN].

Enter:

edge.[YOUR_DOMAIN]

Select Add Custom Domain.

Wait until Cloudflare shows the hostname as active.

Why

Cloudflare creates the required DNS record and TLS certificate. All paths under edge.[YOUR_DOMAIN] will now reach the Worker.

Do not manually create an additional CNAME for this hostname.

Success check

Cloudflare should show:

edge.[YOUR_DOMAIN] — Active

Step 8: Test the snippet through the custom domain

Goal

Confirm that DNS, TLS, the Worker, and the Optimizely CDN all work together.

What to do

Open:

https://edge.[YOUR_DOMAIN]/js/[YOUR_SNIPPET_ID].js

Why

The complete request path is now:

Your browser
→ edge.[YOUR_DOMAIN]
→ Cloudflare Worker
→ cdn.optimizely.com

Success check

You should see the minified Optimizely JavaScript and receive a 200 response.

Stop here if this fails. Your Next.js application should not be changed until this address works directly in the browser.


Phase 4: Connect the Next.js website

Step 9: Replace the existing Optimizely snippet URL

Goal

Make the website download Optimizely through your Worker instead of directly from Optimizely's CDN.

What to do

In your Next.js App Router project, open:

app/layout.tsx

Find and remove the existing Optimizely script tag, such as:

<script src="https://cdn.optimizely.com/js/[YOUR_SNIPPET_ID].js"></script>

Add the proxy version high inside <head>:

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <head>
        <script src="https://edge.[YOUR_DOMAIN]/js/[YOUR_SNIPPET_ID].js"></script>
      </head>
      <body>{children}</body>
    </html>
  );
}

Replace [YOUR_SNIPPET_ID] with your real value.

Do not add async or defer during this learning exercise.

Deploy the change to Vercel.

Why

Optimizely recommends loading the Web Experimentation snippet synchronously and as high in <head> as practical to reduce visible flicker.

Before:

Browser → cdn.optimizely.com

After:

Browser → edge.[YOUR_DOMAIN] → Worker → cdn.optimizely.com

Important Next.js note

Next.js also provides the next/script component with strategy="beforeInteractive". That is a valid framework tool for critical early scripts, but it changes how Next.js schedules and preloads the resource. This beginner guide uses the direct synchronous <script> element so the loading behaviour stays closest to Optimizely's one-line installation guidance.

Next.js uses server rendering and hydration. Optimizely visual changes made before hydration can sometimes be overwritten by React. That is a separate integration topic from reverse proxying. Start with a simple test and verify that the variation remains visible after the page finishes loading.

Success check

The Vercel deployment should complete successfully.


Step 10: Verify that the website loads only the proxy snippet

Goal

Prove that the browser is using the new address and that you have not installed the snippet twice.

What to do

  1. Open an incognito browser window.
  2. Open https://[YOUR_DOMAIN].
  3. Open Chrome DevTools.
  4. Select Network.
  5. Reload the page.
  6. Search for your snippet ID or edge.[YOUR_DOMAIN].

Success check

You should see one request similar to:

GET https://edge.[YOUR_DOMAIN]/js/[YOUR_SNIPPET_ID].js
Status: 200

You should not see another project-snippet request to:

https://cdn.optimizely.com/js/[YOUR_SNIPPET_ID].js

In the Console, run:

window.optimizely

It should be defined rather than undefined.

Why

At this stage, you have proved that snippet delivery works through your reverse proxy.

Event requests may still go directly to logx.optimizely.com. That is expected until Optimizely changes the project build setting.


Step 11: Run a simple QA experiment

Goal

Confirm that the snippet can activate an experiment before changing event tracking.

What to do

Create or use a small QA experiment, for example:

Change one heading from “Welcome” to “Reverse Proxy Test”

Use Optimizely's normal QA or forced-variation process to view the variation.

Why

You are testing the first half of the architecture:

Snippet and configuration delivery

Do not troubleshoot event routing until the experiment itself activates correctly.

Success check

Confirm all three:

The proxy snippet returns 200.
window.optimizely is defined.
The QA variation appears and remains visible.

Phase 5: Route Optimizely events through the Worker

Step 12: Ask Optimizely to update the event-tracking host

Goal

Make the Web Experimentation snippet send experiment events to your Worker.

What to do

If you are still onboarding, contact your Onboarding Solutions Architect. Otherwise, contact Optimizely Support.

Send this request:

Hello,

Please update the EVENT_TRACKING_HOST build setting for the following
Optimizely Web Experimentation project:

Account ID: [YOUR_ACCOUNT_ID]
Project ID: [YOUR_PROJECT_ID]

Reverse-proxy base URL:
https://edge.[YOUR_DOMAIN]

The Worker accepts event requests at:
https://edge.[YOUR_DOMAIN]/v1/events

It forwards those POST requests to:
https://logx.optimizely.com/v1/events

Please confirm the exact event URL that will be generated in the project
snippet after the build-setting change.

Thank you.

Why

Changing the HTML script tag only changes where the JavaScript file is downloaded.

The JavaScript bundle still contains the event-tracking destination. Optimizely must update the EVENT_TRACKING_HOST build setting for the relevant Web Experimentation project.

Asking Optimizely to confirm the generated URL prevents you from guessing whether the setting expects only the hostname or a particular path format.

Success check

Optimizely confirms that the setting has been updated and the project snippet has been rebuilt.


Step 13: Verify event requests

Goal

Confirm that decision and conversion events are passing through the Worker.

What to do

After Optimizely confirms the update:

  1. Open a new incognito window.
  2. Open Chrome DevTools → Network.
  3. Load the experiment page.
  4. Perform the action used by your test metric.
  5. Search for:
v1/events

Success check

You should see:

POST https://edge.[YOUR_DOMAIN]/v1/events

The normal successful response from Optimizely's event endpoint is:

204 No Content

You should no longer see the browser sending the equivalent event directly to:

https://logx.optimizely.com/v1/events

Then verify that visitors and conversions appear in the appropriate Optimizely results page.


Phase 6: Compare normal and privacy-focused browsing

Step 14: Run a controlled comparison

Goal

Understand whether the first-party route changes blocking behaviour.

What to do

Test the same QA experiment in:

  1. normal Chrome without extensions;
  2. Chrome with the privacy extension you want to evaluate;
  3. the privacy-focused browser you want to evaluate.

For each test, record:

TestSnippet requestEvent requestVariation shownEvent recorded
Normal Chrome
Browser/extension test 1
Browser/extension test 2

Why

A Solutions Architect should test each part of the request flow instead of assuming that a first-party hostname solves every blocking method.

Success check

You can explain exactly which request succeeded or failed in each browser.


Troubleshooting guide

The custom-domain snippet returns 404

Check:

  • the snippet ID is correct;
  • the URL contains /js/;
  • the Worker code is deployed;
  • edge.[YOUR_DOMAIN] is attached to the correct Worker.

Test the original Optimizely URL directly:

https://cdn.optimizely.com/js/[YOUR_SNIPPET_ID].js

If the original URL also returns 404, the snippet ID is probably incorrect.


The Worker returns 502

A 502 from this Worker means its request to Optimizely failed or the Worker threw an error.

Open:

Workers & Pages → optimizely-proxy → Logs

Look for:

Optimizely proxy error

window.optimizely is undefined

Check:

  • the snippet request returned 200;
  • the response contains JavaScript rather than an error page;
  • Content Security Policy allows edge.[YOUR_DOMAIN] under script-src;
  • the browser did not block the request;
  • the snippet is not being loaded after an earlier JavaScript error.

The variation appears and then disappears

This may be a React or Next.js hydration issue rather than a reverse-proxy problem.

The proxy has succeeded if:

The snippet loaded from edge.[YOUR_DOMAIN] with status 200.

Investigate Optimizely's React SSR and hydration guidance separately.


The event request returns 403

The browser's exact Origin value is probably missing from ALLOWED_ORIGINS.

In DevTools, inspect the failed request's Request Headers and find:

Origin

Add that exact value to the Worker allowlist and deploy again.

Do not add a wildcard origin merely to hide the error.


The event request still goes directly to logx.optimizely.com

Possible causes:

  • Optimizely has not updated EVENT_TRACKING_HOST yet;
  • the wrong project ID was updated;
  • the snippet was not rebuilt after the setting changed;
  • the browser or CDN is using an older cached snippet;
  • the page is loading a different Optimizely snippet.

Compare the snippet ID in DevTools with the project that Optimizely Support updated.


The browser reports a Content Security Policy error

Your application may use a Content Security Policy.

The new hostname may need to be allowed in directives such as:

script-src
connect-src

Do not copy a broad CSP from another website. Update only the directives required by your application's existing policy.


Safe rollback

If you need to undo the application change, replace:

<script src="https://edge.[YOUR_DOMAIN]/js/[YOUR_SNIPPET_ID].js"></script>

with the original Optimizely snippet:

<script src="https://cdn.optimizely.com/js/[YOUR_SNIPPET_ID].js"></script>

Redeploy the Next.js application.

If Optimizely has already changed EVENT_TRACKING_HOST, ask Optimizely to restore the original setting as part of the rollback. Reverting only the HTML script URL does not automatically revert the event destination embedded in the snippet.


Production-readiness questions

The Worker above is suitable for learning and controlled testing. Before using a similar design for a customer production environment, review:

  • separate development, staging, and production hostnames;
  • exact origin allowlists for every environment;
  • Cloudflare Worker logs and monitoring;
  • rate limiting or abuse controls for /v1/events;
  • Content Security Policy changes;
  • cache behaviour and snippet update expectations;
  • rollback ownership and procedure;
  • privacy, legal, and consent requirements;
  • whether the customer uses a standard, custom, or PCI-compliant snippet;
  • testing for Next.js or React hydration behaviour;
  • the customer's change-management and security-review process.

For a PCI-compliant snippet, the CDN host must be reviewed and changed from:

cdn.optimizely.com

to:

cdn-pci.optimizely.com

Do not make that change unless the Optimizely project actually uses the PCI-compliant snippet.


Standard snippet versus custom snippet

The main steps in this guide use a standard snippet:

https://cdn.optimizely.com/js/PROJECT_ID.js

A custom snippet normally uses an Optimizely /public/ACCOUNT_ID/... path. Optimizely's Cloudflare self-hosting documentation highlights custom snippets for additional account-level path verification.

The Worker in this guide preserves CDN paths, so a custom snippet can also be proxied using the equivalent path under edge.[YOUR_DOMAIN]. However, the correct custom-snippet URL should be copied from Optimizely and tested separately rather than guessed.

As a beginner, first complete the standard-snippet exercise. Then repeat it with a custom snippet as an advanced learning task.


What you should be able to explain after completing the guide

You should be able to answer these questions clearly:

  1. Why does the main Vercel website not need to pass through the Worker?
  2. What is the difference between snippet delivery and event tracking?
  3. Why is a Worker Custom Domain different from a normal manually created DNS record?
  4. Why must the Worker preserve wildcard CDN paths?
  5. Why must first-party cookies be removed before forwarding a request?
  6. Why does the event endpoint need CORS handling?
  7. Why must Optimizely update EVENT_TRACKING_HOST?
  8. Why does a 204 event response count as success?
  9. Why does a first-party reverse proxy reduce blocking risk without guaranteeing success?
  10. Why must consent behaviour remain unchanged?

These are the architectural explanations that matter in a Solutions Architect conversation—not only whether the code runs.


Official references


Public publication checklist

Before publishing this guide, search the Markdown for:

  • your real domain name;
  • @ symbols or email addresses;
  • real Optimizely account/project/snippet IDs;
  • customer or employer names;
  • internal hostnames or URLs;
  • IP addresses;
  • API keys, tokens, secrets, cookies, or authorization headers;
  • screenshots containing browser history, account names, project names, IDs, or personal data;
  • copied DevTools output containing request headers, cookies, query parameters, or identifiers.

If any appear, replace them with placeholders or remove them.

For a beginner-facing public guide, keep the learning flow isolated: test the Worker → test the custom domain → connect the website → test events → run QA → troubleshoot → review production readiness.

Built with LogoFlowershow