How to change the locale through URL?
This is how I did it in one of Rails 4 applications:
in config/routes.rb:
Rails.application.routes.draw do
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
# rest of your routes here
# for example:
resources :projects
end
end
make sure in config/environments/production.rb this line is uncommented:
config.i18n.fallbacks = true
If you wish to have a default_locale
setup other than :en
, then in config/application.rb, uncomment this line:
config.i18n.default_locale = :de # and then :de will be used as default locale
Now, last part of your setup, add this method in ApplicationController
:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :set_locale
private
def set_locale
I18n.locale = params[:locale] || session[:locale] || I18n.default_locale
session[:locale] = I18n.locale
end
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ locale: I18n.locale }
end
end
Now, your application can be accessed as: http://localhost:3000/en/projects
, http://localhost:3000/fr/projects
, or http://localhost:3000/projects
. The last one http://localhost:3000/projects
will use :en
as its default locale(unless you make that change in application.rb).
Change the way the locale is displayed in url with Symfony3
To achieve that you might need decorate "completely" the HttpKernel LocaleListener
to something like this:
// AppBundle\EventListener\LocaleListener
private function setLocale(Request $request)
{
if ($locale = $request->attributes->get('_locale')) {
if (false !== strpos($locale, '-')) {
// translate en-gb to en_GB
$localeParts = explode('-', $locale);
$locale = $localeParts[0].'_'.strtoupper($localeParts[1]);
}
$request->setLocale($locale);
}
}
private function setRouterContext(Request $request)
{
if (null !== $this->router) {
$locale = $request->getLocale();
// translate en_GB to en-gb
$locale = strtolower(strtr($locale, '_', '-'));
$this->router->getContext()->setParameter('_locale', $locale);
}
}
Note: These two methods are private
, it's why we need copy+paste the complete code of the original listener to change its behavior.
More about "How to Decorate Services" here, or creates you own compiler pass to exchange the service class of the locale_listener
definition.
How to force default locale in the URL when clicking a link in Next.js
To force the default language to add the locale to the URL you could pass it to the href
directly, and opt-out of automatically handling the locale prefixing by setting locale
to false
.
<Link href={`/${router.locale === 'en' ? 'fr' : 'en'}`} locale={false}>
<a>Switch</a>
</Link>
If you want all your Link
s to behave this way, and also force the default locale on the URL, the same logic would need to be applied.
Assuming you have a link to the /about
page, it would look like the following.
<Link href={`/${router.locale}/about`} locale={false}>
<a>About Page</a>
</Link>
If using next/router
to do the routing, the same logic can also be applied.
router.push(`/${router.locale}/about`, undefined, { locale: false });
Change URL depending on browser language
You can use navigator.language like this:
var lang = navigator.language.slice(0,2);
var el = document.getElementById('subdomainURL');
var href = `${el.href}#googtrans(en|${lang})`;
el.href = href;
How to translate location URL when changing language?
I finally found an easy and clean method to change the route while also changing the language.
const changeLanguage = (nextLanguage) => {
const routes = i18n.getResourceBundle(i18n.language, 'routes');
const currentPathname = window.location.pathname.replace(/\/+$/, '');
const currentRouteKey = Object.keys(routes).find((key) => routes[key] === currentPathname);
window.location.replace(t(`routes:${currentRouteKey}`, { lng: nextLanguage }));
};
I also needed to change the i18next detection options as follow:
detection: {
order: ['path', ...otherMethods]
lookupFromPathIndex: 0,
checkWhitelist: true
},
I can now safely call this changeLanguage wrapper anywhere and it will handle both the language change (which goes to the default in case it's not part of the url) and the route change.
Related Topics
When Do You Need a Require in a Rails Gemfile
Problem Installing SQLite3-Ruby!
Uploading Files in Ruby on Rails
Ruby/Pgsql Error on Rails Start:Cannot Load Such File -- Pg_Ext (Loaderror)
Match Sequences of Consecutive Characters in a String
Why Does Rails 4.2 + Responders Keeps Telling Me to Add Responders to the Gemfile
How to Change the Locale Through Url
Determining Which Rubygem You'Re Using
Using Nokogiri to Split Content on Br Tags
Ruby What Class Gets a Method When There Is No Explicit Receiver
Param Is Missing or the Value Is Empty
Why Is This Not a Syntax Error
Difference Between Lambda and -> Operator in Ruby
Http Library for Ruby with Https, Ssl Client Certificate and Keep-Alive Support