Cloudflare Worker Setup

Host your Free Tools on a path-based URL using Cloudflare Workers

How Cloudflare Workers Enable Subfolder Hosting

Cloudflare Workers provide the most robust and easiest way to host your Outrank Free Tools on a subfolder of your main domain. This approach works with any type of website and allows you to serve your SEO tools at paths like example.com/tools instead of a separate subdomain.

This configuration is particularly beneficial for SEO as it keeps all content under your main domain, consolidating your domain authority and making your free tools more discoverable.

Prerequisites

  • A Cloudflare account (free tier works perfectly)
  • Your domain's DNS records managed through Cloudflare
  • Active Outrank Free Tools feature enabled

Setup Instructions

Step 1: Open Cloudflare Workers Dashboard

  1. Log in to your Cloudflare account
  2. Navigate to the Workers Routes section from the left sidebar
Cloudflare Workers dashboard overview

Step 2: Create a New Worker Service

  1. Click the "Manage Workers" button
    Creating a new worker in Cloudflare
  2. Select "Create Application"
    Creating a new worker in Cloudflare
  3. Select "Start with Hello World"
    Creating a new worker in Cloudflare
  4. Give your worker a name (e.g., "free-tools-proxy") or keep it as is
  5. Click "Deploy" to create the worker
    Creating a new worker in Cloudflare
  6. Don't worry about the code yet - we'll update it in the next step

Step 3: Configure the Worker Code

  1. After creating the worker, click "Edit code"
    Creating a new worker in Cloudflare
  2. Delete all existing code in the editor
  3. Copy and paste the following worker script:
export default {
  async fetch(request, env, ctx) {
    const ORIGIN_HOST = "seo-tools-container.onrender.com";   // Render upstream
    const PREFIX = "/tools";                                   // mount path

    const url = new URL(request.url);
    const isPrefixed = url.pathname === PREFIX || url.pathname.startsWith(PREFIX + "/");

    // Normalize /tools/ → /tools
    if (url.pathname === PREFIX + "/") {
      url.pathname = PREFIX;
      return Response.redirect(url.toString(), 301);
    }

    // Not our path? pass through unchanged
    if (!isPrefixed) return fetch(request);

    // Build upstream URL: strip the /tools prefix
    const upstream = new URL(url.toString());
    upstream.hostname = ORIGIN_HOST;
    upstream.pathname = url.pathname.replace(/^\/tools(\/?)/, "/") || "/";

    // Forward request
    const init = {
      method: request.method,
      headers: new Headers(request.headers),
      body: ["GET", "HEAD"].includes(request.method) ? undefined : await request.arrayBuffer(),
      redirect: "manual",
    };
    init.headers.set("X-Forwarded-Host", url.host);
    init.headers.set("X-Forwarded-Proto", url.protocol.replace(":", ""));
    init.headers.set("Host", ORIGIN_HOST);

    let resp = await fetch(upstream.toString(), init);

    // Rewrite upstream redirects to /tools/...
    const loc = resp.headers.get("Location");
    if (loc) {
      const abs = new URL(loc, upstream);
      if (abs.hostname === ORIGIN_HOST) {
        const rewritten = PREFIX + (abs.pathname === "/" ? "" : abs.pathname) + (abs.search || "");
        const r = new Response(null, { status: resp.status, headers: resp.headers });
        r.headers.set("Location", rewritten);
        return r;
      }
    }

    // Cookie scope fix (auth/session under /tools)
    const out = new Response(resp.body, resp);
    const getAll = out.headers.getAll
      ? (h) => out.headers.getAll(h)
      : (h) => (out.headers.get(h) ? [out.headers.get(h)] : []);
    const setCookies = getAll("Set-Cookie");
    if (setCookies.length) {
      out.headers.delete("Set-Cookie");
      for (let c of setCookies) {
        // Domain rewrite: seo-tools-container.onrender.com → user's domain
        c = c.replace(/;\s*Domain=seo-tools-container\.onrender\.com/gi, `; Domain=${url.hostname}`);
        // Ensure cookies are scoped to /tools (avoid site-wide leakage)
        c = c.replace(/;\s*Path=\/(?!tools\b)/i, `; Path=${PREFIX}`);
        if (!/;\s*Path=/i.test(c)) c += `; Path=${PREFIX}`;
        out.headers.append("Set-Cookie", c);
      }
    }

    return out;
  }
};
  1. After updating the configuration, click "Save and Deploy"
Worker code editor with script

Step 4: Configure Worker Routes

Now you need to tell Cloudflare which URLs should trigger your worker.

  1. Open the Worker details page
  2. Navigate to the "Settings" tab from the top navbar
  3. Click on the "+ Add" button in front of "Domains and Routes"
    Adding a new route in Cloudflare
  4. Choose "Route" option in the opened right sidebar
    Creating a new worker in Cloudflare
  5. Type "*.yourdomain.com/tools*" or any other path in the route input field and click on the "Add route" button
    Creating a new worker in Cloudflare

Step 5: Configure Outrank Dashboard Settings

  1. Log in to your Outrank dashboard
  2. Navigate to Free Tools Builder → Settings → Domain tab from the left navigation menu
  3. Select the "Path-Based" radio button (instead of "Subdomain")
  4. In the "Main Domain" field, enter your website domain:
    • Example: example.com
    • Do NOT include https:// or www.
    • Do NOT include trailing slash
  5. In the "Base Path" field, enter your subfolder path:
    • Example: /tools
    • Must start with forward slash (/)
    • Must match the PREFIX in your Cloudflare Worker code
    • Cannot end with a slash
  6. You'll see a preview showing how your tools will be accessible:
    example.com/tools/[tool-slug]
  7. Click "Save Settings" button

Verification

Once all steps are complete, your free tools should be accessible at www.example.com/tools (replace with your actual domain and path).

Test by visiting your configured URL. The tools should load seamlessly as if they were part of your main website.

Troubleshooting

404 Not Found Error

Verify that your worker routes are correctly configured with the asterisk (*) at the end and that you've selected the correct domain zone.

Worker Not Triggering

Check that your DNS is properly configured through Cloudflare (orange cloud icon enabled). Workers only work when traffic is proxied through Cloudflare.

Infinite Redirect Loop

Ensure the ORIGIN_HOST in your worker code exactly matches your Outrank Free Tools URL and that you haven't configured a custom domain in the Outrank Domains section.

CSS or Assets Not Loading

Verify that your worker route is correctly configured with the asterisk wildcard (e.g., example.com/tools*) and that the PREFIX in your worker code matches your route path.

Custom Domain Conflict

If you previously had a custom domain configured in Outrank, remove it from Settings → Domains. Having both custom domain and sub-folder enabled will cause conflicts.

Benefits of Subfolder Hosting

  • SEO Advantage: All content lives under your main domain, consolidating domain authority
  • User Trust: Visitors stay on your branded domain throughout their journey
  • Analytics: Easier tracking with all traffic under one domain
  • SSL Simplicity: No need for additional SSL certificates
  • Flexibility: Works with any website platform or CMS

Let's Try!

Start creating magic today with a free trial!