Can't seem to be able to exclude root from a redirect rule

Hello everyone,

I’m having some trouble setting up redirects on my Netlify site and I was hoping someone could help me out.

Here’s what I’m trying to achieve:

  1. When a user visits https://customdomain.com, I want to serve the content from https://maindomain.com/custompage without changing the URL in the browser.
  2. For all other paths on customdomain.com, I want to redirect to the corresponding paths on maindomain.com.

To accomplish this, I added the following rules to my netlify.toml file:

[[redirects]]
  from = "https://customdomain.com"
  to = "https://maindomain.com/custompage"
  status = 200
  force = true

This helped me when a user visits https://customdomain.com I served the content from https://maindomain.com/custompage without changing the URL in the browser. Perfect. However, for all other paths existing on maindomain.com (e.g. maindomain.com/contact), I was having them also existing under customdomain.com (e.g. customdomain.com/contact) and that wasn’t intended. Intention is for all paths like customdomain.com/contact to redirect fully including url change to maindomain.com/contact.

I then tried adding the following rules to my netlify.toml file:

[[redirects]]
  from = "https://customdomain.com"
  to = "https://maindomain.com/custompage"
  status = 200
  force = true

[[redirects]]
  from = "https://customdomain.com/*"
  to = "https://maindomain.com/:splat"
  status = 301
  force = true

However, this configuration didn’t work as expected. The proxy redirect for https://customdomain.com worked, but the URL in the browser changed to https://maindomain.com/custompage. Also, the wildcard redirect didn’t seem to work at all.

I’ve also tried changing the order, but still no success:

[[redirects]]
  from = "https://customdomain.com/*"  
  to = "https://maindomain.com/:splat"   
  status = 301                            

[[redirects]]
  from = "https://customdomain.com"     
  to = "https://maindomain.com/custompage  
  status = 200                             
  force = true

I then tried changing force = true to force = false in the 301 rule, like this:

[[redirects]]
  from = "https://customdomain.com/*"
  to = "https://maindomain.com/:splat"
  status = 301
  force = false

But this didn’t solve the issue either. The URL still changed when visiting https://customdomain.com, and the wildcard redirect still didn’t work.

I’ve checked the Netlify documentation on redirects and followed the instructions there, but I’m still stuck. I’m not sure what I’m doing wrong.

Does anyone have any suggestions on how to fix this? Any help would be greatly appreciated!

Thank you in advance for your assistance.

My site is https://localization-hq.netlify.app

Bump, anyone with any pointers?

The first config should work correctly. Your current config doesn’t have force in it, so I cannot test.

Hi @hrishikesh , many thanks for sharing a pointer. Which config do you say should work correctly?

Because none of them did.

Would you like me to put force = true on the below?

[[redirects]]
  from = "https://customdomain.com/*"  
  to = "https://maindomain.com/:splat"   
  status = 301

Doing it got me:

[[redirects]]
  from = "https://customdomain.com"     
  to = "https://maindomain.com/tt"  
  status = 200                             
  force = true   
                  
[[redirects]]
  from = "https://customdomain.com/*"  
  to = "https://maindomain.com/:splat"   
  status = 301
  force = true

Sadly, force = true made no difference,

With this setup, c is redirecting to https://maindomain.com/tt also in the URL (not intended) as I want the URL to stay as customdomain.com

As a reminder intention is to achieve both the below:

Many thanks in advance for pointers or what I’m doing wrong here.

I’d really recommend switching the first redirect rule to /tt instead of the complete domain. I noticed you mentioned in the other thread that the docs are wrong, but I’m pretty sure the docs are correct. The issue you’re describing is (almost) expected behaviour when using a custom domain in the destination.

And yes, force = true would be required in the second redirect.

Thanks, Following your suggestion I’ve now tried:

[[redirects]]
  from = "https://customdomain.com"     
  to = "/tt"  
  status = 200                             
  force = true   
                  
[[redirects]]
  from = "https://customdomain.com/*"  
  to = "https://maindomain.com/:splat"   
  status = 301
  force = true

This now led to customdomain.com to stop resolving the content of maindomain.com/tt at all (it resolves the content of maindomain.com) and furthermore I got CORS issues, so the css is now broken.

Any idea of what might be going on?

You’ve literally added maindomain and custom domain as your redirects instead of replacing them with the correct values.

Apologies for that. Too many trials and copy pastes here led to that :slight_smile:

Results for:

[[redirects]]
  from = "https://customdomain.com"     
  to = "/tt"  
  status = 200                             
  force = true   
                  
[[redirects]]
  from = "https://customdomain.com/*"  
  to = "https://maindomain.com/:splat"   
  status = 301
  force = true

with correct values applied.

  1. NOT OK: With this setup, customdomain.com is redirecting to maindomain.com/tt also in the URL (not intended) as I want the URL to stay as customdomain.com (page needs to be refreshed 2-3x times though, at first it resolves maindomain.com content under customdomain.com URL)
  2. OK: All other paths in customdomain.com/ redirect to maindomain.com/), also in the URL, so customdomain.com/contact redirects also in the URL to maindomain.com/contact. So this works

It seems that: the first redirect instruction is ignoring the 200 status instruction and reading it as 301, then second redirect instruction is being read correctly

I see. Could you try to add a /, so it’s like:

  from = "https://customdomain.com/"

In the database, I’m seeing path being "" and it’s not matching any redirects (we’re returning a 200) for the homepage on the secondary domain.

Hi again, just tried:

from = "https://customdomain.com/"

results:

  1. NOT OK: With this setup, customdomain.com is not resolving at all the content of maindomain.com/tt and the URL stays as customdomain.com
  2. OK: All other paths in customdomain.com/ redirect to maindomain.com/), also in the URL, so customdomain.com/contact redirects also in the URL to maindomain.com/contact. So this part works

I think I’ve narrowed this down to some caching issues. Will report after trying to reproduce this. The redirect itself is correct and works (tested on a separate site).

I have managed to reproduce this issue. During my testing, I realised, this is not related to caching, but instead how we’re handling routing with Functions. I’ve passed this to the devs and will keep you posted.

Super @hrishikesh ! Happy to hear something/a snag may have been found!
Looking forward to updates.
Thanks a lot again

I believe this is the current expected behaviour. You’d likely have to handle the rewrite from within Next.js middleware or a custom Netlify Edge Function.

Hi @hrishikesh thanks for reverting. Sorry, what is the expected behaviour? Right now we have one redirect rule cancelling the other?

I can’t understand this being the designed behaviour.

I’m either having no resolution of maindomain.com/tt content and customdomain.com persisting as URL or maindomain.com/tt content resolving but then customdomain.com does not persist in the URL.

The expected behaviour is that when you proxy, the Function receives the original request URL, not the proxied one. I had raised this before as well, but forgot about that thread. Then I remembered and noticed this is an exact same case.

The situation is:

  • Request to /
  • Gets proxied to /tt
  • /tt is handled by Next.js Server Handler Function
  • The expected behaviour is to pass / (original URL) to the Function as opposed to the new URL (/tt)
  • Thus, Next.js server sees the URL as / instead of /tt and sends the data for /.

You can reproduce this with any setup, such as a simpler reproduction that I created for this: github.com/hrishikesh-k/f-126343 which does not involve Next.js, but simply uses Functions natively. The 2 domains attached to the site are: https://f-126343-1.tejalshinde.com/ and https://f-126343-2.tejalshinde.com/.

Making a request to https://f-126343-2.tejalshinde.com/ will show home instead of page-1.