Розробка системи управління SEO-даними (meta, OG) сайту
Система управління SEO-даними дозволяє редакторам встановлювати мета-теги для кожної сторінки — title, description, Open Graph, Twitter Card — без змін коду. Критично важлива для новинних сайтів, інтернет-магазинів та корпоративних порталів.
Модель даних
seo_metas (
id, seo_type, seo_id, -- поліморфна зв'язок: Article, Product, Category, Page
title, description, keywords,
og_title, og_description, og_image_url,
twitter_title, twitter_description, twitter_image_url, twitter_card,
robots, -- 'index,follow' | 'noindex,nofollow' | custom
canonical_url, -- переопис автоматичного canonical
schema_type, -- тип для JSON-LD
schema_data (jsonb),
created_at, updated_at
)
Трейт для моделей
trait HasSeoMeta
{
public function seoMeta(): MorphOne
{
return $this->morphOne(SeoMeta::class, 'seo');
}
public function getEffectiveSeoTitle(): string
{
return $this->seoMeta?->title
?? $this->getDefaultSeoTitle()
?? config('seo.site_name');
}
public function getEffectiveSeoDescription(): string
{
return $this->seoMeta?->description
?? $this->getDefaultSeoDescription()
?? '';
}
}
Компонент мета-тегів (Blade/React)
// Blade: layout.blade.php
<title>{{ $seo->title ?? config('seo.default_title') }}</title>
<meta name="description" content="{{ $seo->description ?? '' }}">
<meta name="robots" content="{{ $seo->robots ?? 'index,follow' }}">
@if($seo->canonical_url)
<link rel="canonical" href="{{ $seo->canonical_url }}">
@endif
<meta property="og:title" content="{{ $seo->og_title ?? $seo->title }}">
<meta property="og:description" content="{{ $seo->og_description ?? $seo->description }}">
<meta property="og:image" content="{{ $seo->og_image_url ?? config('seo.default_og_image') }}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ request()->url() }}">
<meta name="twitter:card" content="{{ $seo->twitter_card ?? 'summary_large_image' }}">
<meta name="twitter:title" content="{{ $seo->twitter_title ?? $seo->og_title ?? $seo->title }}">
<meta name="twitter:description" content="{{ $seo->twitter_description ?? $seo->og_description }}">
<meta name="twitter:image" content="{{ $seo->twitter_image_url ?? $seo->og_image_url }}">
Шаблони мета-тегів
Для сторінок без ручного налаштування — автоматична генерація з шаблону:
// Для товарів
'{name} — купити за {price} ₽ | {site_name}'
'{description} Доставка по всій Росії.'
// Заміна
$title = Str::of(config('seo.product_title_template'))
->replace('{name}', $product->name)
->replace('{price}', number_format($product->price / 100, 0, '.', ' '))
->replace('{site_name}', config('seo.site_name'))
->limit(60);
Форма редагування в CMS
SEO-розділ у формі редагування будь-якої сутності — вкладка або accordion:
function SeoMetaForm({ data, onChange }) {
return (
<Accordion type="single" collapsible>
<AccordionItem value="seo">
<AccordionTrigger>SEO-налаштування</AccordionTrigger>
<AccordionContent>
<div className="space-y-4">
<div>
<Label>Title (рекомендується 50-60 символів)</Label>
<Input value={data.title} onChange={e => onChange({ title: e.target.value })} />
<CharCounter current={data.title?.length} max={60} />
</div>
<div>
<Label>Description (рекомендується 150-160 символів)</Label>
<Textarea value={data.description} onChange={e => onChange({ description: e.target.value })} />
<CharCounter current={data.description?.length} max={160} />
</div>
<SeoPreview title={data.title} description={data.description} />
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
);
}
Компонент SeoPreview показує, як сторінка виглядатиме в результатах пошуку Google.
Час розробки: 2–3 дні для повної системи з поліморфними зв'язками, шаблонами та формою редагування.







