Skip to content

SEO ve Rich Snippets (Arama Motoru Optimizasyonu)

Hreflang, canonical, dinamik meta etiketleri ve JSON-LD Schema.org ile kurs, eğitmen ve organizasyon sayfalarının Google'da zengin sonuçlarla görünmesi.

Achidemy’de arama motoru optimizasyonu (SEO) ve zengin sonuçlar (rich snippets) için global hreflang/canonical etiketleri, sayfa bazlı dinamik meta (title, description, Open Graph, Twitter Card) ve JSON-LD Schema.org verileri kullanılır. Bu sayfa bu yapının nerede ve nasıl uygulandığını açıklar.

  1. Root layout: Tüm sayfalarda canonical ve hreflang link’leri dinamik üretilir (app/root.tsx).
  2. Kurs detay: course.$id route’unda meta fonksiyonu ve Course/Offer/AggregateRating JSON-LD.
  3. Eğitmen profil: user.$username route’unda meta + ProfilePage JSON-LD.
  4. Platform kimliği: $lang layout’unda Organization JSON-LD (tüm dil sayfalarında).

Global Hreflang ve Canonical (Root Layout)

Section titled “Global Hreflang ve Canonical (Root Layout)”

Dosya: app/root.tsx

  • Amaç: Her sayfanın dil varyasyonlarını arama motoruna bildirmek; kopya içerik cezasını önlemek.
  • Veri: useLocation() ile mevcut pathname alınır; desteklenen dillerden biri URL önekiyse (/tr/, /en/, /de/, /fr/, /es/, /ja/) çıkarılarak basePath (dil öneki olmadan rota) hesaplanır.
  • baseUrl: Production için sabit (örn. https://achidemy.net); deploy edilen alan adına göre güncellenir.
EtiketAçıklama
<link rel="canonical" href="...">Varsayılan (ana) sayfa URL’i; İngilizce (/en) canonical kabul edilir.
<link rel="alternate" hreflang="tr" href="...">Her dil için alternatif URL (tr, en, de, fr, es, ja).
<link rel="alternate" hreflang="x-default" href="...">Dil eşleşmezse gösterilecek varsayılan sayfa (genelde /en).

Örnek: /tr/courses için canonical https://achidemy.net/en/courses, hreflang’ler .../tr/courses, .../en/courses, vb.


Dosya: app/routes/course.$id.tsx

  • Title: `{course.title} | Achidemy`
  • Description: Açıklamadan HTML temizlenir, 160 karaktere kısaltılır; yoksa varsayılan metin.
  • Open Graph: og:title, og:description, og:image (thumbnail veya varsayılan), og:type: website
  • Twitter Card (X): twitter:card = summary_large_image (meta etiket adı aynı kalır; X/Twitter paylaşım önizlemesi için kullanılır).

Tüm değerler loader’dan gelen course verisine göre dinamik üretilir.

  • @type: Course
  • name, description: Kurs başlığı ve açıklaması (HTML’siz).
  • provider: Organization (Achidemy).
  • creator: Eğitmen adı (Person).
  • image: Kurs thumbnail URL’i.
  • offers: Offer — fiyat, priceCurrency (veya bölgesel), category: Paid.
  • aggregateRating: Yalnızca reviewsCount > 0 ve rating > 0 ise eklenir; AggregateRating (ratingValue, reviewCount, bestRating, worstRating).

Böylece Google arama sonuçlarında kurs sayfaları yıldız ve fiyat bilgisiyle (rich snippet) görünebilir.


Dosya: app/routes/bundle.$slug.tsx

  • Bu route’ta sayfa bazlı meta() export’u yok; dinamik başlık, açıklama ve Open Graph etiketleri kurs sayfasındaki gibi üretilmez.
  • Global SEO: root.tsx içindeki canonical / hreflang (GlobalSeoTags) ve $lang layout’taki Organization JSON-LD tüm dil önekli sayfalara uygulanır; paket URL’leri de bu yapının içinde kalır.
  • Öneri (ileri geliştirme): Kurs detayıyla aynı kalitede paylaşım önizlemesi için bundle.title, bundle.description, thumbnailUrl ile meta + isteğe bağlı Product veya Offer JSON-LD eklenmesi.

Detaylı UI ve loader mantığı: Kurs ve Paket Vitrin Sayfaları.


Dosya: app/routes/user.$username.tsx

  • Title: `{user.name} - Online Kurs Eğitmeni | Achidemy`
  • Description: Bio’dan HTML temizlenir, 160 karakter; yoksa “{user.name} tarafından hazırlanan en iyi online kursları keşfedin.”
  • Open Graph: og:title, og:description, og:image (user.image veya user.googleImage veya varsayılan avatar).
  • @type: ProfilePage
  • mainEntity: Person — name, description (bio), image, jobTitle (eğitmen unvanı veya “Eğitmen”), worksFor: Organization (Achidemy).

Eğitmen aramalarında profil sayfasının daha anlamlı ve zengin görünmesi hedeflenir.


Dosya: app/routes/$lang.tsx

Tüm dil önekli sayfalarda (layout seviyesinde) tek bir Organization JSON-LD script’i render edilir:

  • @type: Organization
  • name: Achidemy
  • url: Production ana sayfa URL’i
  • logo: Platform logosu tam URL’i
  • description: Kısa platform açıklaması
  • sameAs: X (Twitter), LinkedIn, Instagram vb. sosyal medya profilleri

Böylece “Achidemy” aramasında Knowledge Graph / bilgi paneli için temel veri sağlanır.


  • Canonical/hreflang: Sadece root’ta; route bazlı ek canonical (örn. kurs sayfasında) ihtiyaca göre eklenebilir.
  • JSON-LD: dangerouslySetInnerHTML ile <script type="application/ld+json"> içine JSON.stringify(...) yazılır; XSS için veri kaynağı güvenilir (loader/DB) olmalıdır.
  • Görsel URL’leri: Varsayılan OG/logo URL’leri production domain’e göre güncellenmelidir.

  • app/root.tsx — GlobalSeoTags, canonical, hreflang.
  • app/routes/course.$id.tsx — meta, Course JSON-LD.
  • app/routes/bundle.$slug.tsx — Paket vitrin; şu an route-özel meta yok (bkz. yukarıdaki bölüm).
  • app/routes/user.$username.tsx — meta, ProfilePage JSON-LD.
  • app/routes/$lang.tsx — Organization JSON-LD.