This marks a major milestone for Routex, solidifying its stability and readiness for production use. It has been quite a journey, shaped by valuable feedback and real-world use cases.
As the decision-making process comes to a close, I’ve also created a fresh thread in the Libs section to continue the conversation:
A huge thank you to everyone who provided feedback—it has played a crucial role in shaping both the design and documentation. Your insights and contributions have made Routex stronger, and I truly appreciate the support.
With version 1.2.0 on the horizon I would like to collect additional feedback before the release is finalized. After all, nothing better than Elixir-community collaboration
Although the version bump is minor, the release itself is major! The full changelog is linked at the bottom of this post.
Much of the code base has been refactored, new extensions build a bridge between compile time and run time and the most common use case of Routex, localization, has become much easier with the new extension SimpleLocale.
Simplified Integration / Automation
Routex now streamlines integration with your Phoenix application by extending
its functionality from compile time to runtime.
Call functions at runtime using (custom) Routex attributes
Inline LiveView Hooks of extensions
Inline Plugs of extensions**
Localize your Phoenix app
Routex.Extension.SimpleLocale is included as tech preview.
SimpleLocale was designed to provide a solution for the most common
cases of localization. Featuring automated Plug/LiveView integration, a small locales registry and very customizable locale detection at runtime (think Cldr.Plug.PutLocale on tweaker-steroids)
The registry is based on the official IANA registry. It only includes region and language identifiers (combined: locales) and their respective display names.
The runtime integration is not limited to any package and you can even have multiple locale backends at the same time, using different locales / language / region…
Routex using the buildin mini locale registry for button names and setting Gettext locale.
Docs, docs, docs
A much enhanced Usage Guide for getting up and running in no time.
The revamped Localize Phoenix Guide, so the issue this release began with could be closed
Speak up!
I hope to collect feedback on these new extensions / features! Let me know what you think as even a small comment might make a major positive impact. After all, this whole release was triggered by…
Localization guide is missing step to content translation (using Gettext) @KristerV
Full Changelog
For a detailed changelog with all changes explained in depth:
Correction: it now works with any package and any route attribute. The runtime callbacks are inlined in the Routex plug and Routex LiveView Lifecycle Hook.
How? SimpleLocale sets locale attributes during runtime. Extension RuntimeCallbacks can be configured to use these attributes. Now you have ultimate freedom to pick whatever lib you need at runtime, or even multiple (e.g. mixing Fluent and Cldr or having different Gettext backends with different locales at the same time, or a non-locale lib).
One bug down…do you find the next one? @ken-kost catched a regression and contributed a fix.
As they say: Gonna catch them all! What’s holding you up to find one?
SimpleLocale just got…simpler
The new extension SimpleLocale greatly simplifies working with locales in Phoenix. However, it’s configuration was still a bit spartan too provide maximum flexibility. Flexibility and usability / developer experience should not be two sides of a medal though.
Today a PR was opened to have both flexibility and ease of setup on the same side of the golden medal. It adds new configuration options to also generate the locale routes while still providing the possibility to override attributes. Simple by default, powerful when needed.
Route generation options
locales: A list of locale definitions. Each entry can be either:
A simple locale string (e.g. "en", "fr", "de")
A tuple of the form {locale, attrs} to override or add attributes for that locale
default_locale: The default locale for top-level navigation. Defaults to Gettext’s default locale (or fallbacks to "en" if Gettext default locale not set).
Tip: Integration with Gettext
You can synchronize locale routes with Gettext as follows:`
Development of the next next version already started
The before-mentioned @ken-kost is writing a fancy Igniter installer to make the setup a single mix command.
Call for help
The project greatly benefits from having multiple contributors and reviewers. Here is what you can do:
Review documentation: it’s low-hanging fruit yet incredibly valuable. Read the current docs and let us know what is unclear to you or what you think could be improved. You not even have to know the better wording!
Find bugs: having new features is nice, having zero bugs is nicer. Stress test, think of edge cases, make it fail! Open an issue or PR, then boast about your hunter skills; you earned it!
Tell us what you always wanted from a routing library. Santa ain’t in town, but we’ll have a look.
The code smell “does this AND that” was truly too much for me to handle. Both locale route generation and runtime locale detection are customizable in ways unseen before; having all their options on one page became quite confusing.
SimpleLocale sounds like the opposite of PowerfulLocale; not what I intended. It might well be the most configurable locale detection there is in the Phoenix ecosystem with many tweakable options so you can adapt it to your project (instead of the other way around). Yet, due to the sane defaults it’s still simple to setup
So it has been split in two extensions with clear boundaries, separate documentation etc.
This is cool. I just finished getting some multi tenancy stuff working and I was wondering about the calibre of route management that I employed (I’ve not built white paper websites).
Usually the changes within an RC series are minor. This time, not so much.
While tweaking the documentation of SimpleLocale for 1.2.0 release I decided to overhaul before it was too late and the project would be forced to do a breaking change in the next release. So I took it one step further…
Routex lowers the bar of Phoenix localization
I am happy to announce Routex arguably has the most comprehensive localized routes system for Phoenix, the most customizable locale detection and yet the easiest setup due to auto-detection of third-party localization packages.
At compile time, this extension generates localized routes based on locale tags. These locale tags are automatically derived from your Cldr, Gettext or Fluent setup and can be overriden using the extensions options.
When using a custom configuration, tags are validated using a build-in locale registry based on the authoritive IANA Language Subtag Registry. It can also be used the lookup language and region display names.
A Plug and LiveView Livecycle hook to update the connection with locale attributes and store them in the session. Comes with sane defaults but is highly customizable, so each locale attribute (:locale, :region, :language) can be take from independent sources.
You can define a clear order of precedence for each attribute. For instance, you might prioritize a route’s :region attributes over the browser’s Accept-Language header but at the same time use the Accept-Language as the main source for :language.
@BartOtten Really appreciate this effort as I’m just discovering how difficult it is to do localization the way I’d like to do it so this is definitely very much needed in the space.
I’m having a bit of trouble figuring out which version to try out and how to follow the corresponding docs. Should I give the main branch a go or the RC? I’d love to give this lib a try and provide feedback
Main branch is the way to go as localization is fully revamped in 1.2; making it much easier to setup! At main branch, all extensions come with auto-detection for sane default /fallback config yet an load of options to adapt their behavior to your needs. I did not have the time to check the tutorials yet, as the latest changes are very fresh:
Won’t take long for a new release but love to see feedback before I make it final; either an “all okey”, questions regarding setup/docs or raised issues when you are sure it’s a bug. It all helps
The third (and last?) release condidate has been published at Hex.
RuntimeCallbacks: rename RuntimeCallbacks to RuntimeDispatcher, the option is renamed from runtime_callbacks to dispatch_targets)
Changed so the name better reflects it’s purpose.
Plugs: renamed plug callback to simply call for compatibility reasons
LiveView Hooks & Plugs: do not pass Routex.Attrs as separate argument
A little less convenient for extension developers but at the plus side the plug are now simply that: plugs. One can now even add a non-Routex-plug in the extension list and will be be detected and enabled.
Localize Extensions: assign runtime detection values in namespace @runtime (e.g. @runtime.region)
Makes them more distinct from the route/compile-time values.
Version 1.2.0 and it’s documentation has silently be uploaded to Hex, as to make sure AI bots ingest the new features before flow coders are screwed with outdated information and create ghost issues. ‘Official announcement’ will follow later, but here’s a good start already.