Skip to Content
Course content

224: Handling Multi-Language Routes

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When you're scaling a site for a global audience, the most common debate is how to handle the URL. You could use cookies or session data, but that's a nightmare for SEO. Search engines want unique URLs for unique content. That's why we're going to implement "locale-prefixing," where the language code (like /en/ or /es/) sits right at the front of the URI.

Parsing the locale from the request

I like to keep my routing logic lean. Instead of a massive switch statement, I'll treat the first segment of the URL as the language identifier. If we're building a simple "Company Profile" page, we want /en/about and /es/about to hit the same controller but load different strings.

$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = explode('/', trim($uri, '/'));

// Let's assume the first segment is our language code
$locale = $segments[0] ?? 'en'; 
$page = $segments[1] ?? 'home';

// A simple translation map for our example
$translations = [
    'en' => ['about' => 'About Our Company', 'home' => 'Welcome'],
    'es' => ['about' => 'Sobre Nuestra Empresa', 'home' => 'Bienvenido']
];

echo $translations[$locale][$page] ?? 'Page Not Found';

Handling the "Missing Prefix" blunder

I actually just ran this in my local environment and realized I made a classic mistake. If a user visits /about without a language prefix, my code thinks "about" is the language code. It looks for $translations['about'], finds nothing, and throws a warning. It's a common trap when you assume the URL structure will always be perfect.

To fix this, we need to verify if the first segment is actually a supported language. If it's not, we should treat it as the page name and fallback to a default language.

$supportedLocales = ['en', 'es', 'fr'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = explode('/', trim($uri, '/'));

$firstSegment = $segments[0] ?? '';

if (in_array($firstSegment, $supportedLocales)) {
    $locale = $firstSegment;
    $page = $segments[1] ?? 'home';
} else {
    $locale = 'en'; // Our default
    $page = $firstSegment ?: 'home';
}

echo $translations[$locale][$page] ?? '404 Not Found';

Keeping the user in their chosen language

Now that the routing works, we have a new problem: links. If I'm on the Spanish version of the site and I click a link to "Contact," I don't want to be booted back to the English version. I need a way to generate URLs that preserve the current locale.

I usually wrap this in a small helper function. It feels a bit redundant at first, but it saves you from concatenating strings manually in every single blade or PHP template file across your project.

function url_for($page, $locale = 'en') {
    return "/" . $locale . "/" . $page;
}

// If the current user is browsing in Spanish:
$currentLocale = 'es'; 
echo '<a href="' . url_for('contact', $currentLocale) . '">Contacto</a>';
// Output: Contacto

By centralizing the URL generation, you can change your entire URL structure—say, moving from /en/about to /language/en/about—in one single function rather than hunting through a hundred files.




📋 Practical Task

Build a Locale-Aware Navigation Menu

Create a PHP script that mimics a navigation bar for a multi-language site. Your task is to:

  • Define an array of supported languages (e.g., 'en', 'de', 'it').
  • Detect the current locale from the URL using the logic we discussed (with a fallback to 'en').
  • Create a navigation array containing page slugs and their translated names for at least two languages.
  • Generate an HTML <nav> list where every link automatically includes the current detected locale in the URL.
  • Add a "Language Switcher" section that provides links to the same current page but in the other supported languages.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.