Skip to content

Multi-language URLs

Implementing multi-language URLs is a common use-case. Using a route scope block in Avo allows you to seamlessly adapt your application to support multiple languages, enhancing the user experience. This recipe will guide you through the steps to configure a locale scope, ensuring your application dynamically sets and respects the user's preferred language. Let's dive in!

1. Mount Avo within a :locale scope

Using a locale scope is an effective way to set the locale for your users.

Only Avo engine

On the community plan, the only requirement is to wrap the Avo engine mount within the scope.

WARNING

This will work for Avo's engine routes but won't work for any of the nested engines.

If you're using avo-pro, avo-advanced or any other Avo engine check the next section.

ruby
# config/routes.rb

Rails.application.routes.draw do
  scope ":locale" do
    mount Avo::Engine, at: Avo.configuration.root_path
  end
end

Avo engine and nested engines

Because of how Rails is mounting engines, that locale scope is not being applied to nested engines like avo-advanced, avo-pro, etc.

The fix here is to tell Avo not to mount the engines and have them mounted yourself.

ruby
# config/avo.rb

Avo.configure do |config|
  # Disable automatic engine mounting
  config.mount_avo_engines = false
end

Once automatic engine mounting is disabled, the next step is to mount the Avo engine and its nested engines within the locale scope.

ruby
# config/routes.rb

Rails.application.routes.draw do
  scope ":locale" do
    mount Avo::Engine, at: Avo.configuration.root_path
  end
end

if defined? ::Avo
  Avo::Engine.routes.draw do
    scope "(:locale)" do # Take note of the parentheses
      instance_exec(&Avo.mount_engines)
    end
  end
end

WARNING

Take note of the parentheses around the (:locale) scope when mounting the engines. These parentheses are essential to ensure proper functionality.

This will instruct Rails to add the locale scope to all Avo nested engines too.

2. Apply the locale Scope

To properly handle localization within Avo, you'll need to ensure the locale parameter is respected throughout the request which we'll do by overriding the set_avo_locale method in your Avo::ApplicationController as follows:

INFO

If you don't have the app/controllers/avo/application_controller.rb file present in your app, you can eject it using this command:

bash
rails generate avo:eject --controller application_controller
ruby
# app/controllers/avo/application_controller.rb
module Avo
  class ApplicationController < BaseApplicationController
    def set_avo_locale(&action)
      I18n.with_locale(params[:locale], &action)
    end
  end
end

This implementation uses I18n.with_locale to set the desired locale for the duration of the request, ensuring consistent localization behavior across Avo's interface and that it won't impact the other non-Avo parts of your app.