· Admin

Laravel'de Çoklu Dil Desteği (Localization) ve SEO Uyumlu URL'ler

Global pazara açılmak istiyorsanız çoklu dil desteği şart. Laravel'in localization sistemi güçlü bir altyapı sunuyor. Bu yazıda dil dosyaları, middleware ile otomatik algılama, URL bazlı dil seçimi ve SEO uyumlu hreflang etiketlerini ele alıyoruz.

Dil Dosyaları Yapısı

Laravel dil dosyalarını lang/ dizininde saklar:

lang/
├── en/
│   ├── messages.php
│   └── validation.php
└── tr/
    ├── messages.php
    └── validation.php

Dosya içeriği:

// lang/tr/messages.php
return [
    'welcome' => 'Hoş geldiniz!',
    'login' => 'Giriş Yap',
    'register' => 'Kayıt Ol',
    'logout' => 'Çıkış',
    'greeting' => 'Merhaba, :name!',
];
// lang/en/messages.php
return [
    'welcome' => 'Welcome!',
    'login' => 'Login',
    'register' => 'Register',
    'logout' => 'Logout',
    'greeting' => 'Hello, :name!',
];

Çeviri Kullanımı

// Helper fonksiyon
echo __('messages.welcome'); // "Hoş geldiniz!"

// Parametreli çeviri
echo __('messages.greeting', ['name' => 'Ali']); // "Merhaba, Ali!"

// Blade template'de
{{ __('messages.welcome') }}

// @lang direktifi
@lang('messages.welcome')

URL Bazlı Dil Seçimi

En yaygın ve SEO dostu yaklaşım:

example.com/tr/hakkimizda
example.com/en/about

Route Tanımı

Route::prefix('{locale}')
    ->middleware('set.locale')
    ->group(function () {
        Route::get('/', [HomeController::class, 'index'])->name('home');
        Route::get('/about', [PageController::class, 'about'])->name('about');
        Route::get('/contact', [PageController::class, 'contact'])->name('contact');
    });

// Varsayılan dile yönlendirme
Route::get('/', function () {
    return redirect(app()->getLocale());
});

Locale Middleware

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class SetLocale
{
    private array $supportedLocales = ['tr', 'en', 'de'];

    public function handle(Request $request, Closure $next)
    {
        $locale = $request->route('locale');

        if (!in_array($locale, $this->supportedLocales)) {
            abort(404);
        }

        App::setLocale($locale);
        session(['locale' => $locale]);

        return $next($request);
    }
}

bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'set.locale' => \App\Http\Middleware\SetLocale::class,
    ]);
})

Otomatik Dil Algılama

Tarayıcı diline göre yönlendirme:

class RedirectToLocale
{
    public function handle(Request $request, Closure $next)
    {
        if (!session('locale')) {
            $browserLocale = substr($request->server('HTTP_ACCEPT_LANGUAGE', 'tr'), 0, 2);
            $locale = in_array($browserLocale, ['tr', 'en', 'de']) ? $browserLocale : 'tr';

            return redirect("/{$locale}" . $request->getRequestUri());
        }

        return $next($request);
    }
}

Dil Değiştirme Komponenti

<div class="flex gap-2">
    @foreach(['tr' => '🇹🇷', 'en' => '🇬🇧', 'de' => '🇩🇪'] as $locale => $flag)
        <a href="{{ url($locale . '/' . request()->path()) }}"
           class="{{ app()->getLocale() === $locale ? 'font-bold' : '' }}">
            {{ $flag }} {{ strtoupper($locale) }}
        </a>
    @endforeach
</div>

SEO: hreflang Etiketleri

Google'ın çok dilli sayfaları doğru indekslemesi için:

{{-- layout.blade.php head bölümüne --}}
<html lang="{{ app()->getLocale() }}">
<head>
    @foreach(['tr', 'en', 'de'] as $locale)
    <link rel="alternate" hreflang="{{ $locale }}"
          href="{{ url($locale . '/' . request()->path()) }}" />
    @endforeach
    <link rel="alternate" hreflang="x-default"
          href="{{ url('tr/' . request()->path()) }}" />
</head>

Çok Dilli Validation Mesajları

// lang/tr/validation.php
return [
    'required' => ':attribute alanı zorunludur.',
    'email' => ':attribute geçerli bir e-posta adresi olmalıdır.',
    'min' => [
        'string' => ':attribute en az :min karakter olmalıdır.',
    ],

    'attributes' => [
        'name' => 'Ad',
        'email' => 'E-posta',
        'password' => 'Şifre',
    ],
];

Çok Dilli Veritabanı İçeriği

JSON Kolonu Yaklaşımı

Schema::create('pages', function (Blueprint $table) {
    $table->id();
    $table->json('title'); // {"tr": "Hakkımızda", "en": "About Us"}
    $table->json('content');
    $table->timestamps();
});

Model'de cast:

class Page extends Model
{
    protected $casts = [
        'title' => 'array',
        'content' => 'array',
    ];

    public function getLocalizedTitle(): string
    {
        return $this->title[app()->getLocale()] ?? $this->title['tr'] ?? '';
    }
}

Ayrı Çeviri Tablosu Yaklaşımı

Spatie Laravel Translatable paketi:

composer require spatie/laravel-translatable
use Spatie\Translatable\HasTranslations;

class Page extends Model
{
    use HasTranslations;

    public array $translatable = ['title', 'content'];
}

// Kullanım
$page->setTranslation('title', 'tr', 'Hakkımızda');
$page->setTranslation('title', 'en', 'About Us');

echo $page->title; // Aktif locale'e göre otomatik döner

Sonuç

Laravel'in localization sistemi güçlü ve esnek. URL bazlı dil seçimi + hreflang etiketleri ile SEO uyumlu çok dilli site oluşturabilirsiniz. Veritabanı içeriği için JSON kolonlar veya Spatie Translatable kullanın. Global pazarda görünürlük istiyorsanız çoklu dil desteği yatırım yapılması gereken bir alan.