# Rails `allowed_redirect_hosts` Finally Fixed Subdomain Redirects

## The Problem Everyone Has

You're building a multi-tenant SaaS with subdomains. User logs in at `www.myapp.com`, you redirect them to `tenant1.myapp.com`. Rails throws this at you:

```plaintext
ActionController::Redirecting::UnsafeRedirectError:
Unsafe redirect to "http://tenant1.myapp.com"
```

Rails 7.0+ blocks cross-host redirects by default (good security!), but it treats your own subdomains as "external" hosts.

So what do you do?

## What We've All Been Doing (It's Bad)

**Option 1:** Sprinkle `allow_other_host: true` everywhere

```ruby
redirect_to root_url(subdomain: account.subdomain), allow_other_host: true
```

Problem: This allows redirects to **any** host, not just your subdomains. You're basically disabling the security feature you wanted.

**Option 2:** Monkey-patch Rails core

```ruby
# config/initializers/url_host_allowed_patch.rb
module ActionController::Redirecting
  def _url_host_allowed?(url)
    # ... custom logic to check same base domain ...
  end
end
```

This is what we were doing. It works, but you're overriding Rails internals. It's fragile and breaks with updates.

## The Fix (It's Stupidly Simple)

Rails merged [PR #55420](https://github.com/rails/rails/pull/55420) in July 2025. Add this to your config:

```ruby
# config/application.rb
config.action_controller.allowed_redirect_hosts = [".myapp.com"]
```

That's it. The dot prefix matches all subdomains: `www.myapp.com`, `tenant1.myapp.com`, `api.myapp.com`.

Now your redirects just work:

```ruby
redirect_to root_url(subdomain: account.subdomain)  # Works!
```

No `allow_other_host: true`. No monkey-patches.

## Pattern Matching You Get

The feature uses `ActionDispatch::HostAuthorization::Permissions` under the hood, which supports:

```ruby
config.action_controller.allowed_redirect_hosts = [
  "api.myapp.com",           # Exact match
  ".myapp.com",              # All subdomains
  /.*\.staging\.myapp\.com/, # Regex patterns
  IPAddr.new("192.168.0.0/24") # IP ranges
]
```

For most multi-tenant apps, you just need the dot prefix.

I hope this helps, it's a brand new feature with almost no documentation yet, so I figured I'd share what I learned.
