---
title: Rewrite links · Cloudflare Workers docs
description: Rewrite URL links in HTML using the HTMLRewriter. This is useful for JAMstack websites.
lastUpdated: 2025-04-28T14:11:18.000Z
source_url:
  html: https://patricia-pcx17119-l7-overrides.preview.developers.cloudflare.com/workers/examples/rewrite-links/index.md
  md: https://patricia-pcx17119-l7-overrides.preview.developers.cloudflare.com/workers/examples/rewrite-links/
---

If you want to get started quickly, click on the button below.

[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/docs-examples/tree/main/workers/rewrite-links)

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

* JavaScript

  ```js
  export default {
    async fetch(request) {
      const OLD_URL = "developer.mozilla.org";
      const NEW_URL = "mynewdomain.com";


      class AttributeRewriter {
        constructor(attributeName) {
          this.attributeName = attributeName;
        }
        element(element) {
          const attribute = element.getAttribute(this.attributeName);
          if (attribute) {
            element.setAttribute(
              this.attributeName,
              attribute.replace(OLD_URL, NEW_URL),
            );
          }
        }
      }


      const rewriter = new HTMLRewriter()
        .on("a", new AttributeRewriter("href"))
        .on("img", new AttributeRewriter("src"));


      const res = await fetch(request);
      const contentType = res.headers.get("Content-Type");


      // If the response is HTML, it can be transformed with
      // HTMLRewriter -- otherwise, it should pass through
      if (contentType.startsWith("text/html")) {
        return rewriter.transform(res);
      } else {
        return res;
      }
    },
  };
  ```

* TypeScript

  ```ts
  export default {
    async fetch(request): Promise<Response> {
      const OLD_URL = "developer.mozilla.org";
      const NEW_URL = "mynewdomain.com";


      class AttributeRewriter {
        constructor(attributeName) {
          this.attributeName = attributeName;
        }
        element(element) {
          const attribute = element.getAttribute(this.attributeName);
          if (attribute) {
            element.setAttribute(
              this.attributeName,
              attribute.replace(OLD_URL, NEW_URL),
            );
          }
        }
      }


      const rewriter = new HTMLRewriter()
        .on("a", new AttributeRewriter("href"))
        .on("img", new AttributeRewriter("src"));


      const res = await fetch(request);
      const contentType = res.headers.get("Content-Type");


      // If the response is HTML, it can be transformed with
      // HTMLRewriter -- otherwise, it should pass through
      if (contentType.startsWith("text/html")) {
        return rewriter.transform(res);
      } else {
        return res;
      }
    },
  } satisfies ExportedHandler;
  ```

* Python

  ```py
  from pyodide.ffi import create_proxy
  from js import HTMLRewriter, fetch


  async def on_fetch(request):
      old_url = "developer.mozilla.org"
      new_url = "mynewdomain.com"


      class AttributeRewriter:
          def __init__(self, attr_name):
              self.attr_name = attr_name
          def element(self, element):
              attr = element.getAttribute(self.attr_name)
              if attr:
                  element.setAttribute(self.attr_name, attr.replace(old_url, new_url))


      href = create_proxy(AttributeRewriter("href"))
      src = create_proxy(AttributeRewriter("src"))
      rewriter = HTMLRewriter.new().on("a", href).on("img", src)
      res = await fetch(request)
      content_type = res.headers["Content-Type"]


      # If the response is HTML, it can be transformed with
      # HTMLRewriter -- otherwise, it should pass through
      if content_type.startswith("text/html"):
          return rewriter.transform(res)
      return res
  ```

* Hono

  ```ts
  import { Hono } from 'hono';
  import { html } from 'hono/html';


  const app = new Hono();


  app.get('*', async (c) => {
    const OLD_URL = "developer.mozilla.org";
    const NEW_URL = "mynewdomain.com";


    class AttributeRewriter {
      attributeName: string;


      constructor(attributeName: string) {
        this.attributeName = attributeName;
      }


      element(element: Element) {
        const attribute = element.getAttribute(this.attributeName);
        if (attribute) {
          element.setAttribute(
            this.attributeName,
            attribute.replace(OLD_URL, NEW_URL)
          );
        }
      }
    }


    // Make a fetch request using the original request
    const res = await fetch(c.req.raw);
    const contentType = res.headers.get("Content-Type") || "";


    // If the response is HTML, transform it with HTMLRewriter
    if (contentType.startsWith("text/html")) {
      const rewriter = new HTMLRewriter()
        .on("a", new AttributeRewriter("href"))
        .on("img", new AttributeRewriter("src"));


      return new Response(rewriter.transform(res).body, {
        headers: res.headers
      });
    } else {
      // Pass through the response as is
      return res;
    }
  });


  export default app;
  ```
