Hikayenin Başlangıcı
Geçtiğimiz aylarda Türkiye'deki bir canlı TV streaming sitesi olan kiraztv.com üzerinde teknik bir SEO denetimi yaparken, ilk bakışta her şey yolunda görünüyordu. WordPress, Rank Math SEO eklentisi, temiz URL yapısı, hızlı sunucu (TTFB 300ms civarı), responsive tasarım… Klasik bir "iyi yapılandırılmış" WordPress sitesi.
Ancak Chrome DevTools'u açıp document.querySelectorAll('script[type="application/ld+json"]').length yazdığımda gelen sonuç beni şaşırttı:
0
110'dan fazla kanal sayfasının HİÇBİRİNDE yapısal veri yoktu.
Bu yazıda, canlı TV ve yayın siteleri için en kritik schema'ları nasıl uyguladığımı, hangi çözümün hangi probleme cevap olduğunu ve 2026'da AI Overviews / Search Generative Experience (SGE) çağında bunların neden hayati olduğunu paylaşacağım.
Neden BroadcastService? Neden Şimdi?
Google 2024'ten itibaren arama sonuçlarına AI Overviews getirdi. Bu sistem, yapısal verisi zengin sayfaları belirgin biçimde tercih ediyor. Özellikle:
• "X kanalı canlı izle" tipi sorgular
• "X kanalı frekansı" tipi soru-cevap sorguları
• Knowledge Panel ve Entity-based sonuçlar
Bunlarda öne çıkmak için sıradan Article schema'sı yetmiyor. TV ve yayın siteleri için Schema.org'un sunduğu özel tipleri kullanmak gerekiyor:
Schema Ne işe yarar
TelevisionChannel Kanalın kendisini tanımlar (logo, dil, yayıncı)
BroadcastService Yayın hizmetini tanımlar (frekans, format, dağıtım)
BroadcastEvent Canlı yayın olayını tanımlar (LIVE badge için)
VideoObject Player'ı tanımlar (thumbnail, süre, embed)
FAQPage Sık Sorulan Sorular için (zengin sonuç)
BreadcrumbList Site içi navigasyon yolu
Bunların hepsini doğru şekilde implemente ettiğimde, Google Search Console'daki "Discovered – currently not indexed" uyarısı 3 hafta içinde dramatik biçimde azaldı ve organik tıklama oranı (CTR) bazı sayfalarda iki katına çıktı.
Şimdi nasıl yapıldığını adım adım göstereyim.
1. Adım: TelevisionChannel + BroadcastService Schema
Her kanal sayfası için temel schema şu şekilde olmalı:
{
"@context": "https://schema.org",
"@type": "TelevisionChannel",
"name": "ATV",
"alternateName": "atv",
"url": "https://example.com/canlitv/atv/",
"logo": "https://example.com/uploads/atv.jpg",
"broadcastChannelId": "ATV-HD",
"inBroadcastLineup": {
"@type": "CableOrSatelliteService",
"name": "Türksat 4A"
},
"providesBroadcastService": {
"@type": "BroadcastService",
"name": "ATV Canlı Yayın",
"broadcastDisplayName": "ATV",
"broadcaster": {
"@type": "Organization",
"name": "Turkuvaz Medya Grubu",
"url": "https://www.turkuvazmedya.com/"
},
"inLanguage": "tr",
"videoFormat": "HD",
"broadcastFrequency": {
"@type": "BroadcastFrequencySpecification",
"broadcastFrequencyValue": 12053,
"broadcastSignalModulation": "DVB-S",
"broadcastSubChannel": "H"
}
}
}
WordPress'te Bu Schema'yı Otomatik Üretmek
Her kanal için manuel JSON-LD yazmak 110 sayfada delilik olur. Custom Post Type meta alanlarından otomatik üretim yapan bir fonksiyon yazdım. functions.php'ye veya kendi eklentinize ekleyebilirsiniz:
add_action( 'wp_head', 'kanal_schema_olustur', 99 );
function kanal_schema_olustur() {
if ( ! is_singular( 'canlitv' ) ) {
return;
}
$post_id = get_the_ID();
$kanal_adi = get_the_title( $post_id );
$url = get_permalink( $post_id );
$logo = get_the_post_thumbnail_url( $post_id, 'full' );
$yayinci = get_post_meta( $post_id, 'yayinci_kurulus', true );
$frekans = get_post_meta( $post_id, 'turksat_frekans', true );
$dil = get_post_meta( $post_id, 'yayin_dili', true ) ?: 'tr';
$format = get_post_meta( $post_id, 'yayin_formati', true ) ?: 'HD';
$schema = [
'@context' => 'https://schema.org',
'@type' => 'TelevisionChannel',
'name' => $kanal_adi,
'url' => $url,
'logo' => $logo,
'providesBroadcastService' => [
'@type' => 'BroadcastService',
'name' => $kanal_adi . ' Canlı Yayın',
'broadcastDisplayName' => $kanal_adi,
'inLanguage' => $dil,
'videoFormat' => $format,
'broadcaster' => [
'@type' => 'Organization',
'name' => $yayinci,
],
],
];
if ( $frekans ) {
$schema['providesBroadcastService']['broadcastFrequency'] = [
'@type' => 'BroadcastFrequencySpecification',
'broadcastFrequencyValue' => (int) $frekans,
'broadcastSignalModulation' => 'DVB-S',
];
}
echo '<script type="application/ld+json">';
echo wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
echo '</script>';
}
Custom Post Type meta alanlarını ACF (Advanced Custom Fields) veya Meta Box ile kolayca yönetebilirsiniz. Her yeni kanal eklendiğinde editör frekansı, yayıncıyı, dili girer ve schema otomatik üretilir.
2. Adım: BroadcastEvent ile "LIVE" Badge
Google'ın canlı yayınlar için arama sonuçlarında gösterdiği o güzel kırmızı LIVE rozeti var ya — onu almak için BroadcastEvent şart:
{
"@context": "https://schema.org",
"@type": "BroadcastEvent",
"name": "ATV Canlı Yayın",
"isLiveBroadcast": true,
"startDate": "2026-05-20T00:00:00+03:00",
"endDate": "2026-05-21T00:00:00+03:00",
"videoFormat": "HD",
"broadcastOfEvent": {
"@type": "Event",
"name": "ATV Günlük Yayın Akışı"
}
}
startDate ve endDate dinamik olmalı. Yine WordPress fonksiyonuyla:
function broadcast_event_schema() {
if ( ! is_singular( 'canlitv' ) ) return;
$bugun = current_time( 'Y-m-d' );
$yarin = date( 'Y-m-d', strtotime( $bugun . ' +1 day' ) );
$kanal_adi = get_the_title();
$schema = [
'@context' => 'https://schema.org',
'@type' => 'BroadcastEvent',
'name' => $kanal_adi . ' Canlı Yayın',
'isLiveBroadcast' => true,
'startDate' => $bugun . 'T00:00:00+03:00',
'endDate' => $yarin . 'T00:00:00+03:00',
'videoFormat' => 'HD',
];
echo '<script type="application/ld+json">';
echo wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
echo '</script>';
}
add_action( 'wp_head', 'broadcast_event_schema', 100 );
İpucu: isLiveBroadcast: true Google'a "bu yayın şu an canlı" sinyali verir. Eğer 7/24 yayın yapan bir kanalsa endDate her gün otomatik 1 gün ileri kayar.
3. Adım: VideoObject ile Player'ı Tanımla
Eğer sayfanızda gömülü bir player varsa (HLS.js, Video.js, JW Player vs.), Google'a bu video hakkında bilgi vermeniz lazım:
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "ATV Canlı Yayını HD izle",
"description": "ATV canlı yayını kesintisiz HD kalitede izleyin.",
"thumbnailUrl": "https://example.com/uploads/atv.jpg",
"uploadDate": "2026-03-01T00:00:00+03:00",
"contentUrl": "https://example.com/canlitv/atv/",
"embedUrl": "https://example.com/canlitv/atv/?embed=1",
"publication": {
"@type": "BroadcastEvent",
"isLiveBroadcast": true,
"startDate": "2026-05-20T00:00:00+03:00"
}
}
Önemli: thumbnailUrl mutlaka gerçek, erişilebilir ve en az 60×30 piksel olmalı. Google bu görseli arama sonuçlarında küçük önizleme olarak gösterir.
4. Adım: FAQPage Schema (En Büyük Kazanç)
Sayfanızda 5+ Sık Sorulan Soru varsa, FAQPage schema organik CTR'ı %20-50 artırabilir. Bu, denetimini yaptığım sitedeki en büyük kaçırılmış fırsattı.
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "ATV ne zaman kuruldu?",
"acceptedAnswer": {
"@type": "Answer",
"text": "ATV, 12 Temmuz 1993 tarihinde Sabah Grubu bünyesinde yayın hayatına başladı."
}
},
{
"@type": "Question",
"name": "ATV Türksat frekansı nedir?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Türksat 4A üzerinden 12053 H 27500 - FEC 5/6 frekansı kullanılmaktadır."
}
}
]
}
WordPress'te FAQ bloklarını ACF Repeater alanından üretip otomatik schema'ya çevirmek:
function faq_schema_olustur() {
if ( ! is_singular( 'canlitv' ) ) return;
$sorular = get_field( 'sss_listesi' );
if ( empty( $sorular ) ) return;
$main_entity = [];
foreach ( $sorular as $satir ) {
$main_entity[] = [
'@type' => 'Question',
'name' => $satir['soru'],
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => wp_strip_all_tags( $satir['cevap'] ),
],
];
}
$schema = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => $main_entity,
];
echo '<script type="application/ld+json">';
echo wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
echo '</script>';
}
add_action( 'wp_head', 'faq_schema_olustur', 101 );
2024 Güncellemesi: Google FAQ rich results'ı bazı bölgelerde kısıtladı, ancak Türkiye'de hâlâ aktif. Ayrıca AI Overviews FAQ schema'sını kaynak olarak hâlâ tercih ediyor.
5. Adım: BreadcrumbList — Navigasyon Yolu
Kullanıcının hangi yoldan geldiğini Google'a göstermek için:
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Ana Sayfa",
"item": "https://example.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Ulusal",
"item": "https://example.com/kanal-kategorisi/ulusal/"
},
{
"@type": "ListItem",
"position": 3,
"name": "ATV",
"item": "https://example.com/canlitv/atv/"
}
]
}
Bu, arama sonuçlarında URL yerine güzel bir "Ana Sayfa > Ulusal > ATV" yolunun çıkmasını sağlar.
Test ve Doğrulama
Tüm bunları yazdıktan sonra mutlaka iki yerden test edin:
- Google Rich Results Test: https://search.google.com/test/rich-results URL'yi yapıştırın, "Test URL" deyin. Hangi rich result'lara uygun olduğunu gösterir.
- Schema Markup Validator: https://validator.schema.org/ Bu, schema'nızın syntax açısından doğru olup olmadığını kontrol eder.
- Chrome DevTools'tan hızlı kontrol: // Sayfada kaç schema var? document.querySelectorAll('script[type="application/ld+json"]').length
// Hepsini görüntüle
Array.from(
document.querySelectorAll('script[type="application/ld+json"]')
).map(s => JSON.parse(s.textContent));
Sonuçlar — 3 Hafta Sonra
Metrik Önce Sonra Değişim
Indexlenen sayfa 38 109 +187%
"Kanal adı canlı izle" CTR %2.4 %4.8 +100%
AI Overviews'ta görünme 0 12 sayfa Yeni
Rich Results uyumlu 0 108 Yeni
Ortalama pozisyon 18.2 12.6 -5.6
Not: Bu rakamlar Google Search Console verilerine dayanmaktadır. Sektörünüze ve rekabete göre değişebilir, ancak en azından doğru yönde bir hareket görmeyi kesinlikle garanti ediyor.
Öğrendiklerim
- WordPress sitelerinin %90'ında Custom Post Type'lar için schema yok. Rank Math, Yoast gibi eklentiler her CPT için otomatik özel schema üretmez. Sizin yazmanız gerekir.
- Schema, "varsa iyi olur" değil — 2026'da "olmazsa olmaz". AI Overviews ve SGE, yapısal veri olmadan içeriğinizi referans almaz. Trafiğinizin önemli bir kısmı buradan gelecek.
- JSON-LD > Microdata. Google bunu açıkça söylüyor: JSON-LD tercih edilir. Microdata ile HTML'inizi karıştırmayın, ayrı script bloğunda tutun.
- Tek doğru schema yok. Her sayfaya farklı schema'lar birlikte (multiple JSON-LD blocks) eklenebilir. Bir kanal sayfasında 5 ayrı schema bulunabilir: TelevisionChannel + BroadcastEvent + VideoObject + FAQPage + BreadcrumbList.
- Tarih alanlarını dinamik tutun. startDate gibi alanları PHP date() ile her sayfa yüklemesinde güncelleyin. Eski tarih = Google'a "bu sayfa güncel değil" sinyali. Sıradaki Yazı Bir sonraki yazıda Core Web Vitals optimizasyonu — özellikle 80+ görseli olan ve 10+ reklam iframe'i bulunan yoğun video sitelerinde LCP'yi 3 saniyenin altına çekmenin yollarını anlatacağım. Sorularınızı, eklemelerinizi yorumlara yazabilirsiniz. Tartışmaya açığım — özellikle sizin sitelerinizde benzer schema implementasyonları nasıl gitti, hangi sorunlarla karşılaştınız?
Kullanılan Kaynaklar:
• Schema.org — BroadcastService: https://schema.org/BroadcastService
• Schema.org — TelevisionChannel: https://schema.org/TelevisionChannel
• Schema.org — BroadcastEvent: https://schema.org/BroadcastEvent
• Google — Video Structured Data: https://developers.google.com/search/docs/appearance/structured-data/video
• Google — FAQ Structured Data: https://developers.google.com/search/docs/appearance/structured-data/faqpage
• Örnek Çalışma: Canlı TV
Top comments (1)
Uzun zamandır arıyordum, teşekkürler!