Reputation: 417
I want to generate current url with different locales as hreflang
tags on every page and for each language. For example, for example.com/es/category/general
I would like to generate this hreflangs in my <head>
section:
<link rel="alternate" hreflang="en" href="example.com/category/general" />
<link rel="alternate" hreflang="es" href="example.com/es/category/general" />
<link rel="alternate" hreflang="de" href="example.com/de/category/general" />
Currently, I set locale via prefix. Notice that for default en
locale I don't use the prefix:
Route::prefix(parseLocale())->group(function () {
... // all routes go here
}
function parseLocale()
{
$locale = request()->segment(1);
$locales = config('app.available_locales');
$default = config('app.fallback_locale');
if ($locale !== $default && in_array($locale, $locales)) {
app()->setLocale($locale);
return $locale;
}
return;
}
How can I generate correct hreflang
tags for each locale?
Upvotes: 1
Views: 1573
Reputation: 4854
We could use a blade
directive to generate the hreflang
tags for each locale, in each page:
@foreach (config('app.available_locales') as $locale)
@if ($locale == app()->getLocale())
<link rel="alternate" hreflang="{{ $locale }}" href="{{ url()->current() }}" />
@else
@if ($locale == config('app.fallback_locale'))
<link rel="alternate" hreflang="{{ $locale }}" href="{{ url('/') . request()->segments() }}" />
@else
<link rel="alternate" hreflang="{{ $locale }}" href="{{ url('/') . $locale . request()->segments() }}" />
@endif
@endif
@endforeach
Upvotes: 1
Reputation: 417
The solution was a bit more complex that I thought, because I don't use a prefix for default language. I decided to create a custom Service Provider and return an array with locales associated with URLs for these locales (I will also use this array for the language switcher component):
public function boot()
{
view()->composer('*', function ($view) {
$languageUrls = [];
$currentLocale = request()->segment(1);
$locales = config('app.available_locales'); // ['en', 'de', 'es']
$defaultLocale = config('app.fallback_locale'); // 'en'
// Remove language prefix if not default from segments
if ($currentLocale !== $defaultLocale && in_array($currentLocale, $locales)) {
$noPrefixSegments = request()->segments();
array_shift($noPrefixSegments);
$noPrefixSegments = implode('/', $noPrefixSegments);
}
// Keep all segments
else {
$noPrefixSegments = request()->segments();
$noPrefixSegments = implode('/', $noPrefixSegments);
}
// Generate an array of locales associated with URLs
foreach ($locales as $locale) {
if ($locale === $defaultLocale) {
$languageUrls[$locale] = $noPrefixSegments;
} else {
$languageUrls[$locale] = $locale . '/' . $noPrefixSegments;
}
}
return $view->with('languageUrls', $languageUrls);
});
}
Then in the blade template I simply generate all hreflangs:
@foreach ($languageUrls as $language => $url)
<link rel="alternate" hreflang="{{ $language }}" href="{{ url('/') }}/{{ $url }}" />
@endforeach
which for https://example.com/es/category/page
gives me what I've expected:
<link rel="alternate" hreflang="en" href="https://example.com/category/page" />
<link rel="alternate" hreflang="es" href="https://example.com/es/category/page" />
<link rel="alternate" hreflang="de" href="https://example.com/de/category/page" />
Upvotes: 0