Headless commerce hakkındaki en büyük endişe SEO’dur. Mağaza vitrininiz bir JavaScript uygulamasıysa, Google onu düzgün indexler mi? Kısa cevap: evet, eğer SSR/SSG’yi doğru uygularsanız. Uzun cevap meta tagları, structured data, sitemapları ve birkaç headless’e özel zorluğu içerir.

Problem: Client-Side Rendering

Tamamen client-side rendered (CSR) React uygulaması tarayıcıya (ve Googlebot’a) boş bir HTML kabuğu gönderir:



  

Google JavaScript’i render edebilir, ancak daha yavaş, daha az güvenilir ve ayrı bir rendering kuyruğu kullanır. Kritik e-ticaret sayfaları — ürünler, kategoriler, landing sayfaları — indexlenebilir içerik için asla client-side rendering’e bağımlı olmamalıdır.

Çözüm: SSR ve SSG

Next.js ve Nuxt, server-side rendering (SSR) ve static site generation (SSG) sağlar. Bunlarla ürün sayfalarınız tamamen render edilmiş HTML olarak teslim edilir:



  Blue Widget - YourStore
  
  


  

Blue Widget

$29.99

Premium blue widget with stainless steel construction...

Next.js: ISR (Incremental Static Regeneration)

WooCommerce ürün sayfaları için ideal yaklaşım:

// app/products/[slug]/page.js

export async function generateStaticParams() {

const products = await fetchAllProductSlugs();

return products.map(p => ({ slug: p.slug }));

}

export async function generateMetadata({ params }) {

const product = await fetchProduct(params.slug);

return {

title: ${product.name} | YourStore,

description: product.short_description,

openGraph: {

title: product.name,

description: product.short_description,

images: [{ url: product.images[0]?.src }],

type: 'website'

}

};

}

export default async function ProductPage({ params }) {

const product = await fetchProduct(params.slug);

return ;

}

// Revalidate every 5 minutes

export const revalidate = 300;

Sayfalar build zamanında önceden render edilir ve eskidiğinde arka planda yeniden oluşturulur. Googlebot her zaman tamamen render edilmiş HTML alır.

Meta Tag Yönetimi

Geleneksel WooCommerce’de Yoast veya RankMath meta tagları yönetir. Headless’te bunları frontend frameworkünüzde yönetirsiniz.

Dinamik Meta Tagları (Next.js App Router)

// lib/seo.js

export function generateProductMeta(product) {

const title = product.yoast_head_json?.title || ${product.name} | YourStore;

const description = product.yoast_head_json?.og_description ||

stripHtml(product.short_description).substring(0, 160);

return {

title,

description,

openGraph: {

title: product.yoast_head_json?.og_title || product.name,

description,

url: https://yourstore.com/products/${product.slug},

images: product.images.map(img => ({

url: img.src,

width: 800,

height: 800,

alt: img.alt || product.name

})),

type: 'website',

siteName: 'YourStore'

},

twitter: {

card: 'summary_large_image',

title: product.name,

description,

images: [product.images[0]?.src]

},

alternates: {

canonical: https://yourstore.com/products/${product.slug}

}

};

}

Yoast Verilerini Kullanma

WordPress backend’inizde Yoast SEO kuruluysa, REST API aracılığıyla SEO verilerini sunar:

// Fetch product with Yoast SEO data

const product = await fetch(

${WP_URL}/wp-json/wp/v2/product/${id}?_fields=yoast_head_json

);

const yoast = product.yoast_head_json;

// Use Yoast's pre-computed meta

const meta = {

title: yoast.title,

description: yoast.og_description,

canonical: yoast.canonical,

robots: yoast.robots

};

Structured Data (Schema.org)

Arama sonuçlarında rich snippet’ler için ürün şeması kritiktir. Bunu server-side oluşturun:

function generateProductSchema(product) {

const schema = {

'@context': 'https://schema.org',

'@type': 'Product',

name: product.name,

description: stripHtml(product.short_description),

image: product.images.map(img => img.src),

sku: product.sku,

brand: {

'@type': 'Brand',

name: product.brands?.[0]?.name || 'YourStore'

},

offers: {

'@type': 'Offer',

url: https://yourstore.com/products/${product.slug},

priceCurrency: 'USD',

price: product.price,

availability: product.stock_status === 'instock'

? 'https://schema.org/InStock'

: 'https://schema.org/OutOfStock',

seller: {

'@type': 'Organization',

name: 'YourStore'

}

}

};

// Add reviews if available

if (product.rating_count > 0) {

schema.aggregateRating = {

'@type': 'AggregateRating',

ratingValue: product.average_rating,

reviewCount: product.rating_count

};

}

return schema;

}

// In your page component

Close Search Window