Using :host parameter for matching routes

Hi,

My use case: I allow CNAMEs in my app, allowing users to bring their own hostname for public pages.

My idea then was to use host in all scopes for my native routes and a scope that matches any host for routes that may have custom hostnames.

  scope "/", MyWeb, host: "my.example.com" do
    pipe_through :public_browser

    get "/", PageController, :index
  end

  scope "/", MyWeb, as: :hostname do
    pipe_through :public_browser_custom_url

    get "/*segments", CustomController, :index
  end

This kind-of-works but it makes local development hard due to the static hostname matching. I first had host: Application.get_env(:my, MyWeb.Endpoint)[:url][:host] but the :host parameter only takes strings. (as an aside, it took a while to figure that out because Phoenix does not complain that you pass a function and the route just doesn’t match – but the documentation mentions that it’s string only, so I can’t complain :slight_smile: )

Any ideas how to make the :host parameter dynamic or is that not possible with the current implementation?

You can match prefixes by setting a :host option that ends with ..

scope "/", MyWeb, host: "my.example." do
  ...
end

scope "/", MyWeb, as: :hostname do
  ...
end

will match my.example.com and my.example.local for non-custom hostname routes. Anything else falls through to the second scope.

4 Likes

That works :slight_smile: I still need to setup a domain locally that’s not the default localhost but from there on it should work just fine. Thanks!