What would be the best way to persist a url parameter between links? Can I override Routes.x_path?

Let’s say I have a env param in my url, that could be prod/dev/ (this has nothing to do with my current env, it’s something the user would choose). I want to persist this between clicks, so if the current env is dev, I want Routes.some_path(@conn, :show, @thing, env: "dev") to act like this. Currently I do so with Routes.some_path(@conn, :show, @thing, env: @conn.params["env"]), but ideally I wouldn’t have to extract the env from the conn each time and remember to add it to each link, is there a better way to do this with Phoenix or Plug?

Also, If I have some links in the header, one for dev and one for prod, is there a way to use Phoenix’s path helpers to create a link to the current url, but with a new param? Like: Routes.current_path(@conn, env: "prod")?

Your use case seems very similar to how Gettext operates with Gettext.put_locale(locale) and Gettext.get_locale().

So, in a plug, you would set your param and everywhere thereafter you could read it.

Gettext stores the locale in the process dictionary.

But, honestly, I wouldn’t over complicate this if you can extract it from the conn params as you currently do. Why do you feel that’s a problem?

Is there a reason not to save the env in the session? That would be easier and more robust than add the param to every URL.

1 Like

Because I wouldn’t want User A to copy a link from their current page (User A has dev in their session), and send it to User B to edit (User B has prod in their session), and who therefore ends up editing their prod config when they thought they were accessing their dev config.

1 Like

Maybe then have a combination and if the param is in the link, then change the session

Would it be a possibility then to use a path namespace (/dev/... vs /prod/...), or subdomain (dev.example.com vs prod.example.com)? Don’t get me wrong, you probably have your good reasons for using a URL param, but I am just thinking that it would be much easier and robust to store this information elsewhere. My point is that, if you use a URL param, you have to remember to do that for literally every link (and form too), and only one missing place would be enough to break it.

If the env needs to be in the url in order to correctly link to the right page, then I don’t see the point of also having it in the session. I think I’ll either just have to grab is from the conn each time I create a new link, or embed it directly into the url path itself.

Yeah, I think i’ll have to go with the first one. That’s how I had it before, but it made my routes and controllers a bit of a mess. Maybe I’ll add it to the end, so it’s /account/123/config/456/dev or /account/123/config/456/prod, instead of /.../?end=prod. I was just curious if there was a better was to handle it in the conn or route helpers, but it seems like adding it to the url path itself is the best way forward. Thanks.

1 Like

Routes.some_path is just a function; make a different one that does the conn.params["env"] dance and forwards all the rest of its arguments.