Reverse Proxy with Netlify Edge Functions

Happy holidays, Netlify team :smiling_face:! Hope you are all doing well.

I have what feels like a silly question haha, regarding reverse proxy configurations through an edge function.

I have a Webflow site hosted at a subdomain - example.domain.com, for example (pun intended).

I am trying to have the website reverse proxied so users visit the site at domain.com/example instead. Now, that is relatively easy to do by setting a redirect in the Netlify.toml file.

This is where I got stuck and why I have a feeling I may need an edge function instead of going with the traditional redirect route. I would like the subdomain to do a 301 redirect to the subdirectory, which Webflow supports. But, I learned the hard way that causes a redirect loop and thus a Too Many Redirects error. I had a feeling that would happen but hoped it would somehow be fine haha.

I guess my question is, how exactly would I go about approaching this? I have used an edge function before to rewrite and replace standalone elements on a page, but this feels like I need to rewrite an entire page.

To give you a better idea of what exactly I mean, I am trying to do essentially what this website here has also done. You’ll see they’re doing a 301 redirect to a subdirectory and then using Cloudflare to serve content from the subdomain. What I am most confused by is, from my understanding, Cloudflare Service Workers are identical to Netlify Edge Functions in the sense that they both run on the edge. The reason I’m confused is their source code is rewritten as well, which I thought functions that run on the edge couldn’t do. Otherwise, they wouldn’t be as fast as they are.

Hiya @nocodebenny and thanks for the polite and thoughtful question! Hope your holidays have been swell too - and, I hope that the swelling doesn’t go down for some time yet :wink:

Dad jokes aside, you most likely wouldn’t want to reverse proxy in an edge function. You can absolutely make outgoing network connections and the time awaiting response generally isn’t included in this limit, but the 50ms max CPU runtime relies on you doing whatever else you’ll do, very quickly, and if your remote service (us, webflow, something else) returns data somewhat slowly…I think we could run out of that 50ms processing data bit by bit before the transmission is completed. So I would suggest redirecting or modifying HTML in an edge function, and doing potentially-long-running network operations in a lambda or using our redirects.

I wonder if you could share your existing config in more detail so we could understand what is failing with it? I’m hoping for something like this:

  1. I host xyz.com on Netlify
  2. I host subdomain.xyz.com on webflow
  3. visit uses browser to go to subdomain.xyz.com on webflow
  4. I want webflow to instead place the visitor, with URL updated in browser, at .xyz Domain Names | Join Generation XYZ
  5. which is served by the netlify site, and as you can see, there is a file at /subdomain on the xyz.com site, so I don’t understand the redirect loop

We don’t know anything about how webflow works and won’t be able to become experts, but including your actual netlify sites, and hostnames, so we can see your configuration here, and in DNS, will make our analysis much more directly helpful, and waste less of our time guessing at a theoretical setup, if you wanted to give us a real holiday present as we try to help you troubleshoot :slight_smile:

Hey @fool!

Thank you SO much for responding so quickly, especially amidst the holiday season. Hahaha I think I’ll be fully recovered from the holidays by the new year.

I am so sorry for not providing the full context from the start. I was going to but didn’t want my initial message to be a mile long haha.

Here is my current config:

  • I have the domain eviltwins.studio connected to Netlify, with a live site under that at the moment.

  • I have the subdomain ‘experiments.eviltwins.studio’ connected to Webflow, which currently has this wildcard 301 redirect: /(.*) -> https://eviltwins.studio/experiments/%1.

  • I then have this in my Netlify.toml file for the eviltwins.studio domain:

[[redirects]]    
    from = "/experiments/*"
    to = "https://experiments.eviltwins.studio/:splat"
    status = 200
    force = true

So I won’t have anything sitting at that subdirectory, but instead, have it reverse proxy to my Webflow site. Which, of course, causes the redirect loop (technology, eh?).

Now, as for why I am putting myself through this hahaha.

I am looking to essentially build a “layer” on top of Webflow using Netlify’s incredible architecture. My primary objective at the moment is to use Netlify to have serverside auth for Webflow sites with an edge function. So without having the subdomain redirect, a user could easily bypass my configuration by visiting the site on the subdomain since the edge function wouldn’t run on it, obviously.

For further clarity, Webflow does support setting a <base> tag and href prefix. So all the internal links on the site will already be adjusted accordingly. It is just this redirect I am trying to tackle.

This journey has led me to wonder how this crew did it heregreenhouse.finsweet.com”, but with Cloudflare. Looking at the network tab, you’ll see they are doing a 301 redirect to the subdirectory. But then reverse proxying the subdomain from the subdirectory. If they hadn’t cracked it, then I wouldn’t believe someone if they told me it is possible haha. Because from my (very) limited understanding, something like this shouldn’t be possible.

I think you can achieve the example you’ve shared here:

using Netlify Redirects as well. Here’s how:

Connect eviltwins.studio and experiments.eviltwins.studio both to a single Netlify site. In that Netlify site, add the following redirects:

[[redirects]]
  force = true 
  from = "https://experiments.eviltwins.studio/*"
  to = "https://eviltwins.studio/experiments/:splat"
  status = 301
[[redirects]]
  force = true 
  from = "/experiments/*"
  to = "your-webflow-url/:splat"
  status = 200

This way, when someone hits experiments.eviltwins.studio, they will be (301) redirected to https://eviltwins.studio/experiments/ and then, the second rule will take care of the proxy to Webflow. You can then remove the 301 from Webflow.

Not sure if I’ve missed something, in which case, apologies and feel free to point out.

Hey @hrishikesh!

I’m afraid that wouldn’t work :frowning:

As the subdomain, experiments.eviltwins.studio, is what I have connected to Webflow. So it can’t be pointed to Webflow and Netlify.

Yes, which is why I asked to point it to Netlify (which means, removed it from Webflow). You can definitely add some other domain there, as from your setup, it doesn’t look like that domain is going to be known to anyone.

Ah, I wish it was that easy haha.

But, Webflow doesn’t make it easy :sweat_smile:

In the code for every Webflow site, they add the domain for your site as an attribute to the HTML tag.

Like this: data-wf-domain=greenhouse.finsweet.com.

view-source:https://greenhouse.finsweet.com

So anyone that inspects the page source would be able to see the subdomain for the site, and then access it that way.

Well, I believe you can use Edge Functions for that part, to remove or modify the domain from that response, only if you think it’s going to be a problem big enough if people notice that domain.

Hmm, yeah that is a good point. Things can only be so secure, there will always be loopholes, etc. that people can find if motivated enough.

Hey @fool and @hrishikesh!

I hope you are both doing well.

Sorry for re-opening a (very) old thread. I figured out a solution for this and thought I would share it here in case you have any other customers in the future who run into something similar.

This is the Javascript that the customer would add to a Cloudflare Worker. Essentially what it does is whenever a site visitor hits the customer’s subdomain (i.e. blog.example.com), it will check if the request is from Netlify or a human. It does this by checking for the x-nf-site-id request header, which as you both obviously know, Netlify sets in a redirect.

With this configuration, a user is able to have their main website / root domain (i.e. example.com) hosted by Netlify while also adding any other sites under it via a reverse proxy. For example, a blog they may have hosted on Ghost, Webflow, WordPress, etc.

There are two benefits to this configuration. The first being - SEO; by 301 redirecting your subdomain (blog.example.com) to your subdirectory (example.com/blog), search engines will only crawl and rank the latter one. The second benefit is users will be able to use Netlify Edge Functions and not have to worry about users bypassing them by accessing their blog through the subdomain instead.

const base = "YOUR-BASE-URL" // i.e. https://example.com/blog

const statusCode = 301

async function handleRequest(request) {

    const url = new URL(request.url)

    const isNetlifyReq = request.headers.get('x-nf-site-id'); // Check If Request Is From Netlify

    if (!isNetlifyReq) { // If Not Netlify Request, Redirect To Base URL

        const { pathname, search, hash } = url
    
        let destinationURL = base + pathname + search + hash;
    
        destinationURL = destinationURL.endsWith('/') ? destinationURL.slice(0, -1) : destinationURL; // Remove Trailing Slash (If Exists)
    
        return Response.redirect(destinationURL, statusCode)
    
    } else {

    // If Netlify Request, Return Response

    const response = await fetch(url);

    return response;

    }

}

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request));
  });

Hi @nocodebenny :wave:t6: , thanks so much for coming back and sharing your solution. This will definitely help other users who stumble on this thread.