Meritt Get started

All platforms

Affiliate tracking inside your web application

If your site is an application, the rule can live inside it: one route on your tracking prefix that relays the request to us and returns the answer. Three details separate a route that tracks from one that only looks like it: accepting GET and POST, keeping the query string, and not requiring a CSRF token.

Next.js

Where: next.config.js

One entry in rewrites() in next.config.js. Next.js does not strip headers: your visitors' cookies reach us, and we do not read them.

Nuxt

Where: nuxt.config.ts

One routeRules entry with proxy in nuxt.config.ts. Like Next.js, Nuxt does not strip the headers of the relayed request.

Express

Where: app.js

One app.all route in app.js: it relays with https.request using req.originalUrl, never the token alone, since the query string carries the click id. It returns the cookie set and the redirect.

Node (standalone proxy)

Where: server.js

For a site with no application server: a small Node proxy in two files, server.js and package.json, started with npm start. It uses https.request and never fetch, which overwrites the Sec-Fetch headers: every visitor would look like a machine and every click would be discarded.

ASP.NET Core

Where: Program.cs

One GET and POST MapMethods in Program.cs: the request is relayed with its headers and query string through an IHttpClientFactory client, and the response returns the cookie and the redirect.

Laravel

Where: routes/web.php

One GET and POST Route::match in routes/web.php, plus a CSRF exception in bootstrap/app.php: the tag posts with no token, and without the exception Laravel answers 419. The query string is relayed raw, because getQueryString() reorders it.

Ruby on Rails

Where: config/routes.rb + a controller

A GET and POST route in config/routes.rb and a MerittController with skip_forgery_protection, for the same reason as Laravel: the tag reports through sendBeacon, with no token.

Django

Where: urls.py + a view

Two steps: the route in urls.py, then the view in views.py, marked @csrf_exempt — otherwise Django refuses before the view — which relays with requests without following redirects.

Common questions

Why accept POST?

The tag reports the click through sendBeacon, which sends a POST. A route that only accepts GET lets the redirect through and loses that signal.

Why keep the query string as it is?

It carries the click id. A method that reorders or re-encodes it can lose it.

After adding the route?

Restart the application, redeploy it, then run the check in Meritt.

And then

Free until your first commission. No card asked for.