Skip to content

Render

Render runs your app behind Cloudflare and its own load balancer. WebDecoy runs inside the app as your framework’s middleware, so it sees every request that reaches your code, including crawlers that never run JavaScript.

Each starter has a Deploy to Render button that creates a free web service from its render.yaml. The same repositories deploy to Railway too: the code picks the right client-IP setting from the RENDER variable Render sets.

Framework Deploy Source
Express Deploy to Render WebDecoy/railway-express-starter
Next.js 16 Deploy to Render WebDecoy/railway-nextjs-starter
Fastify 5 Deploy to Render WebDecoy/railway-fastify-starter
Hono (Node) Deploy to Render WebDecoy/railway-hono-starter
Angular SSR Deploy to Render WebDecoy/railway-angular-ssr-starter
  1. In WebDecoy, create an API key under Settings > API Keys.
  2. Click Deploy to Render, name the Blueprint, and paste the key into WEBDECOY_API_KEY. It is a secret, so keep it in Render’s environment and never in a file you commit.
  3. Open the service’s onrender.com address and send a test request (see Prove it reports).

The middleware starts in monitor mode: detections are recorded and every request is still served. Free Render services sleep when idle, so the first request after a pause can take up to a minute.

Angular SSR refuses to render for a host it does not recognise. *.onrender.com is allowed; for a custom domain, set NG_ALLOWED_HOSTS (comma-separated) in the service’s environment, or Angular answers 400.

Follow the Express, Fastify or Next.js install, set WEBDECOY_API_KEY in the service’s Environment, and pass it to the middleware as apiKey. The SDK does not read the variable by itself.

Render keeps whatever X-Forwarded-For the client sent and appends to it, so the header arrives as <anything the client wrote>, <client>, <cloudflare>, <render>. The leftmost entry is the client’s choice, which is why the common advice to trust every proxy (trust proxy: true) lets any visitor pick the address you record.

Render serves its services through Cloudflare, which sets CF-Connecting-IP to the real client and rejects a request that tries to supply its own. Use it:

// Any adapter
webdecoy({ apiKey: process.env.WEBDECOY_API_KEY, trustProxy: 'cloudflare' });
// Express's own req.ip (and Angular SSR's Express server): three hops
app.set('trust proxy', 3);

Both were checked against a live service on its onrender.com address, including a request with a forged X-Forwarded-For. On a custom domain, confirm CF-Connecting-IP is present before relying on it. If you put your own proxy in front of Render, count it too, or configure for that proxy instead.

Request any page with the reserved test user agent:

Terminal window
curl -A "WebDecoy-Test/1.0" https://YOUR-SERVICE.onrender.com/

A detection labeled Test appears on the Detections page within a few seconds. Test detections are excluded from stats and billing.

When you have seen what it would block, set mode: 'enforce'. Blocked requests then get a 403; pass onBlocked to answer them your own way.