Background
⌘K

Proxy Setup (Optional)

Serve Affonso from your own domain for Bypassing Ad Blockers.

Silvestro
Written by Silvestro
Updated more than a week ago

Proxy Pixel and Embed Through Your Own Domain

Use this guide if you want more reliable pixel and embed delivery in environments where ad blockers, privacy tools, or strict browser policies are common.

In the standard setup, the browser talks directly to:

  • cdn.affonso.io for the pixel script
  • api.affonso.io for tracking requests
  • affonso.io for the embedded dashboard

If that causes tracking or embed issues, you can proxy the same routes through your own domain. Affonso calls this first-party delivery.

If the hosted setup already works for you, keep using it. First-party delivery is optional.

What This Changes

With first-party delivery:

  • the browser loads the pixel from your domain
  • browser-visible tracking requests stay on your domain
  • the embedded dashboard can load from your domain too

This usually helps because blockers are less likely to flag requests that start on your own domain.

Before You Start

You need:

  • a domain you control
  • a reverse proxy, rewrite layer, or edge function on that domain
  • one path prefix that you will reserve for Affonso, such as /r

You do not need to use /affonso. The prefix is configurable.

If your main goal is to avoid blockers, use a neutral prefix such as:

/r

Route Map

Proxy these customer-domain paths to the Affonso hosted endpoints:

Your pathForward toRequired for
/r/pixel.jshttps://cdn.affonso.io/js/pixel.min.jsPixel installs
/r/psl.min.jshttps://cdn.affonso.io/js/psl.min.jsPixel installs
/r/trackhttps://api.affonso.io/v1/trackClick tracking
/r/signupshttps://api.affonso.io/v1/signupsSignup tracking
/r/embed/:path*https://affonso.io/embed/:path*Embedded dashboard

Notes:

  • keep the suffixes exactly as shown: /pixel.js, /psl.min.js, /track, /signups, and /embed/...
  • only the prefix is your choice
  • if you do not use signup tracking, /r/signups can be omitted
  • if you do not use the embedded dashboard, /r/embed/:path* can be omitted

Step 1: Choose a Prefix

Pick one short path on your domain and use it consistently everywhere.

Examples:

  • /r
  • /partner
  • /links

All examples below use /r.

Step 2: Add the Proxy Routes

Option 1: Vercel rewrites

If your site runs on Vercel, add these rewrites:

{
  "rewrites": [
    {
      "source": "/r/pixel.js",
      "destination": "https://cdn.affonso.io/js/pixel.min.js"
    },
    {
      "source": "/r/psl.min.js",
      "destination": "https://cdn.affonso.io/js/psl.min.js"
    },
    {
      "source": "/r/track",
      "destination": "https://api.affonso.io/v1/track"
    },
    {
      "source": "/r/signups",
      "destination": "https://api.affonso.io/v1/signups"
    },
    {
      "source": "/r/embed/:path*",
      "destination": "https://affonso.io/embed/:path*"
    }
  ]
}

Option 2: Cloudflare Worker

If you use Cloudflare, attach a Worker to a route such as:

customer.com/r/*

The important part is that the Worker forwards the original request method, headers, body, and query string unchanged:

export default {
  async fetch(request) {
    const url = new URL(request.url);

    const directMap = {
      '/r/pixel.js': 'https://cdn.affonso.io/js/pixel.min.js',
      '/r/psl.min.js': 'https://cdn.affonso.io/js/psl.min.js',
      '/r/track': 'https://api.affonso.io/v1/track',
      '/r/signups': 'https://api.affonso.io/v1/signups',
    };

    if (directMap[url.pathname]) {
      return fetch(new Request(directMap[url.pathname], request));
    }

    if (url.pathname.startsWith('/r/embed/')) {
      const upstream = new URL(
        `https://affonso.io${url.pathname.replace('/r', '')}${url.search}`
      );
      return fetch(new Request(upstream.toString(), request));
    }

    return fetch(request);
  },
};

If you use Cloudflare Snippets or another Cloudflare proxy layer instead of a Worker, keep the same path mapping and preserve the full request body for POST /r/track and POST /r/signups.

Option 3: NGINX

If you use NGINX, add explicit locations for the Affonso routes:

location = /r/pixel.js {
  proxy_pass https://cdn.affonso.io/js/pixel.min.js;
  proxy_set_header Host cdn.affonso.io;
}

location = /r/psl.min.js {
  proxy_pass https://cdn.affonso.io/js/psl.min.js;
  proxy_set_header Host cdn.affonso.io;
}

location = /r/track {
  proxy_pass https://api.affonso.io/v1/track;
  proxy_http_version 1.1;
  proxy_set_header Host api.affonso.io;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location = /r/signups {
  proxy_pass https://api.affonso.io/v1/signups;
  proxy_http_version 1.1;
  proxy_set_header Host api.affonso.io;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /r/embed/ {
  proxy_pass https://affonso.io/embed/;
  proxy_http_version 1.1;
  proxy_set_header Host affonso.io;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

If your NGINX stack has extra request filtering, make sure it does not strip JSON request bodies or query strings on the tracking endpoints.

Step 3: Update the Pixel Script

Load the pixel from your domain and set data-api-base to the same prefix:

<script
  async
  defer
  src="https://customer.com/r/pixel.js"
  data-affonso="YOUR_PUBLIC_PROGRAM_ID"
  data-cookie_duration="30"
  data-api-base="/r"
></script>

data-api-base must match the prefix from your proxy routes.

If you also need consent mode, keep your existing consent attributes. Only the script URL and data-api-base need to change.

Step 4: Update the Embedded Dashboard

If you use the embedded dashboard, load the iframe from the same prefix:

<iframe
  src="https://customer.com/r/embed/referrals?token=YOUR_EMBED_TOKEN&theme=light&lang=en"
  style="width: 100%; height: 600px; border: none;"
  allow="clipboard-write"
></iframe>

The embed token still needs to be created on your server. First-party delivery does not change token generation or auth requirements.

Verify the Setup

After you deploy the proxy:

  1. Open https://customer.com/r/pixel.js directly in the browser and confirm it returns JavaScript.
  2. Load a page with the updated pixel script.
  3. Visit your site with an affiliate parameter such as ?atp=test.
  4. In DevTools, confirm the browser sends requests to /r/track.
  5. If you use signup tracking, confirm requests go to /r/signups.
  6. If you use the embedded dashboard, confirm the iframe loads from /r/embed/....

If all of those pass, the proxy is set up correctly.

Troubleshooting

The script loads, but clicks are not tracked

  • Confirm the script tag uses your proxied src
  • Confirm data-api-base matches the prefix exactly
  • Check that POST /r/track reaches your proxy and returns 200
  • Make sure your proxy preserves request bodies and query strings

Signup tracking does not work

  • Confirm you are proxying /r/signups
  • Confirm your app still calls window.Affonso.signup()
  • Check whether the referral cookie exists before signup
  • Inspect the network request to /r/signups for proxy errors

The embedded dashboard stays blank or fails to load

  • Confirm you are proxying /r/embed/:path*
  • Make sure the iframe src points to your domain, not affonso.io
  • Confirm the embed token is created on the server and still valid
  • Check browser DevTools for CSP, auth, or proxy errors

Can I proxy only part of the setup?

Yes.

Common combinations:

  • pixel only: /r/pixel.js, /r/psl.min.js, /r/track
  • pixel + signup tracking: add /r/signups
  • embedded dashboard only: /r/embed/:path*

FAQ

Is /affonso required?

No. The prefix is not hardcoded. Only the route suffixes are fixed.

Should I switch every customer to first-party delivery?

No. Use it when you have a concrete blocker problem or want a more resilient setup. The hosted setup remains the default.

Does this replace custom domains for the affiliate portal?

No. This guide is only about proxying the pixel and embedded dashboard through your own domain.

Was this article helpful?

If you still need help, our support team is here for you.

Contact Support
bg

Ready to Scale Your SaaS?

Affonso is the easiest way to launch your own affiliate program. We take care of the technical stuff, so you can focus on growing your business.