In short, the “match any subdomain” clause in the router is to just not specify the :host
option. The subdomain itself will be available in conn.host
so you could pull it out in a plug and do whatever you need to do with it.
If you want different routes depending on the presence of a subdomain, that’s a little different. There are a few discussions around here about it but I’m having trouble finding the ones I found helpful. I do have the (abandon) project I was using it in, though. In short you want to make a plug, check if there is a subdomain then delegate to another router. Maybe there is an easier way at this point? In any event, here is my code:
# lib/my_app_web/subdomain_router.ex
defmodule MyAppWeb.SubdomainRouter do
# This is just a regular router but with subdomain specific routes
end
# lib/my_app_web/plugs/subdomain_plug
defmodule MyAppWeb.SubdomainPlug do
import Plug.Conn
def init(opts), do: opts
def call(conn, router) do
case get_subdomain(conn.host) do
subdomain when byte_size(subdomain) > 0 ->
conn
|> fetch_session()
|> put_session(:subdomain, subdomain)
|> router.call(router.init({}))
|> halt()
_ -> conn
end
end
defp get_subdomain(host) do
root_host = MyAppWeb.Endpoint.config(:url)[:host]
if root_host == "localhost" do
# This handles tests
""
else
String.replace(host, ~r/.?#{root_host}/, "")
end
end
end
# BOTTOM of lib/my_app_web/endpoint.ex
defmodule MyAppWeb.Endpoint do
# ...
plug MyAppWeb.SubdomainPlug, MyAppWeb.SubdomainRouter
plug MyAppWeb.Router
end
Maybe it’s easier at this point? I did always find this to be a little bit of a pain point in Phoenix. Actually, have you tried simply host: "."
at all? I can’t remember if that’s a thing or not and don’t feel like spinning up that app