How to define a global prefix?

The base_url for my app isn’t at the root of the server, but is instead one level higher (i.e. instead of just How do I configure the router for this? This is something I’m unable to alter, and currently none of my url helpers work because they lack this prefix. Just putting that in base_url in config/app.rb doesn’t appear to be doing the trick.

I documented this bug in #249 and fixed it in #250.

This didn’t see a release until the 2.1 beta, so if you are still on 2.0.2 that’s why.

You can pin your router to 2.1.0.rc2 separate from the rest of the framework and it should be okay. There are no breaking changes you need to worry about.

I’m actually using 2.1rc2. I think the issue may actually be limited to assets only, but I’ll need to confirm that.

So adding config.assets.base_url = config.base_url to config/app.rb appears to have partially resolved the issue. Now the helpers are generating the correct URL at least. But now the asset routing itself appears to be broken, as I’m seeing this when assets are trying to be retrieved:
11:10:51 web.1 | 2023-12-11 11:10:51 -0600 Rack app ("GET //assets/main/app.js" - ( #<Hanami::Router::NotFoundError: No route found for GET //assets/main/app.js>

This is with the base_url set to http://localhost/prefix, and the generated URL that ends up in the HTML is http://localhost/prefix/assets/main/app.js. So somewhere in there an extra / is being generated, though I don’t know if THAT is the actual problem or just a symptom.

That part is fine, a URI starting with // just means that the scheme is implicit which allows either http or https to be valid depending on the current URL.

The real problem appears to be that the assets are subject to a similar prefix-clobbering bug. I would anticipate that URI#merge is involved as before.

Yeah, looks like the problem is probably here:

def initialize(url, prefix = nil)
  @url = URI(url + prefix.to_s).to_s

In combination with this:

setting :base_url, constructor: -> url { }

Though I’m not clear on where this is mucking up the routing.

Because URI#+ is aliased to #merge, which interprets any path beginning with / as absolute. So if you’re merging /assets/main/app.js it clobbers the prefix.

Ahhhh, alright. Then I was definitely wrong about where the problem is :joy:

No, you got it. It’s this bit right here:

URI(url + prefix.to_s)

See, I thought that, but when I went digging, the only place I could find that class being initialized is in that base_url setting… where it never uses the prefix argument.

I’m not working with assets currently, so I would recommend filing a bug for this on GitHub. I’m sure the team would like to correct this before the official release

1 Like