Next.js
MarkdownNext.js App Router kullanan bir mağazada SSR, script ve oturum açmış müşteri entegrasyonu.
Bu sayfa, SSR yönteminin Next.js App Router’daki uygulamasını anlatır. Ek paket kurulumu gerekmez; next ve react yeterlidir.
Ortam değişkenleri
Bölüm başlığı “Ortam değişkenleri”NEXT_PUBLIC_SAYPROOF_BASE=https://api.sayproof.exampleNEXT_PUBLIC_SAYPROOF_SITE_KEY=SITE-ANAHTARINIZNEXT_PUBLIC_SAYPROOF_SCRIPT=https://cdn.sayproof.example/sayproof.jsSAYPROOF_SSR_KEY=SUNUCU-ANAHTARINIZSAYPROOF_CHANNEL=webNEXT_PUBLIC_önekli değerler tarayıcıya aktarılır; site anahtarı ve adresler gizli değildir.- Sunucu anahtarı
SAYPROOF_SSR_KEYöneksiz tanımlanır ve tarayıcıya aktarılmamalıdır. - Sunucunuz Sayproof’a farklı bir adres üzerinden erişiyorsa (örneğin iç ağ) ayrıca
SAYPROOF_BASEdeğişkenini tanımlayın.
Sunucudan istek
Bölüm başlığı “Sunucudan istek”Sunucu anahtarını okuyan kodu ayrı bir dosyada tutun ve dosyanın başına import "server-only" satırını ekleyin. Bir client component bu dosyayı içe aktarmaya çalışırsa build başarısız olur; böylece anahtar yanlışlıkla tarayıcı bundle’ına girmez.
import "server-only";
const base = process.env.SAYPROOF_BASE || process.env.NEXT_PUBLIC_SAYPROOF_BASE;
export async function sayproofReviews(product: string, name: string, locale: string) { const query = new URLSearchParams({ product, name, lang: locale, channel: process.env.SAYPROOF_CHANNEL ?? "web", }); try { const answer = await fetch(`${base}/v1/ssr?${query}`, { headers: { Authorization: `Bearer ${process.env.SAYPROOF_SSR_KEY}` }, next: { revalidate: 60 }, signal: AbortSignal.timeout(1500), }); return answer.ok ? await answer.json() : null; } catch { return null; }}Ürün sayfası
Bölüm başlığı “Ürün sayfası”import Script from "next/script";import { sayproofReviews } from "@/lib/sayproof.server";
export default async function ProductPage({ params }) { const product = await getProduct(params.slug); const reviews = await sayproofReviews(product.sku, product.name, params.locale);
return ( <> <div key={product.sku} data-review-mount data-review-product={product.sku} data-review-product-name={product.name} data-review-locale={params.locale} suppressHydrationWarning dangerouslySetInnerHTML={{ __html: reviews?.html ?? "" }} /> <Script id="sayproof" type="module" strategy="afterInteractive" crossOrigin="anonymous" src={process.env.NEXT_PUBLIC_SAYPROOF_SCRIPT} data-review-site-key={process.env.NEXT_PUBLIC_SAYPROOF_SITE_KEY} data-review-base={process.env.NEXT_PUBLIC_SAYPROOF_BASE} data-review-locale={params.locale} /> </> );}Dikkat edilmesi gerekenler:
key={product.sku}: Varyant değiştiğinde React container’ı yeniden oluşturur; script yeni container’ı algılar ve bağlar.suppressHydrationWarning: Container’ın içeriği script tarafından yönetildiği için React’in içerik uyuşmazlığı uyarısını kapatır.dangerouslySetInnerHTML: Sunucudan gelenhtmlburada olduğu gibi kullanılır; ikinci bir sanitizer’dan geçirilmemelidir.router.refresh()sonrasında React container’ı yeni HTML ile yeniden oluşturursa script yeni içeriği algılar ve yeniden devralır.- Ürün grubunun tüm yorumlarını göstermek için grup kodunu kullanın, container’a
data-review-scope="group"attribute’unu ekleyin ve sunucudan gönderilen isteğe descope: "group"parametresini ekleyin.
Yapılandırılmış veri
Bölüm başlığı “Yapılandırılmış veri”Ürün sayfanız zaten bir Product JSON-LD’si içeriyorsa ikinci bir Product eklemeyin; puanı ve yorumları kendi nesnenize ekleyin. Escape kuralı ve örnek için: SSR › Yapılandırılmış veri.
const jsonLd = reviews?.json_ld?.aggregateRating ? { ...productJsonLd, aggregateRating: reviews.json_ld.aggregateRating, review: reviews.json_ld.review ?? [] } : productJsonLd;
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: jsonLdScript(jsonLd) }} />İçerik güvenliği politikası (CSP)
Bölüm başlığı “İçerik güvenliği politikası (CSP)”Nonce kullanıyorsanız <Script> bileşenine nonce değerini verin. Script, eklediği <style> öğelerine (#sayproof-style, #sayproof-style-form, #sayproof-style-lightbox) de aynı nonce değerini yazar.
Oturum açmış müşteri
Bölüm başlığı “Oturum açmış müşteri”Oturum açmış müşteri için formu sipariş numarası sormadan açmak üzere bir Route Handler yazılır ve container’a data-review-viewer="pending" attribute’u eklenir. Yöntemin tamamı ve Next.js örneği için: Oturum açmış müşteri.
Sipariş detayı sayfası
Bölüm başlığı “Sipariş detayı sayfası”Hesap bölümündeki sipariş detayı sayfasında siparişin ürünlerini sayfanın içinde değerlendirtmek için sunucu bileşeninde oturumdaki e-posta adresi ve sipariş numarasıyla Sayproof’a sorun, yanıtı data-review-order öğesinin içine yazın. sayproofOrderState fonksiyonu ve yanıtın değerleri için: Oturum açmış müşteri › Sipariş detayı sayfası. Oturum bilgisini kendi kimlik doğrulama kütüphanenizden alın; buradaki auth() yalnızca örnektir.
import Script from "next/script";import { auth } from "@/auth";import { sayproofOrderState } from "@/lib/sayproof-order.server";
export default async function OrderPage({ params }) { const session = await auth(); const state = await sayproofOrderState(params.id, session?.user?.email, params.locale);
return ( <> {state ? ( <div key={params.id} data-review-order={params.id} suppressHydrationWarning dangerouslySetInnerHTML={{ __html: state }} /> ) : null} <Script id="sayproof" type="module" strategy="afterInteractive" crossOrigin="anonymous" src={process.env.NEXT_PUBLIC_SAYPROOF_SCRIPT} data-review-site-key={process.env.NEXT_PUBLIC_SAYPROOF_SITE_KEY} data-review-base={process.env.NEXT_PUBLIC_SAYPROOF_BASE} data-review-locale={params.locale} /> </> );}Yanıt kişiye özeldir ve cache: "no-store" ile alınır; sayfanın bu bölümü önbelleğe alınmaz. Yanıtta ürün yoksa öğe hiç eklenmez.
Headless kullanım
Bölüm başlığı “Headless kullanım”Yorum listesini kendi bileşenlerinizle gösterecekseniz container’a data-review-mode="headless" attribute’unu ekleyin ve html yerine state_script değerini kullanın. Örnek için: Headless kullanım.
Hazır kit
Bölüm başlığı “Hazır kit”Sayproof ekibi, bu sayfadaki yöntemleri hazır bileşenler olarak içeren bir Next.js kiti sağlar: sunucudan istek ve JSON-LD birleştirme, varsayılan bileşen için container, headless kullanım için container, script etiketi, oturum açmış müşteri route’u, yorum listeleme, oylama ve bildirim client’ı ile sipariş detayı sayfası için Sayproof isteği (fetchSayproofOrder()), yanıtı güvenle yazan etiket (sayproofOrderStateScript()) ve bileşen (<SayproofOrderReviews>). fetchSayproofOrder() yanıtta ürün yoksa ya da istek başarısız olursa null döndürür; <SayproofOrderReviews> bu durumda hiçbir şey çizmez. Kit mağaza reposuna kopyalanır; paket kurulumu gerektirmez ve es5 hedefli TypeScript ayarlarıyla derlenir. Kitin kullanılması zorunlu değildir; bu sayfadaki kod aynı işi görür.