Настройка SEO-friendly URL для сайта
SEO-friendly URL — читаемые, понятные адреса страниц без технических параметров. Влияют на CTR в поиске (пользователь видит URL в сниппете), на восприятие ссылки и косвенно на ранжирование.
Принципы хорошего URL
| Плохо | Хорошо |
|---|---|
/product.php?id=4521 |
/products/iphone-15-pro-256gb |
/cat/12/sub/45 |
/catalog/smartphones/apple |
/articles/2024/03/15/post-1 |
/blog/kak-vybrat-noutbuk |
/page?lang=ru&id=about |
/o-kompanii |
/Products/Laptops/Dell |
/products/laptops/dell (строчные) |
Правила:
- Только строчные буквы
- Разделитель — дефис, не подчёркивание
- Без технических ID (если можно обойтись)
- Транслитерация или семантический перевод на английский
- Логичная иерархия, отражающая структуру сайта
- Без лишних стоп-слов:
the,и,или,для
Транслитерация slug в Laravel
use Illuminate\Support\Str;
// Простая транслитерация через iconv
function translit(string $text): string
{
$text = mb_strtolower($text);
$cyrToLat = [
'а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'yo',
'ж'=>'zh','з'=>'z','и'=>'i','й'=>'y','к'=>'k','л'=>'l','м'=>'m',
'н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u',
'ф'=>'f','х'=>'kh','ц'=>'ts','ч'=>'ch','ш'=>'sh','щ'=>'shch',
'ъ'=>'','ы'=>'y','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya',
' '=>'-','_'=>'-',
];
$text = strtr($text, $cyrToLat);
return preg_replace('/[^a-z0-9\-]/', '', $text);
}
// В модели
protected static function boot(): void
{
parent::boot();
static::creating(function (self $model) {
if (empty($model->slug)) {
$model->slug = static::generateUniqueSlug($model->title);
}
});
}
protected static function generateUniqueSlug(string $title): string
{
$slug = translit($title);
$original = $slug;
$count = 1;
while (static::where('slug', $slug)->exists()) {
$slug = "{$original}-{$count}";
$count++;
}
return $slug;
}
Маршрутизация
// Вложенные маршруты для иерархии
Route::get('/catalog/{category}/{subcategory?}', [CatalogController::class, 'show'])
->where(['category' => '[a-z0-9\-]+', 'subcategory' => '[a-z0-9\-]+']);
Route::get('/catalog/{category}/{subcategory}/{product}', [ProductController::class, 'show'])
->where(['product' => '[a-z0-9\-]+']);
Постоянный slug vs. генерируемый из заголовка
- Фиксированный slug — не меняется при редактировании заголовка (SEO-предпочтительно, нет битых ссылок)
- Автоматический — обновляется с заголовком (нужен автоматический 301-редирект со старого slug)
Хранить историю slug для автоматических 301:
Schema::create('slug_redirects', function (Blueprint $table) {
$table->string('old_slug')->primary();
$table->string('new_slug');
$table->string('model_type');
$table->unsignedBigInteger('model_id');
$table->timestamps();
});
URL для мультиязычных сайтов
Варианты структуры:
| Структура | Пример |
|---|---|
| Субдомен | ru.example.com/products/laptop |
| Префикс пути | example.com/ru/products/laptop |
| Отдельный домен | example.ru/products/laptop |
Для Яндекса предпочтительны региональные домены (.ru). Для Google — любой вариант работает, если настроен hreflang.
Пагинация
Предпочтительный формат: /blog/page/2 или /blog?page=2. Второй вариант удобнее — не требует отдельного роута, canonical автоматически корректен.
Срок настройки: 1 день для реализации slug-системы с историей редиректов.







