feat: implement structured data support for blog and page components, enhancing SEO and user experience through JSON-LD integration

This commit is contained in:
Ümit Tunç
2026-05-21 21:54:12 +03:00
parent 8675325f50
commit 6d9ffc808b
15 changed files with 509 additions and 176 deletions
+149
View File
@@ -0,0 +1,149 @@
<?php
namespace App\Support;
abstract class StructuredData
{
/**
* @param array<int, array<string, mixed>> $graph
* @return array<string, mixed>
*/
protected static function wrap(array $graph): array
{
return [
'@context' => 'https://schema.org',
'@graph' => array_values($graph),
];
}
protected static function siteUrl(): string
{
return url('/');
}
protected static function siteName(): string
{
return (string) setting('site_name', config('app.name'));
}
/**
* @return array<string, mixed>
*/
protected static function websiteNode(?string $searchUrlTemplate = null): array
{
$siteUrl = static::siteUrl();
$siteName = static::siteName();
$node = [
'@type' => 'WebSite',
'@id' => $siteUrl . '#website',
'url' => $siteUrl,
'name' => $siteName,
'inLanguage' => app()->getLocale(),
'publisher' => ['@id' => $siteUrl . '#organization'],
];
if ($searchUrlTemplate) {
$node['potentialAction'] = [
'@type' => 'SearchAction',
'target' => [
'@type' => 'EntryPoint',
'urlTemplate' => $searchUrlTemplate,
],
'query-input' => 'required name=search_term_string',
];
}
return $node;
}
/**
* @return array<string, mixed>
*/
protected static function organizationNode(): array
{
$siteUrl = static::siteUrl();
$siteName = static::siteName();
$node = [
'@type' => 'Organization',
'@id' => $siteUrl . '#organization',
'name' => $siteName,
'url' => $siteUrl,
];
$logo = setting('site_logo');
if ($logo) {
$logoUrl = str_starts_with($logo, 'http') ? $logo : asset('storage/' . ltrim($logo, '/'));
$node['logo'] = [
'@type' => 'ImageObject',
'url' => $logoUrl,
];
}
return $node;
}
/**
* @param array<int, array{name: string, item: string}> $items
* @return array<string, mixed>
*/
protected static function breadcrumbNode(string $pageUrl, array $items): array
{
$elements = [];
foreach ($items as $index => $item) {
$elements[] = [
'@type' => 'ListItem',
'position' => $index + 1,
'name' => $item['name'],
'item' => $item['item'],
];
}
return [
'@type' => 'BreadcrumbList',
'@id' => $pageUrl . '#breadcrumb',
'itemListElement' => $elements,
];
}
/**
* @param array<string, mixed> $extra
* @return array<string, mixed>
*/
protected static function webPageNode(
string $pageUrl,
string $name,
?string $description = null,
array $extra = [],
): array {
$node = array_merge([
'@type' => 'WebPage',
'@id' => $pageUrl . '#webpage',
'url' => $pageUrl,
'name' => $name,
'inLanguage' => app()->getLocale(),
'isPartOf' => ['@id' => static::siteUrl() . '#website'],
'breadcrumb' => ['@id' => $pageUrl . '#breadcrumb'],
], $extra);
if ($description) {
$node['description'] = $description;
}
return $node;
}
/**
* @return array<string, mixed>
*/
protected static function listItem(int $position, array $item): array
{
return [
'@type' => 'ListItem',
'position' => $position,
'item' => $item,
];
}
}