Implement language selection inside URLs

To have more customer-friendly URLs and improve SEO, you may want the language selection of your site to be reflected in the URL. For example, <https://example.tld/en/> and <https://example.tld/fr/> for English and French pages.

To do this, you'll need to follow the below steps.

1. Landing pages

For a landing page (also known as a homepage, main page, start page, and so on), you can make use of our internationalized routing.

To do this, you'll need to edit the page folder settings (hover on a page folder and click the settings icon). Then you can specify the relative path for a specific language:

To display the language inside your landing pages, change the relative path of your homepage page folder for each language. In our example, we could add de and en for the de_DE and en_GB locale.



You don't need to include the / in your relative path, this is automatically added for you.

By doing so (and also applying the internationalized routes to all subsequent page folders accordingly), you'll have everything you're building in the site builder in the structure of having the language inside the URL. To find out more, see the URLs in multi-language projects article.

But what happens when someone reaches just your example.tld page? That's what we'll look at next.

2. Dealing with the landing page

By renaming the relative path of your former main page folder, you also got somehow “lost” of the default page that's being served once you reach your page without specifying any sub-path. There are several ways to deal with that, so you can choose the one that suits you best from the following list:

1. Language chooser
One option is to create a new landing page dealing with requests against / that shows a language chooser Frontastic component and then directs to the correct subpaths by referencing the former page folder and also setting the correct selected language.

2. Frontend redirect
Another option is to create a new landing page dealing with requests against / but only has a Frontastic component on it that determines the language, which sets it correctly without having to change anything, and does a frontend redirect to the correct page.


This approach will affect the Lighthouse score of your landing page because of the frontend redirect, so you need to consider this.

See also Redirecting in a Frontastic component.

3. Registering a Symfony route for /

You can also register a Symfony route for the main page under / and implement your own controller that takes the language of the browser (and maybe also other logic into account) to set the language based on that and then redirects the user to the former start page.

See the Custom endpoints and API access article for more information.

4. Registering a default language for /

To have a default language of your site (for example, English), you can modify the changes done in 1. Landing pages to only have a different i18n relative URL for your non-default languages.

This will lead to URLs like the following:

  • <https://example.tld/...> for everything in English
  • <https://example.tld/de/...> for everything in German
  • ...

You'll need to take this into account in the next steps and this will make the decision as well as setting up the routing for dynamic pages more complicated as you'll need to add duplicated routes with different IDs for the routes where a language is contained and the ones where the default is taken.

3. Customizing dynamic pages

For dynamic pages, you'll need to overwrite their predefined route and enhance it to also contain the language. You can do this by following the Customize product URLs article for product detail pages.

This works similarly for the other routes as well. You'll find the necessary routes inside this configuration of our Catwalk library:

4. Retrieving the locale and using it

After you've configured everything to contain the language in the route, it's now time to also take it into account and properly retrieve it from the URL.

Have a look at our article on locale resolvers for how to come up with your own LocaleResolver.

Inside your own resolver, you can inject Symfony's request_stack and access the route information from there to set the correct language. You can also take into account other settings you might have made through some language or currency selector. That's totally up to your needs.

5. Language switcher component

If you have a language switcher component on your site, you'll need to properly set the locale and then redirect to the correct URL if necessary.