Dynamic routes or mapping URL aliases to internal routes with Phoenix LiveView

Hello Elixir/Phoenix Forum

Although I’m not planning on doing this anytime soon, I’ve been thinking about this topic for a while and I thought maybe the forum wants to join this thought process. :wink:

As far as I can see, there’s no way with Phoenix LiveView to build a system with dynamic routes (right?). Let’s assume we’d like to build a head for a headless CMS with LiveView. I see a way to serve “pages” defined in the CMS from a single route that looks something like /page/:id. The LiveView would fetch the data from the CMS API and render the contents.

Now usually for SEO reasons, in your CMS you’d like to give each page a “nice” URL path - let’s call them “URL aliases”. Obviously these routes would be defined dynamically, i.e. during runtime. But in Phoenix, routes are defined at compile time. There’s no way to make Phoenix add routes during compile time. Now I think that’s exactly how it should be and it’s not even necessary to dynamically add routes to Phoenix. Internally we can still use the compile-time defined URL /page/:id for the routing. But in order to serve the URL aliases, we would need to mainain a map %{alias_url => id} and a way to translate URL aliases to internal routes right before routing.

While I can see doing that for Non-LiveView Phoenix using a Plug, I don’t see a way doing this in LiveView. I think you’d have to add some translation hook mechanism into Phoenix.Router.route_info/4 or Phoenix.LiveView.Route.live_link_info/3. Or maybe I’m missing something…

Happy to read your thoughts…

1 Like

I don’t understand, why is /page/:id not a nice URL? :id can be a meaningful string too.
If you insist on having one level of route going directly to each page, eg: /:id then why bother with the router since you don’t use it. You can just write a plug.

You could always store the alias of the page in the db, and have /page/:id issue a redirect to a catch-all /page/:id/*alias route.

Oh boy, I guess I forgot about the catch-all routes. Thanks for reminding me! :slight_smile:
I would not have to store aliases as they are retrieved from the headless CMS. I can simply keep the mapping in process memory (e.g. a GenServer) and refresh them from time to time or upon request. Then in mount of my LiveView I can check if the URL actually matches an existing alias and otherwise render a NotFound page.

1 Like