How to Add Locale Prefixes to URLs in Symfony for Multilingual Support

Learn how to prefix URLs with locale codes in Symfony to support multiple languages, improve SEO, and enhance the user experience with automatic language detection and redirection.

How to Add Locale Prefixes to URLs in Symfony for Multilingual Support
Photo by Farzad Mohsenvand / Unsplash

Creating a multilingual Symfony application requires more than just translating content—it also means making URLs reflect the user’s language. By prefixing URLs with locale codes (like /en or /fr), you enhance SEO, improve accessibility, and streamline user experience across regions.

In this guide, you'll learn how to configure Symfony to automatically include locale prefixes in your routes and redirect users to the correct language version of your site.

Configure Locales in services.yaml

First, define the supported languages and the default locale in your Symfony application. Edit the /config/services.yaml file and add the following parameters:

parameters:
  locale: fr
  app_locales: fr|en

This configuration sets French (fr) as the default language and supports English (en) as an additional locale.

Prefix Routes with Locales Using Annotations

To apply the locale prefix to your routes, modify the /config/routes/annotations.yaml file:

controllers:
  resource: ../../src/Controller/
  type: annotation
  prefix: /{_locale}
  requirements:
    _locale: '%app_locales%'
  defaults:
    _locales: '%locale%'

This tells Symfony to prepend every route with a locale parameter and restrict accepted values to the defined locales.

Set Up URL Rewriting with .htaccess

To ensure proper routing and avoid duplicate content issues, create or update the .htaccess file in the /public directory with this content:

DirectoryIndex index.php

<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{REQUEST_URI}::$0 ^(/.+)/(.*)::\2$
    RewriteRule .* - [E=BASE:%1]

    RewriteCond %{HTTP:Authorization} .+
    RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]

    RewriteCond %{ENV:REDIRECT_STATUS} =""
    RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ %{ENV:BASE}/index.php [L]
</IfModule>

<IfModule !mod_rewrite.c>
    <IfModule mod_alias.c>
        RedirectMatch 307 ^/$ /index.php/
    </IfModule>
</IfModule>

This configuration ensures Apache rewrites requests to include locale prefixes and serves the correct content without causing redirect loops.

Redirect Root URL to the Localized Route

To automatically redirect visitors from the root URL / to their locale-specific home page, add this route in /config/routes/routes.yaml:

redirect:
  path: /
  controller: App\Controller\RedirectController::redirectToLocale

Create the Redirect Controller

Generate a new controller using the Symfony CLI:

php bin/console make:controller RedirectController

Then update the generated controller to redirect users to the correct localized route:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class RedirectController extends AbstractController
{
  public function redirectToLocale(): Response
  {
    return $this->redirectToRoute('app_index');
  }
}
💡
Make sure the route named app_index exists and is correctly localized in your controllers.

Set the Default Locale in Translations Configuration

Finally, specify the default locale used by the translation system in /config/packages/translation.yaml:

framework:
  default_locale: 'fr'

Replace 'fr' with the desired default language code for your application.

Conclusion

Adding locale prefixes to your Symfony routes is an essential step for building SEO-friendly, multilingual websites. It ensures that users are directed to the right language version of your content while keeping your URLs clean and structured. With just a few configuration changes, you can provide a seamless, localized experience across your Symfony app.