Elixir makes managing your digital product easier, especially when it’s time to scale. Book a free consult today to learn how it can put you ahead of the competition.
Some applications require the ability to serve multiple domains, which is typically accomplished through the use of subdomains or by hosting multiple distinct sites.
Take YouTube, for instance. They have many subdomains such as music.youtube.com
and studio.youtube.com
, and also different domains like youtube.com
and youtubekids.com
.
While we can’t say for sure how this is implemented by them, in this blog, we will demonstrate how to configure a single Phoenix application to handle multiple domains and subdomains. Fortunately, Phoenix makes the process simple and straightforward.
First, let’s take a look at this example inside the router.ex
file:
scope "/", MyAppWeb do
live "/music", MusicLive
live "/video", VideoLive
end
These are routes that the user could access through the following URLs: myapp.com/music
and myapp.com/video
. But imagine we want to point the user to the MusicLive
page if they access it through the subdomain music.myapp.com
and to the VideoLive
when video.myapp.com
. We could also have a subdomain for all admin
content.
Here’s an example of how to define routes grouped together by a single subdomain.
# partial host match - match subdomain `music.`, i.e., matches `music.myapp.com`
scope "/", MyAppWeb, host: "music." do
live "/", MusicLive
end
# partial host match - match subdomain `video.`, i.e., matches `video.myapp.com`
scope "/", MyAppWeb, host: "video." do
live "/", VideoLive
end
# partial host match - match subdomain `admin.`, i.e., matches `admin.myapp.com`
scope "/", MyAppWeb, host: "admin." do
live "/", AdminLive, :home
live "/settings", AdminSettingsLive # admin.myapp.com/settings
end
This uses the scope/4 macro with the host option to group routes under the music.
and video.
subdomains. The live/4 macro then defines a path and the name of the LiveView to render the page.
We can also define routes grouped under one or more completely different hosts if we include the top-level domain:
# full host match
scope "/", MyAppWeb, host: "my-example.org" do
live "/", HomeLive, :new
end
The host option also accepts a list instead of a string to match multiple different hosts or subdomains.
scope "/", MyAppWeb, host: ["guest.", "example.com", "example2.com"] do
live "/", AnotherHomeLive, :new
end
You also need to pass the :check_origin
option when configuring your endpoint explicitly outlining which origins are allowed, otherwise you will end up getting a Phoenix.Socket transport error.
Edit config/runtime.exs
and edit the following config inside config :my_app, MyAppWeb.Endpoint, ...
:
config :my_app, MyAppWeb.Endpoint,
check_origin: [
"https://myapp.com/",
"https://example.com",
"https://example2.com",
"https://my-example.org"
],
# ... Truncated for demonstration purposes