Docs·Proxy guide
Proxy with Next.js
One route handler in the App Router serves Spreelytics from /sp/. This guide uses /sp/. Any path works if nothing else on your site uses it and it doesn't contain words like "analytics" or "tracking", which blockers look for.
Add the route handler
Create app/sp/[...path]/route.ts:
// app/sp/[...path]/route.ts
// Serves Spreelytics from /sp/ on your site: /sp/js/ is the script, everything else is tracking.
const SCRIPTS = "https://cdn.spreelytics.com/cdn/sdk/";
const API = "https://sdk.spreelytics.com/1.0/";
const FORWARD = ["content-type", "user-agent", "origin", "referer", "accept", "accept-language"];
async function proxy(request: Request, { params }: { params: Promise<{ path: string[] }> }) {
const path = (await params).path.join("/");
const target = (path.startsWith("js/") ? SCRIPTS + path.slice(3) : API + path) + new URL(request.url).search;
const headers = new Headers();
for (const name of FORWARD) {
const value = request.headers.get(name);
if (value) headers.set(name, value);
}
// The visitor's IP address. Vercel and most hosts put it first in X-Forwarded-For.
const ip = request.headers.get("x-forwarded-for")?.split(",")[0].trim();
if (ip) headers.set("x-forwarded-for", ip);
const upstream = await fetch(target, {
method: request.method,
headers,
body: request.method === "GET" || request.method === "HEAD" ? undefined : await request.arrayBuffer(),
cache: "no-store",
});
// fetch has already unzipped the body, so these headers no longer apply.
const responseHeaders = new Headers(upstream.headers);
responseHeaders.delete("content-encoding");
responseHeaders.delete("content-length");
return new Response(upstream.body, { status: upstream.status, headers: responseHeaders });
}
export { proxy as GET, proxy as POST };
Point the script at your proxy
In your Spreelytics snippet (see Next.js), load the script through /sp/js/ and add api_host:
<script src="/sp/js/spreelytics-loader.js"></script>
<script>
Spreelytics.init({
client_key: "YOUR_CLIENT_KEY",
api_host: "https://www.example.com/sp",
});
</script>
Check it works
Open your site with the browser's Network tab open and filtered by /sp/. The script files and
requests like track/page should come from your own domain, with status 200. In Spreelytics,
Settings → Tracking script says "Last seen just now" and Realtime shows you in your own country.
- Wrong country, or
200and nothing arrives: the proxy isn't passing the visitor's IP address inX-Forwarded-For. See The visitor's IP address below. 401: theOriginandRefererheaders didn't arrive, or your domain isn't in Allowed domains.
The visitor's IP address
The handler passes on the first address in X-Forwarded-For, which Vercel, Netlify and most load balancers set to the visitor. If you run next start with nothing in front of it, put nginx or Caddy in front, or every visitor arrives from your server's address.
Related
- Proxy overview: the other ways to set it up.
- Filter traffic: which traffic Spreelytics drops.