Hologram router - possible to have a route like /:username at the root? (+ some misc feedback)

As someone who had a lot of initial interest in Hologram, I’m only just diving into it now. It’s feeling magical being able to write Elixir in the template and have it update on the client. I’m still getting used to it (in a good way).

Regarding routes: Since you specify routes right in a Page itself, it doesn’t appear possible to have a route like /:username at the root (and of course I’ve tried and it doesn’t work). I’m assuming this is a deliberate design decision to enforce a static fragment at the root? Are there any plans to support this? If not it would be cool if the docs could be updated to point this out explicitly (even though it is kind of obvious).

Regarding random feedback: I’m again ass-u-me’ing, that @impl trues are left out of examples on purpose, maybe to appeal to non-Elixir folk? I find @impl true incredibly useful (even when I know the API inside out) however, I can’t use it effectively since action and command are not part of the page behaviour. More than anything curious about the design descision around this. I haven’t studied the code in great detail to find out why it’s done like so really more just curious and wondering if this could be fudged somehow? Otherwise I can get used to just not using @impl true.

Ok that’s all for now. Thanks for all your work, Bart!

5 Likes

Oops, it turns out I had an entirely different issue and I can indeed define a route "/:username" route and, if I create another page with route "/static", it works! Magic!

Ok, so forgive me but it turns out this thread is only about the @impl true feedback.

I will say the error I got was super ambiguous. I had <Link to={MyPage}> which failed when I added params (because I wasn’t passing the params prop to Link). The stack trace didn’t contain any app traces so this was hard to debug and had to ask ye olde AI machine for help.

2 Likes

About time, @sodapopcan! :wink: You’ve been sponsoring the project long enough - glad you’re finally getting your hands dirty. And happy to hear it’s feeling magical.

Let me address your points one by one:

Routing

Hologram’s router uses a search tree rather than ordered routing (like Phoenix/Rails). Static segments are always prioritized over parameterized ones automatically - so /users will always match before /:username, regardless of the order pages are defined. This eliminates a whole class of “route shadowing” bugs that are common in ordered routers where adding a route in the wrong position silently breaks another. The tradeoff is you can’t have two ambiguous parameterized routes at the same level (e.g. /:username and /:post_slug), but that’s a design smell in any framework - the fix is always to give them distinct prefixes.

The Link error

Hologram should be raising an ArgumentError with the message: page "YourPageModule" expects "param_name" param when you use <Link to={MyPage}> for a page that requires params. What error did you actually get? I’d like to make sure the error reporting is working correctly here.

@impl true

Good catch. Hologram does have Component and Page behaviours, but currently they only define callbacks for init/3 and template/0 - not for action/3 and command/3. Adding those as optional callbacks would let you use something like @impl Component on your action/command handlers. Could you open a short enhancement issue on GitHub for this?

As for the docs - I’ll likely keep examples without @impl true, same as LiveView does. Docs should be minimal and focused on the concept being taught. But with the callbacks in place, you’ll be able to use @impl true in your own code.

2 Likes

Routing

This is how I assumed it worked and that’s very cool! It would be great to add this to docs. I’m happy to open a PR. I’m freshly unemployed and have time for these things currently :grin:

The tradeoff is you can’t have two ambiguous parameterized routes at the same level (e.g. /:username and /:post_slug),

I have never even considered doing this over the past 15 years I’ve been using framework routers so no complaints from me there, lol.

The Link Error

This is indeed the error I got, but it was very confusing as a n00b. How I got there was that I used the tutorial boilerplate which includes the line:

<Link to={Blog.HomePage}>Home</Link>

I later added a param to Blog.HomePage which resulted in that error. Since the error doesn’t mention anything about the Link component and the stacktrace contains no app code, it didn’t occur to me that this is what the problem was, I thought I had done something wrong with either the route or param macros. Now that I know it’s not a big deal but at the very least it’s a beginner trap for some! Perhaps the error message could be improved a little? Like introspect if the Link component is used? Again, lots of time, happy to look :grin:

@impl true

I did look at the code a little so I saw all that. It does make sense they aren’t there since those callbacks are for both pages and components. I will open an issue and, again, happy to do the work.

I actually didn’t realize that LiveView didn’t use @impl true in their docs! I always thought that’s where I learned about it. I’m now having a bit of a Mandela moment over here.

1 Like

Glad the routing clicked! :slight_smile:

Regarding docs - the website repo is currently private, but feel free to open an issue in the Hologram repo with any docs suggestions you have.

For the other items (the ambiguous Link error message, optional callbacks for action/command) - PRs are welcome! Just please also create GitHub issues first so we can track them.

Also, I’ve been publishing contributor-friendly tasks here: Contributor-friendly tasks to claim - though at the moment all of them are taken. More will be added over time.