TecofRender, editörün kaydettiği sayfayı yayında çizer. Veri getirmez: sayfayı sunucuda çekip renderer’a verirsiniz. Editörle aynı StudioConfig’i kullanmalısınız; config’te olmayan type’lar sessizce atlanır.
"use client";
import { TecofRender, type PuckPageData } from "@tecof/theme-editor";
import { editorConfig } from "@/app/editor-config";
export default function RenderClient({ data, cmsData }: { data: PuckPageData; cmsData?: Record<string, unknown> | null }) {
return <TecofRender data={data} config={editorConfig} cmsData={cmsData} />;
}| Prop | Tip | Açıklama |
|---|---|---|
data | PuckPageData | Yayınlanacak doküman (content, root, zones) |
config | StudioConfig | Editörle aynı bileşen kaydı |
cmsData | Record<string, unknown> | null | CMS şablon sayfasının kaydı; bileşenlere puck.metadata.cmsData olarak iletilir |
className | string? | Kök elemana ek sınıf |
Renderer ne yapar#
Her render’da:
config.migrationsvarsa dokümanı yükseltir (İzinler ve migration).- Katmanlar’da gizlenen (
_hidden) düğümleri atlar; yalnız gizli çocukları olan slot boş sayılır. - Her düğümün
_tecofStylestoken’larını sınıflara derler veclassName’e ekler. - Slot alanlarını hazır slot elemanları olarak bileşene verir;
repeatSource’lu slotları satır başına tekrarlar. - Sayfaya şunları basar:
| Çıktı | İçerik |
|---|---|
<style data-tecof-styles> | Dokümanda kullanılan tüm stil sınıflarının CSS’i (masaüstü-öncelikli, bkz. Stil editörü) |
<style data-tecof-theme> | Çözülmüş temanın --theme-* değişkenleri (karanlık mod açıksa :root.dark bloğu da) |
<link> + <style data-tecof-font-faces> | Google Fonts ve yüklenen fontlar |
<style data-tecof-animations> | Giriş animasyonu anahtar kareleri |
<script data-tecof-interactions> | Etkileşim kuralları (yalnız kullanılıyorsa) |
<script data-tecof-darkmode> | Karanlık mod ayarı (yalnız config.darkMode açıksa) |
İstemcide küçük bir çalışma zamanı görününce animasyon (reveal), parallax, etkileşimler ve karanlık mod düğmesini bağlar. Sayfayı TecofRender olmadan kendiniz render ediyorsanız aynı davranış için initInteractions(document) ve initDarkMode(document) dışa aktarılır.
Sayfa verisini çekmek#
Tecof temaları sayfayı vitrin ucundan alır:
const THEME_ID = process.env.NEXT_PUBLIC_THEME_ID!;
const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/store/render?themeId=${THEME_ID}&locale=${locale}`, {
method: "POST",
headers: { "Content-Type": "application/json", "x-secret-key": process.env.NEXT_PUBLIC_MERCHANT_SECRET_KEY! },
body: JSON.stringify({ slug, themeId: THEME_ID, locale, showDraftData, previewToken }),
});
const json = await res.json();
const pageData = showDraftData ? json.data.draftData : json.data.publishedData;
const cmsData = json.data._cmsData ?? null;Taslak önizleme (showDraftData) backend’de imzalı previewToken ister; token geçersizse yanıt sessizce yayınlanmış içeriğe düşer. Vitrin anahtarı tarayıcıda gezdiği için tek başına taslak okuma yetkisi sayılmaz.
Yanıt sayfa verisinin yanında SEO alanlarını (metaTitle, metaDescription, ogImage, noIndex), sayfaya özel kodu (customHeadCode, customBodyCode) ve çok dilli adres bilgisini (localizedSlug, slugAlternates, redirectTo) taşır; ayrıntı: Tema SEO’su ve Public API. Aynı akış için TecofApiClient.getPublishedPage(slug, locale) de kullanılabilir (API istemcisi).
CMS şablon sayfaları#
Bir koleksiyonun şablon sayfası /<koleksiyon>/<içerik> adresinde render edilirken backend şablondaki token’ları kayıt verisiyle doldurur ve yanıtla birlikte ham kaydı _cmsData olarak döner. Renderer token’ları yeniden çözmez; kaydı bileşenlere puck.metadata.cmsData olarak iletir.
| Token | Değer |
|---|---|
{{ data.<alan> }} ya da {{ <alan> }} | Kaydın alanı (çok dilli alan istek diline göre çözülür) |
{{ url }} | Render edilen sayfanın tam adresi |
{{ siteName }} | Mağaza adı (ör. "{{ name }} | {{ siteName }}" meta başlığı) |
{{ locale }}, {{ itemSlug }}, {{ collectionSlug }} | İstek dili ve o dildeki adres parçaları |
{{ publishedDate }} | Okunur yayın tarihi (istek dilinde) |
{{ _refs.<alan>.slug }} | Referans alanının tam nesnesi (alanın kendisi etiket olarak çözülür) |
- Prop’un değeri yalnız token ise (
"{{ data.gallery }}") dizi/nesne değeri olduğu gibi yerleştirilir; metne gömülü token metne çevrilir, bulunamayan gömülü token boş metne döner. - Meta başlık ve açıklama da aynı çözümden geçer.
- Editörde metin alanlarındaki
{ }düğmesi token’ı ekler (CMS veri bağlama);{{ item.* }}token’ları ise repeat zone’a aittir ve kütüphane tarafından çözülür (Repeat zone).
Bileşen ham kayda ihtiyaç duyarsa:
render: ({ puck, className }) => {
const cms = puck.metadata?.cmsData as { title?: unknown } | null;
return <article className={className}>{/* cms?.title … */}</article>;
}TecofPicture#
UploadedFile kaydından doğru medya adresini seçer, görsel ve videoyu ayırt eder, boyut varyantlarını (thumbnail, medium, large, full) kullanır.
import Image from "next/image";
import { TecofPicture } from "@tecof/theme-editor";
<TecofPicture data={file} alt="Ürün görseli" size="large" />
<TecofPicture data={file} fill />
<TecofPicture data={file} ImageComponent={Image} imageProps={{ quality: 85, priority: true }} />
<TecofPicture data={file} fancybox fancyboxName="product-gallery" />| Prop | Tip | Açıklama |
|---|---|---|
data | UploadedFile | null | undefined | Dosya kaydı (UploadField değerinin bir öğesi) |
alt | string | null | Alternatif metin |
size | thumbnail | medium | large | full | Boyut varyantı |
fill | boolean | Üst kapsayıcıyı kaplar (position: absolute) |
loading | lazy | eager | Yükleme stratejisi |
width, height | number | Boyutlar |
className, imgClassName, style, imgStyle | — | Kapsayıcı ve img için sınıf/stil |
usePlaceholder, blurDataURL | — | Bulanık yer tutucu |
ImageComponent, imageProps | — | Özel görsel bileşeni (ör. Next.js Image) ve ek prop’ları |
fancybox, fancyboxName | — | Lightbox galerisi |
- Odak noktası: dosyada
focalPoint: { x, y }varsaobject-position: "X% Y%"uygulanır;object-fit: coverkırpmalarında seçilen nokta kadrajda kalır. KendiimgStyle.objectPositiondeğeriniz kazanır; odak yoksa ya da merkezdeyse çıktı değişmez. Yardımcılar:focalPointToObjectPosition,clampFocalPoint,isDefaultFocalPoint,DEFAULT_FOCAL_POINT. - CMS referans kaydı (
type: "image/reference") dosya değildir;nullrender edilir. Stok görsel gibi harici dosyalar kayıttaki mutlakurl’i kullanır.
Powered by bandı#
Panelde (Ayarlar → Powered by bandı) tanımlanan “Powered by Tecof” bandını basar. Temada elle yazmayın; bileşeni kullanın.
import { PoweredBy } from "@tecof/theme-editor";
// Layout (SSR): sunucudaki merchant-info ile ilk boyama; askı/yapım aşamasında null verin
const band = merchantInfo.isSuspended || merchantInfo.isUnderConstruction ? null : merchantInfo.poweredBy ?? null;
<PoweredBy initialData={band} defaultLanguage={merchantInfo.defaultLanguage} locale={locale} />
// <TecofProvider> içinde: kendisi çeker (SWR, 10 dk tekilleştirme)
<PoweredBy />| Prop | Açıklama |
|---|---|
locale | Dil; verilmezse Studio dili → <html lang> → varsayılan dil → ilk dil |
defaultLanguage | SSR’da merchantInfo.defaultLanguage; verilmezse dil flaşı olabilir |
mode | light / dark; verilmezse <html class="dark"> → prefers-color-scheme |
initialData | SSR’dan gelen merchantInfo.poweredBy; null = band yok, undefined = kendisi çeker |
apiUrl, secretKey | Provider dışında çekmek için |
renderBoth | İki varyantı da basar, seçimi CSS yapar (JS’siz sıfır flaş) |
revalidateOnMount, className | — |
Hak yoksa (showPoweredBy=false), mağaza askıdaysa ya da yapım aşamasındaysa bileşen hiçbir şey basmaz (bu bayrakları yalnız kendi çektiği merchant-info’dan okur; SSR yolunda süzgeci tema uygular). Kendi işaretlemenizi basmak için usePoweredBy(options) → { band, html, css, js, visible, isLoading, error, refresh, … }.
Yapım aşaması sayfası#
import { UnderConstruction } from "@tecof/theme-editor/under-construction";
<UnderConstruction title="Çok yakında" description="Mağazamız hazırlanıyor." logoUrl={logo} accentColor="#9ae600" />Prop’lar: title, description, subtitle?, logoUrl?, accentColor?.
Etkileşimler#
Inspector’ın Etkileşimler sekmesinde tanımlanan kurallar (click / hover → scrollTo, toggleClass, show, hide, toggle; hedef bir düğüm, self ya da sayfa başı top) düğümün _interactions prop’unda saklanır. _startHidden işaretli düğüm bir eylem onu gösterene kadar gizli başlar. TecofRender kuralları kendisi bağlar; özel render için collectInteractionRegistry(doc) + initInteractions(document) kullanılır.