Hot-link protection

Block other websites from linking to your content. This is useful for protecting images.

Last updated Apr 23, 2026 If you want to get started quickly, click on the button below.

Deploy to Cloudflare

This creates a repository in your GitHub account and deploys the application to Cloudflare Workers.

export default {
    async fetch(request) {
        const HOMEPAGE_URL = "https://tutorial.cloudflareworkers.com/";
        const PROTECTED_TYPE = "image/";

        // Fetch the original request
        const response = await fetch(request);

        // If it's an image, engage hotlink protection based on the
        // Referer header.
        const referer = request.headers.get("Referer");
        const contentType = response.headers.get("Content-Type") || "";

        if (referer && contentType.startsWith(PROTECTED_TYPE)) {
            // If the hostnames don't match, it's a hotlink
            if (new URL(referer).hostname !== new URL(request.url).hostname) {
                // Redirect the user to your website
                return Response.redirect(HOMEPAGE_URL, 302);
            }
        }

        // Everything is fine, return the response normally.
        return response;
    },
};
export default {
    async fetch(request): Promise<Response> {
        const HOMEPAGE_URL = "https://tutorial.cloudflareworkers.com/";
        const PROTECTED_TYPE = "image/";

        // Fetch the original request
        const response = await fetch(request);

        // If it's an image, engage hotlink protection based on the
        // Referer header.
        const referer = request.headers.get("Referer");
        const contentType = response.headers.get("Content-Type") || "";

        if (referer && contentType.startsWith(PROTECTED_TYPE)) {
            // If the hostnames don't match, it's a hotlink
            if (new URL(referer).hostname !== new URL(request.url).hostname) {
                // Redirect the user to your website
                return Response.redirect(HOMEPAGE_URL, 302);
            }
        }

        // Everything is fine, return the response normally.
        return response;
    },
} satisfies ExportedHandler;
from workers import WorkerEntrypoint, Response, fetch
from urllib.parse import urlparse

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        homepage_url = "https://tutorial.cloudflareworkers.com/"
        protected_type = "image/"

        # Fetch the original request
        response = await fetch(request)

        # If it's an image, engage hotlink protection based on the referer header
        referer = request.headers["Referer"]
        content_type = response.headers["Content-Type"] or ""

        if referer and content_type.startswith(protected_type):
            # If the hostnames don't match, it's a hotlink
            if urlparse(referer).hostname != urlparse(request.url).hostname:
                # Redirect the user to your website
                return Response.redirect(homepage_url, 302)

        # Everything is fine, return the response normally
        return response
import { Hono } from 'hono';

const app = new Hono();

// Middleware for hot-link protection
app.use('*', async (c, next) => {
  const HOMEPAGE_URL = "https://tutorial.cloudflareworkers.com/";
  const PROTECTED_TYPE = "image/";

  // Continue to the next handler to get the response
  await next();

  // If we have a response, check for hotlinking
  if (c.res) {
    // If it's an image, engage hotlink protection based on the Referer header
    const referer = c.req.header("Referer");
    const contentType = c.res.headers.get("Content-Type") || "";

    if (referer && contentType.startsWith(PROTECTED_TYPE)) {
      // If the hostnames don't match, it's a hotlink
      if (new URL(referer).hostname !== new URL(c.req.url).hostname) {
        // Redirect the user to your website
        c.res = c.redirect(HOMEPAGE_URL, 302);
      }
    }
  }
});

// Default route handler that passes through the request to the origin
app.all('*', async (c) => {
  // Fetch the original request
  return fetch(c.req.raw);
});

export default app;

Was this helpful?

YesNo

On this page

Hot-link protection - 图2Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workers/examples/hot-link-protection/#page","headline":"Hot-link protection","description":"Block other websites from linking to your content. This is useful for protecting images.","url":"https://developers.cloudflare.com/workers/examples/hot-link-protection/","inLanguage":"en","image":"https://developers.cloudflare.com/workers/examples/hot-link-protection/og.png?v=07917c743c5c9752","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Security","Headers","JavaScript","TypeScript","Python"]}


description: Set up custom domain for Images using a Worker or serve images using a prefix path and Cloudflare registered domain. title: Custom Domain with Images image: https://developers.cloudflare.com/workers/examples/images-workers/og.png?v=26e142834ac846a1


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt
Use this file to discover all available pages before exploring further.