Skip to content

Improved prefix support for verified routes #6501

Open

Description

@LostKobrakai

use Phoenix.VerifiedRoutes currently supports path_prefixes: [{Gettext, :get_locale, []}] as an option. This is quite limiting though, because it's a static prefix set per module (per use call). ~p"/somewhere" implicitly gets the prefix applied based on context alone.

Often prefixes also happen to be mixed in with non prefixed routes in templates (e.g. in the app layout) and the need for distinct modules makes this confusing.

I'm proposing changing the option to path_prefixes: %{"locale" => {Gettext, :get_locale, []}}, which makes applying the prefix depend on the route provided like so: ~p"/:locale/somewhere". This clearly indicates the use of a prefix, while allowing for multiple prefixes as well as no prefix to coexist.

Activity

  1. LostKobrakai commented on Oct 1, 2025

    @LostKobrakai
    ContributorAuthor

    @josevalim ping as requested :)

  2. achedeuzot commented on Oct 3, 2025

    @achedeuzot

    I'm not sure you'd want to use or write ~p"/:locale/somewhere for every URL that needs to have the locale prefixed.

    For example, for all mix phx.gen.auth generated routes, I'd love to simply change the scope from scope "/" do to scope "/:locale" do so the full route would be /:locale/users/register.

    So for given configuration like so:

    scope "/:locale" do
        [...]
        live "/users/register", UserLive.Registration, :new
        [...]
    end

    I would continue to use ~p"/users/register". I'd expect the configured verified routes configuration like so path_prefixes: %{"locale" => {Gettext, :get_locale, []}} to be smart enough to replace the /:locale from the scope automatically and generate /en/users/register for example. The advantage for all generated files, for example for mix phx.gen.auth is that there is no need to change all the verified routes ~p calls and thus igniter would work for upgrades out of the box as there was no changes of urls.

    Another idea would be to give an mfa (module/function/args) configuration to the verified routes macro so they can be pre-processed by the user so it implements its own logic (URL translation, URL rewriting, URL prefixing, etc.). What do you think ?

  3. josevalim commented on Oct 4, 2025

    @josevalim
    Member

    Right, perhaps this should be called custom_segments, where you can define a segment that gets injected if you write it, but I think it is a separate feature to path prefix.

    Meanwhile, I suggest following the steps in the docs, and use Phoenix.VerifiedRoutes without path prefixes in the few places you don't always have localization.

  4. achedeuzot commented on Oct 4, 2025

    @achedeuzot

    @josevalim the issue mostly arises when path_prefixes is set, it will prefix everything, including static path assets making the layout have errors by default.

    Initially I was searching for a guide or documentation that shows how to use the feature. I wasn't able to figure out how to use it on a vanilla phoenix generated project without having to change all routes, including static paths in the layout (which doesn't have a lot of sense to have statics prefixed with a locale). I stumbled on this configuration option because I was searching for an easy path prefix locale configuration while cldr_locale and routex seem overkill. It is currently described as a locale-in-path solution in the docs that's why I tried it out to see if it could solve my problem :).

  5. josevalim commented on Oct 4, 2025

    @josevalim
    Member

    It should definitely not apply to assets. I will fix that.

  6. josevalim commented on Oct 4, 2025

    @josevalim
    Member

    Fixed in main. :)

  7. achedeuzot commented on Oct 4, 2025

    @achedeuzot

    @josevalim amazing 😍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions