Back Home
TOC Loading..
Keyframes
References
Github Repo
Webflow Cloneable

Using HonoJS with your reverse proxy

No items found.

This is Article 3 in my Reverse Proxy Series.

That 30-line proxy from the last article? It works.

But it’s a long way off from something you can deem as production-ready.

Why Our Quick Start Version Will Hurt You Eventually

Your current proxy is a single if/else statement. It breaks when:

  • Someone visits the subdomain instead of the main domain
  • You need to hand off the project to a team
  • You want to do some testing
  • SEO gets involved

We're going to fix all of that with Hono.js. A tiny framework that makes routing simpler

Enter Hono.js

Hono simplifies our if-else statements and data retrieval from the request. It's tiny, fast, and makes your code readable.

First you need to run bun i hono in your terminal to install the hono.js packages

Hono saves us from writing an enormous chain of if-else statements.

Instead of:

if (url.pathname.startsWith('/blog')) {
  // blog stuff
} else if (url.pathname.startsWith('/help')) {
  // help stuff
} else {
  // main stuff
}

You get:

app.get('/blog/*', handleBlog)
app.get('/help/*', handleHelp)
app.get('*', handleMain)

A basic example with Hono.js

Make sure Hono is installed in your repo

Replace your current index.js file with the following and run bun wrangler dev, then open the localhost URL (or press b for the shortcut). 

import { Hono } from "hono";

const app = new Hono();

app.get("*", async (c) => {
  const { pathname } = new URL(c.req.url);
  let res = await fetch("https://jamesbattye.dev" + pathname);
  return res;
});

export default app;

Ok nice. We’re exactly where we were a minute ago, but in 11 lines of code instead of 30. Brilliant /s

Adding more routes

Now we’ll add another project. /blog.

This initial approach will be a bit wordy, then we’ll clean it up after

import { Hono } from "hono";

const app = new Hono();

// Make a variable which holds our projects. This will be easy to add to later
const projects = {
  main: "https://jamesbattye.dev",
  blog: "https://webflow.com",
};

// if the request is for the blog page
app.get("/blog", async (c) => {
  const { pathname } = new URL(c.req.url);
  let res = await fetch(projects.blog);
  return res;
});

// if the request is for a subpage of the blog folder
app.get("/blog/*", async (c) => {
  const { pathname } = new URL(c.req.url);
  let res = await fetch(projects.blog + pathname);
  return res;
});

// everything else
app.get("*", async (c) => {
  const { pathname } = new URL(c.req.url);
  let res = await fetch(projects.main + pathname);
  return res;
});

export default app;

Now we’re saying: if it’s the blog page, get the blog home, if it’s a blog subpage get the blog project + the path, otherwise get the main project.

Not bad, but it’s a bit repetitive. Let's group our requests into a helper function to tidy this up.

import { Hono } from "hono";

const app = new Hono();

const projects = {
  main: "https://jamesbattye.dev",
  blog: "https://webflow.com",
};

// A helper function that makes the request for us, so we can keep the code tidy
const proxyTo = (target) => async (c) => {
  // get the url from the request
  const url = new URL(c.req.url);
  const targetUrl = target + url.pathname + url.search;

  // also we'll clean up the fetch request to include more meta data.
  const res = await fetch(targetUrl, {
    method: c.req.method,
    headers: c.req.raw.headers,
    body: c.req.raw.body,
    redirect: "manual",
  });

  return res;
};

// Blog (root + children)
app.get("/blog/", proxyTo(projects.blog));
app.get("/blog/*", proxyTo(projects.blog));

// everything else
app.get("*", proxyTo(projects.main));

export default app;

Now you can run bun wrangler deploy and push your new and improved reverse proxy to your worker!

We’ve not got a pretty decent little proxy running, but it’s still not 100% there yet. We’ve still got to resolve these issues: 

  1. What if someone visits your subdomain?
  2. How can we change the HTML the user receives?
  3. What’s the SEO implications of all this?
  4. How do you store, manage and deliver the code to a client?

More on that soon.

Writings

Reverse Proxy First Steps

In the next ~30 minutes, you'll have two different sites running under one URL.

Webflow Reverse Proxy Overview: What It Is, Why It Matters, and When to Use It

Reverse proxies are the gateway drug to Webflow Enterprise. Almost every enterprise project I’ve been involved in has implemented it in some form.

Building a Webflow to Algolia Sync with Cloudflare Workers

Build an automated sync between Webflow's CMS and Algolia's search service using Cloudflare Workers.

Using Videos Effectively in Webflow (Without Losing Your Mind)

If you’ve ever used Webflow’s native background video component and thought “damn, that looks rough” I'm here for you.

Webflow + Cloudflare reverse proxy. Why and How

As more companies move to Webflow and demand for Webflow Enterprise grows, you’ll see more teams leaning on reverse proxies to solve some of Webflow’s infrastructure limitations.

How (and why) to add keyboard shortcuts to your Webflow site

A small keyboard shortcut can make a marketing site feel faster, more intentional, and “app-like” with almost no extra design or development

Useful GSAP utilities

A practical, code-heavy dive into GSAP’s utility functions—keyframes, pipe, clamp, normalize, and interpolate—and why they’re so much more than just shortcuts for animation math.

Using Functions as Property Values in GSAP (And Why You Probably Should)

GSAP lets you pass _functions_ as property values. I've known this for a while but never really explored it particularly deeply. Over the last couple of weeks I've been testing, experimenting and getting creative with it to deepen my understanding.

Organising JavaScript in Webflow: Exploring Scalable Patterns

Exploring ways to keep JavaScript modular and maintainable in Webflow — from Slater to GitHub to a custom window.functions pattern. A look at what’s worked (and what hasn’t) while building more scalable websites.

Building a Scroll-Based Image Sequencer with GSAP

An exploration in building a scroll-driven image sequence animation using GSAP and HTML5 canvas. Using Avif file compression with the Avif CLI, hosting strategies (Webflow vs AWS), GSAP and the quirks of working with canvas.