Panduan Sanity SEO
Sanity stores konten sebagai JSON dan emits zero HTML — Anda frontend decides Anda SEO. rendering modes, Portable Text, SEO object, sitemaps, draft-mode noindex, JSON-LD, dan plugins.
Bahasa
Sanity adalah sebuah CMS headless itu stores konten sebagai structured JSON di -nya konten Lake dan produces no HTML — so Anda frontend framework (Next.js, Astro, Remix) decides everything tentang Anda SEO. single biggest lever adalah rendering: SSG dan SSR ship complete HTML dan adalah safe; CSR adalah risky because LLM-crawler rendering contracts vary oleh provider. Portable Text adalah sebuah JSON AST, not HTML, so frontend harus serialize ini. bangun reusable SEO object di konten model, generate sitemaps dan JSON-LD programmatically, pertahankan drafts out dari indeks dengan sebuah X-Robots-Tag: noindex header, dan gunakan sanity-plugin-seo (not deprecated Yoast pane). SEO success di Sanity comes dari intentional structure, not plugins.
TL;DR — Sanity adalah sebuah place untuk store konten, not sebuah place itu publishes halaman web. ini hands Anda konten out sebagai data (JSON), not sebagai finished HTML — so sebuah separate situs web dibangun dengan something like Next.js atau Astro memiliki untuk turn itu data ke halaman. itu berarti none dari usual SEO stuff (judul, sitemaps, canonical tags) happens automatically cara ini melakukan pada WordPress. biggest aturan: bangun Anda halaman pada sebuah server atau di bangun time, not entirely di pengunjung’s browser, atau mesin pencari dan AI alat dapat tidak pernah see Anda konten.
What Sanity actually adalah
People sometimes assume Sanity adalah “a CMS like WordPress,” (terjemahan) “sebuah CMS like WordPress,” dan itu’s where confusion starts. Sanity adalah sebuah CMS headless. ini melakukan two things: ini stores Anda konten (di something Sanity panggilan konten Lake) dan ini gives konten editors sebuah place untuk write (Sanity Studio). What ini melakukan not melakukan adalah produce sebuah single line dari HTML. Anda konten comes out sebagai data terstruktur — JSON — melalui sebuah API.
Evidence for this claim Sanity stores structured content in Content Lake and provides it to applications as data rather than finished site HTML. Scope: Sanity platform architecture; the frontend owns public rendering. Confidence: high · Verified: Sanity: Content Lakeitu berarti sebuah separate situs web — dibangun dengan sebuah framework like Next.js, Astro, atau Remix — memiliki untuk fetch itu JSON dan bangun actual halaman people dan mesin pencari see. Sanity stores konten; Anda frontend publishes ini. setelah Anda internalize itu one kalimat, almost everything tentang Sanity SEO membuat sense.
one decision itu penting sebagian besar: rendering
Because Anda frontend membangun halaman, how ini membangun them decides Anda SEO. There adalah two safe cara dan one risky cara:
- di bangun time (SSG) — halaman adalah pre-dibangun ke plain HTML files. Fast dan search-friendly.
- pada sebuah server, per permintaan (SSR) — server membangun full halaman dan mengirim ini. juga search-friendly, selalu fresh.
- di pengunjung’s browser (CSR) — server mengirim sebuah near-empty shell dan JavaScript fills ini di afterward. ini adalah risky one.
Google dapat eventually run JavaScript dan read sebuah CSR halaman, tetapi ini adalah slower dan less reliable — dan today crawler behind ChatGPT, Claude, dan Perplexity typically don’t render JavaScript di semua, so mereka hanya see empty shell. itu’s not sebuah fixed aturan, though: Google’s Gemini jawaban reuse Googlebot’s own rendering infrastructure, so perilaku sudah varies oleh provider dan isn’t guaranteed untuk stay yang sama. So jika Anda ingin tampilkan up di Google dan get cited oleh AI alat, bangun Anda HTML pada server atau di bangun time.
Evidence for this claim Google can render JavaScript pages, but browser-only content depends on a separate rendering stage. Scope: Google Search only; this record does not support claims about named AI crawlers. Confidence: high · Verified: Google: JavaScript SEO basics”where did my SEO settings go?” (terjemahan) “where melakukan my SEO settings go?” masalah
pada WordPress, sebuah plugin like Yoast quietly handled Anda judul, deskripsi meta, sitemap, dan tag canonical. Sanity memiliki no such thing. So someone memiliki untuk deliberately:
- tambahkan SEO fields (judul, deskripsi, social image) untuk konten di Sanity.
- Wire itu fields ke setiap halaman’s HTML di frontend.
- bangun sitemap, sebuah robots.txt, dan data terstruktur — semua di code.
None dari ini adalah hard. ini hanya won’t happen pada -nya own. sebuah lot dari “my Sanity site has no SEO” (terjemahan) “my Sanity situs memiliki no SEO” stories adalah really “nobody built the stuff a plugin used to do.” (terjemahan) “nobody dibangun stuff sebuah plugin digunakan untuk melakukan.”
Two things itu quietly go wrong
- Draft halaman getting ke Google. Sanity dapat sajikan unpublished drafts melalui -nya API. jika someone shares sebuah preview tautan dan sebuah crawler menemukan ini, itu draft dapat get terindeks. Anda memiliki untuk actively block itu.
- Body text itu’s invisible. Sanity stores rich text di sebuah special format called Portable Text — ini adalah data, not HTML. Anda frontend memiliki untuk convert ini. pada sebuah CSR halaman, itu conversion happens di browser, so AI crawler tidak pernah see Anda artikel text.
ingin full versi — four rendering modes, reusable SEO field setup, sitemaps, draft-mode protection, JSON-LD, dan which plugins untuk gunakan? Switch untuk Advanced tab.
TL;DR — Sanity adalah konten-neutral: ini stores structured JSON di konten Lake dan emits zero HTML, so frontend’s rendering mode decides everything. SSG dan SSR ship complete HTML dan adalah safe; CSR adalah risky one because LLM crawler don’t execute JavaScript, dan Google deprecated dynamic rendering sebagai sebuah workaround. Portable Text adalah sebuah JSON AST itu frontend harus serialize. bangun reusable
seoobject di konten model dengan overrides (not requirements) viacoalesce(), generate sitemaps dan JSON-LD programmatically dari existing fields, dan pertahankan drafts out dari indeks dengan sebuahX-Robots-Tag: noindexheader pada setiap preview respons. gunakansanity-plugin-seo— tidak pernah deprecated Yoast pane — tetapi remember “SEO success in Sanity comes from intentional structure, not plugins.” (terjemahan) “SEO success di Sanity comes dari intentional structure, not plugins.”
Sanity adalah konten storage, not sebuah publisher
sebuah berguna pertama principle: Sanity touches Anda konten, tidak pernah Anda rendering.
konten Lake stores everything sebagai structured JSON, queried dengan GROQ
(Sanity’s kueri language) atau REST. Sanity Studio — editing UI — adalah sebuah React
single-halaman app itu biasanya lives pada -nya own .sanity.studio subdomain dan isn’t
something Anda indeks. Nothing di ini stack produces HTML.
So entire SEO surface lives di Anda frontend framework. sebagai Webstacks put ini, “Sanity handles content storage and editing, while your frontend framework handles SEO output.” (terjemahan) “Sanity handles konten storage dan editing, while Anda frontend framework handles SEO output.” itu’s not sebuah limitation — ini adalah whole headless model. Sanity’s own team frames ini well: “When using Sanity as a CMS, you’re doing headless SEO. Although this approach requires thoughtful technical implementation, it can liberate your content to help you reach more users across all channels.” (terjemahan) “When menggunakan Sanity sebagai sebuah CMS, Anda’re doing headless SEO. Although ini approach memerlukan thoughtful technical implementation, ini dapat liberate Anda konten untuk help Anda reach more pengguna di seluruh semua channels.” berfungsi adalah nyata, tetapi ini adalah yang sama berfungsi sebagai apa pun headless bangun (see SEO untuk sebuah CMS headless).
rendering mode adalah foundation
Because frontend membangun HTML, rendering decision adalah single sebagian besar consequential SEO choice pada sebuah Sanity situs. Four modes:
SSG — Static situs Generation. konten adalah fetched dari Sanity di bangun time dan baked ke static HTML disajikan dari sebuah CDN. Best-case SEO: fully-rendered HTML pada pertama permintaan, fast TTFB. Ideal untuk blog posts, marketing halaman, dan product/landing halaman. tradeoff adalah freshness — changed konten perlu sebuah rebuild (ISR solves ini).
SSR — rendering sisi server. konten adalah fetched per permintaan dan full HTML adalah rendered pada server. Excellent SEO, selalu fresh. gunakan ini untuk frequently updated konten. Tradeoff adalah infrastructure cost dan slightly higher TTFB daripada static files.
ISR — Incremental Static Regeneration (Vercel/Next.js). Static halaman regenerate di background, ideally triggered oleh sebuah Sanity webhook pada publish so halaman rebuilds moment sebuah editor hits publish. ini adalah best dari SSG’s speed dan SSR’s freshness untuk konten itu perubahan pada order dari hours atau days.
CSR — rendering sisi klien. sebuah HTML shell ships, lalu JavaScript fetches dari Sanity dan membangun DOM di browser. ini adalah worst SEO option: Googlebot memiliki untuk queue halaman untuk sebuah later render wave, timing adalah unpredictable, dan AI crawler dan banyak lainnya bot see hanya shell. CSR adalah acceptable hanya behind authentication untuk konten Anda tidak ingin terindeks anyway.
dan don’t reach untuk old shortcut: Google memiliki deprecated dynamic rendering (serving prerendered HTML untuk bot, CSR untuk pengguna). Officially, “dynamic rendering was a workaround and not a long-term solution,” (terjemahan) “dynamic rendering adalah sebuah workaround dan not sebuah panjang-istilah solusi,” dan Google now recommends “server-side rendering, static rendering, or hydration.” (terjemahan) “rendering sisi server, static rendering, atau hydration.” untuk sebuah Sanity situs, itu berarti SSG atau SSR — not sebuah bot-detection hack. (Full rendering treatment di JavaScript SEO.)
Evidence for this claim Google describes dynamic rendering as a workaround rather than a recommended long-term solution and recommends server-side rendering, static rendering, or hydration. Scope: Google Search guidance for JavaScript sites. Confidence: high · Verified: Google: Dynamic renderingPortable Text — Anda body copy adalah sebuah JSON AST
ini adalah paling Sanity-spesifik thing pada halaman. Sanity stores rich text sebagai
Portable Text: sebuah JSON abstract syntax tree, not HTML. Body copy di konten
Lake looks like sebuah array dari typed blocks, not <p> tags. Anda frontend memiliki untuk
serialize ini ke HTML sebelum apa pun crawler dapat read ini:
@portabletext/react— untuk React/Next.js.@portabletext/to-html— framework-agnostic (Astro, Remix, anything).- old
@sanity/block-content-to-reactadalah deprecated — don’t gunakan ini.
jika Anda render server-side atau di bangun time, serialization happens sebelum halaman adalah
dikirim dan crawler get full HTML. jika Anda render client-side, serialization runs
di browser. Because LLM-crawler rendering contracts vary oleh provider, CSR
Portable Text membuat sebuah coverage risk itu raw HTML menghindari. There’s juga sebuah handy GROQ
helper: pt::text(body) extracts semua plain text dari sebuah Portable Text field sebagai sebuah
string, which adalah perfect untuk feeding JSON-LD deskripsi without sebuah separate editor
field.
konten modeling untuk SEO — reusable SEO object
cleanest pattern, dan one Sanity’s own course teaches, adalah sebuah single
reusable seo object ditambahkan untuk setiap document jenis — not SEO fields copy-pasted per
jenis. key design principle dari Sanity Learn: “For the benefit of content
authors, fields relevant to SEO should not always be required. Instead, they should
be used to override some existing content, when provided.” (terjemahan) “untuk benefit dari konten
authors, fields relevant untuk SEO seharusnya not selalu menjadi diperlukan. Instead, mereka seharusnya
menjadi digunakan untuk override beberapa existing konten, when disediakan.”
dalam praktik itu berarti SEO fields adalah overrides dengan fallbacks, implemented dengan
GROQ’s coalesce():
"title": coalesce(seo.title, title, ""),
"description": coalesce(seo.description, excerpt, "")sebuah minimum viable seo object: metaTitle (≤65 chars), metaDescription
(≤155 chars), canonicalUrl, openGraphImage (1200×630), dan sebuah noIndex boolean.
tambahkan Sanity validation aturan untuk enforce itu character limits sebelum publish —
so editors catch masalah platform akan otherwise let melalui. gunakan slug
jenis dengan sebuah custom generation function, dan gunakan references untuk tautan internal so
URL perubahan propagate automatically. tambahkan sebuah hideFromSearch boolean dan filter ini out
dari both sitemap GROQ kueri dan halaman’s robots metadata.
Metadata, sitemaps, dan canonicals — semua dibangun di frontend
Metadata. di Next.js App Router, gunakan exported generateMetadata() function
(not inline <head> tags) so metadata doesn’t duplicate di seluruh nested layouts.
bangun one server-side helper itu takes sebuah GROQ hasil dan mengembalikan framework’s
metadata object — implement ini once, gunakan ini everywhere. Open Graph images dapat menjadi
generated dynamically dengan Next.js Edge OG generation, pulling konten straight dari
Sanity.
Sitemaps. There’s no auto-sitemap. Anda bangun ini dari sebuah GROQ kueri → URL array →
XML (sitemap.ts di Next.js, @astrojs/sitemap di Astro). selalu filter drafts dan
hidden halaman:
*[_type in ["page", "post"] && defined(slug.current) && hideFromSearch != true]gunakan _updatedAt (not _createdAt atau sebuah manual date) untuk lastModified, pertahankan
individual sitemap files di bawah 50 000 URLs dengan sebuah indeks untuk larger situs, dan
trigger regeneration via sebuah Sanity webhook pada publish/unpublish so ini tidak pernah goes stale.
Canonicals. Set canonical URLs dari konten model, default untuk sebuah
self-referencing canonical, dan bangun absolute URLs dari sebuah single SITE_URL so
canonical tidak pernah drifts. (Mechanics di
Canonicalization.)
data terstruktur — generate ini, don’t author ini
right pattern adalah untuk generate JSON-LD programmatically dari existing konten fields di render time — tidak pernah bangun separate JSON-LD editor surface di Studio, which hanya membuat drift antara konten dan markup. Roboto Studio’s aturan adalah blunt: “Derive JSON-LD from existing fields, at render time, in code.” (terjemahan) “Derive JSON-LD dari existing fields, di render time, di code.” Sanity agrees — “JSON-LD is a powerful way to provide structured data to search engines — fortunately structured data is what Sanity does best.” (terjemahan) “JSON-LD adalah sebuah powerful cara untuk menyediakan data terstruktur untuk mesin pencari — fortunately data terstruktur adalah what Sanity melakukan best.”
gunakan pt::text(body) untuk pull plain text untuk schema deskripsi, TypeScript
package schema-dts untuk jenis safety, dan render ini dengan
<script type="application/ld+json">. Note itu “the JSON-LD markup can be
rendered anywhere in the page — it doesn’t need to be stored inside the
<head>.” (terjemahan) “ JSON-LD markup dapat menjadi
rendered anywhere di halaman — ini doesn’t perlu untuk menjadi stored inside
undefined.” Priority jenis untuk konten situs: artikel/BlogPosting,
BreadcrumbList, FAQPage, Organization, situs web.
Keeping drafts out dari Google — nyata-incident pitfall
Sanity’s perspective sistem controls draft visibilitas: published mengembalikan hanya
production konten; drafts mengembalikan draft documents untuk preview. selalu gunakan
published perspective di production API panggilan. tetapi itu alone isn’t enough,
because draft URLs leak. sebagai one developer recounted, danger adalah
“a client panicking because an unpublished landing page showed up in Google Search
Console. If a content editor shares that URL in Slack, and someone clicks it from a
browser that’s then crawled (it happens), the draft content can end up indexed.” (terjemahan) “sebuah client panicking because sebuah unpublished landing halaman showed up di Google Search
Console. jika sebuah konten editor shares itu URL di Slack, dan someone clicks ini dari sebuah
browser itu’s lalu di-crawl (ini happens), draft konten dapat end up terindeks.”
reliable defense adalah sebuah multi-layer one:
- gunakan
publishedperspective di production; tidak pernah expose sebuah unprotected preview endpoint. - tambahkan sebuah
X-Robots-Tag: noindexheader HTTP untuk setiap draft-mode/preview respons — bahkan jika sebuah draft URL leaks dan gets di-crawl, Googlebot respects header dan won’t indeks ini. (Don’t rely pada robots.txt untuk ini; sebuah header adalah more reliable daripada sebuah disallow untuk preview halaman.) - Validate preview secret server-side; tidak pernah reflect ini di redirect URL, dan scope preview-enable endpoint untuk Anda Studio’s origin.
Robots, redirects, image SEO, dan hreflang
robots.txt adalah sebuah static frontend file (app/robots.ts di Next.js). Block Studio
paths hanya jika mereka’re pada yang sama domain (Disallow: /studio/); don’t try untuk block
preview halaman dengan ini.
Redirects adalah sebuah genuine workflow win: store them sebagai Sanity documents (from,
to, statusCode) so konten team dapat manage redirects without sebuah developer
deploy, lalu implement them di Next.js middleware.ts atau sebuah CDN/Worker layer (tidak pernah
di Sanity itself). tambahkan validation aturan untuk mencegah loops dan invalid paths.
Image SEO: gunakan Sanity’s image CDN dengan ?auto=format untuk automatic WebP/AVIF,
manage teks alt di asset tingkat dengan document-tingkat overrides, gunakan vanity
filenames alih-alih hashed URLs, dan set hotspot/crop so automatic crops pertahankan
subject — which penting sebagian besar untuk OG images.
Hreflang: model locale variants sebagai separate Sanity documents referencing canonical versi, generate hreflang dari sebuah GROQ kueri returning semua locale slugs, dan give setiap locale halaman sebuah self-referencing canonical — tidak pernah canonical sebuah non-English halaman untuk English one.
Plugins — helpful, not sebuah substitute
sanity-plugin-seo— primary recommendation (22k+ downloads). Live SEO score, meta/OG preview, social cards, robots control, hreflang, readability. AI tier menambahkan keyword suggestions dan meta generation.sanity-plugin-seofields— sebuah alternative: 39 schema.org jenis, sebuah SEO Health Dashboard, dan Next.js helper functions (buildSeoMeta()).sanity-plugin-seo-pane— DEPRECATED. ini adalah old Yoast integration, dihapus karena sebuah outdated dependency. ini masih menampilkan up di old tutorials. Don’t gunakan ini.
honest framing, dari Yanatiev: “SEO success in Sanity comes from intentional structure, not plugins.” (terjemahan) “SEO success di Sanity comes dari intentional structure, not plugins.” Plugins surface fields dan give editorial feedback — mereka don’t replace proper konten modeling.
AI search dan AEO
2026 wrinkle: LLM training dan retrieval crawler (Anthropic, OpenAI, umum
crawl) typically don’t execute JavaScript today, so CSR Portable Text adalah largely
invisible untuk them regardless dari whether Googlebot dapat render ini — tetapi ini adalah
provider-spesifik dan not sebuah guaranteed contract. Google’s Gemini pipeline adalah
notable exception, since ini reuses Googlebot’s own rendering infrastructure, dan
lainnya providers’ perilaku dapat perubahan. Treat “no rendering” (terjemahan) “no rendering” sebagai safe assumption untuk
bangun untuk, not sebuah permanent law. Beyond rendering, two Sanity-friendly
tactics: sajikan clean markdown via konten negotiation when Accept: text/markdown
adalah present (Sanity’s @portabletext/markdown package converts Portable Text dengan no
extra authoring), dan monitor Bing specifically since Bing’s indeks feeds
ChatGPT’s browse respons. pada llms.txt, Sanity’s own Knut Melvær adalah skeptical —
“Probably don’t do llms.txt” (terjemahan) “Probably don’t melakukan llms.txt” untuk besar situs, because semua-atau-nothing scope dan
file-size limits membuat ini impractical; per-halaman konten negotiation adalah more granular.
Roboto Studio’s summary adalah right mindset: “AEO and SEO live on the same plumbing,
so we treat them as one job.” (terjemahan) “AEO dan SEO live pada yang sama plumbing,
so kami treat them sebagai one job.” (More di AI Search.)
myths worth killing
- “Sanity does SEO automatically like WordPress + Yoast.” (terjemahan) “Sanity melakukan SEO automatically like WordPress + Yoast.” No. Zero HTML, zero automatic anything.
- “Any rendering mode is fine if the content’s in Sanity.” (terjemahan) “apa pun rendering mode adalah fine jika konten’s di Sanity.” No. CSR breaks pengindeksan dan AI visibilitas; dynamic rendering adalah deprecated.
- “Drafts can’t be indexed.” (terjemahan) “Drafts dapat’t menjadi terindeks.” mereka dapat, jika sebuah preview URL leaks. gunakan
noindexheader. - “Portable Text is HTML.” (terjemahan) “Portable Text adalah HTML.” ini adalah sebuah JSON AST itu frontend harus serialize.
- “You need a JSON-LD editor in Studio.” (terjemahan) “Anda perlu sebuah JSON-LD editor di Studio.” No — generate ini dari existing fields.
AI summary
sebuah condensed take pada Advanced versi:
- Sanity adalah konten-neutral. ini stores structured JSON di konten Lake (queried via GROQ/REST) dan emits zero HTML. frontend (Next.js, Astro, Remix) produces semua SEO output. “Sanity does SEO like WordPress” (terjemahan) “Sanity melakukan SEO like WordPress” adalah sebuah myth.
- rendering mode adalah foundation. SSG dan SSR ship complete HTML dan adalah safe; ISR (webhook-triggered pada publish) menambahkan freshness; CSR adalah risky. Google deprecated dynamic rendering — gunakan SSR/static/hydration.
- LLM-crawler rendering varies oleh provider — raw HTML maximizes Portable Text coverage.
- Portable Text adalah sebuah JSON AST, not HTML. Serialize ini dengan
@portabletext/reactatau@portabletext/to-html;@sanity/block-content-to-reactadalah deprecated. gunakanpt::text(body)untuk extract plain text untuk JSON-LD. - konten modeling: one reusable
seoobject di seluruh semua jenis, fields sebagai overrides not requirements viacoalesce(), validation aturan enforcing limits, dan sebuahhideFromSearchflag filtered dari both sitemap dan robots metadata. - Sitemaps, metadata, canonicals, robots.txt adalah semua dibangun di frontend.
Filter drafts dari sitemap GROQ kueri, gunakan
_updatedAtuntuklastModified, dan regenerate via Sanity webhooks. - Generate JSON-LD programmatically dari existing fields di render time — tidak pernah sebuah
separate Studio editor. gunakan
schema-dts; ini dapat render anywhere, not hanya<head>. - pertahankan drafts out dari indeks: gunakan
publishedperspective di production dan tambahkan sebuahX-Robots-Tag: noindexheader untuk setiap preview respons. sebuah leaked draft URL memiliki caused nyata pengindeksan incidents. - Plugins:
sanity-plugin-seo(primary) atausanity-plugin-seofields. Yoastsanity-plugin-seo-paneadalah deprecated. “SEO success in Sanity comes from intentional structure, not plugins.” (terjemahan) “SEO success di Sanity comes dari intentional structure, not plugins.” - AEO: monitor Bing (feeds ChatGPT browse); sajikan markdown via konten
negotiation; Sanity advises terhadap
llms.txtuntuk besar situs.
Official documentation
Primary-source documentation dari mesin pencari dan Sanity.
- memahami JavaScript SEO Basics — crawl → render → indeks pipeline, JS canonicals, dan why blocked files don’t get rendered. core reference untuk apa pun Sanity frontend.
- Dynamic rendering (deprecated workaround) — why Google deprecated ini dan what untuk gunakan instead (SSR, static rendering, hydration).
- rendering untuk konten-Driven Web Apps — SSR vs. SSG vs. CSR tradeoffs untuk exactly jenis dari konten situs Sanity powers.
- Robots meta tag, data-nosnippet, dan X-Robots-Tag —
X-Robots-Tag: noindexheader HTTP digunakan untuk pertahankan draft/preview respons out dari indeks. - Intro untuk robots.txt — what robots.txt melakukan dan doesn’t melakukan (ini controls crawling, not pengindeksan dari leaked drafts).
Bing / Microsoft
- baru evergreen Bingbot (Microsoft Edge) — Bingbot rendering JavaScript via Edge; relevant since Bing’s indeks feeds ChatGPT browse.
- IndexNow / indexnow.org — push protocol untuk wire untuk Anda Sanity publish webhook.
Sanity
- SEO dengan Sanity — Sanity’s own master SEO guide.
- SEO Optimization course — full Next.js SEO course (schema jenis, dynamic sitemaps, JSON-LD).
- Presenting dan previewing konten (perspectives) —
publishedvs.draftsperspectives, basis dari draft-mode safety.
Quotes dari source
pada—record statements relevant untuk Sanity SEO. setiap tautan adalah sebuah deep tautan itu jumps untuk quoted passage pada source halaman.
Sanity — headless SEO model
- “When using Sanity as a CMS, you’re doing headless SEO. Although this approach requires thoughtful technical implementation, it can liberate your content to help you reach more users across all channels.” (terjemahan) “When menggunakan Sanity sebagai sebuah CMS, Anda’re doing headless SEO. Although ini approach memerlukan thoughtful technical implementation, ini dapat liberate Anda konten untuk help Anda reach more pengguna di seluruh semua channels.” — Sanity, SEO dengan Sanity. Jump untuk quote
- “SEO doesn’t have to be complicated. It’s a matter of taking content you’ve already responsibly structured with Sanity and rendering it in the format and places that search engines expect.” (terjemahan) “SEO doesn’t memiliki untuk menjadi complicated. ini adalah sebuah penting dari taking konten Anda’ve sudah responsibly structured dengan Sanity dan rendering ini di format dan places itu mesin pencari expect.” — Sanity Learn, SEO Optimization course. Jump untuk quote
- “For the benefit of content authors, fields relevant to SEO should not always be required. Instead, they should be used to override some existing content, when provided.” (terjemahan) “untuk benefit dari konten authors, fields relevant untuk SEO seharusnya not selalu menjadi diperlukan. Instead, mereka seharusnya menjadi digunakan untuk override beberapa existing konten, when disediakan.” — Sanity Learn, SEO schema jenis dan metadata. Jump untuk quote
- “JSON-LD is a powerful way to provide structured data to search engines—fortunately structured data is what Sanity does best.” (terjemahan) “JSON-LD adalah sebuah powerful cara untuk menyediakan data terstruktur untuk mesin pencari—fortunately data terstruktur adalah what Sanity melakukan best.” — Sanity Learn, Generating JSON-LD dynamically. Jump untuk quote
Google — dynamic rendering adalah deprecated
- “Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.” (terjemahan) “Dynamic rendering adalah sebuah workaround dan not sebuah panjang-istilah solusi untuk masalah dengan JavaScript-generated konten di mesin pencari.” — Google Search Central docs. Jump untuk quote
- Recommended instead: “server-side rendering, static rendering, or hydration.” (terjemahan) “rendering sisi server, static rendering, atau hydration.” Jump untuk quote
Industry — frontend owns SEO; structure beats plugins
- “Sanity handles content storage and editing, while your frontend framework handles SEO output.” (terjemahan) “Sanity handles konten storage dan editing, while Anda frontend framework handles SEO output.” — Webstacks, Sanity SEO. Read guide
- “AEO and SEO live on the same plumbing, so we treat them as one job.” (terjemahan) “AEO dan SEO live pada yang sama plumbing, so kami treat them sebagai one job.” — Roboto Studio / Jono Alford, AEO & SEO best practices untuk Sanity. Read post
- “SEO success in Sanity comes from intentional structure, not plugins.” (terjemahan) “SEO success di Sanity comes dari intentional structure, not plugins.” — Yanatiev, SEO best practices untuk Sanity CMS. Read post
- “Probably don’t do llms.txt.” (terjemahan) “Probably don’t melakukan llms.txt.” — Knut Melvær, Sanity, cara sajikan konten untuk agents. Read field guide
Sanity SEO checklist
sebuah pass dibangun sekitar how Sanity actually berfungsi — bangun things platform leaves untuk Anda frontend, dan lock down things itu quietly break.
rendering & konten ( foundation)
- halaman render mereka konten di HTML pada pertama permintaan (SSG atau SSR), not hanya setelah client-side JavaScript runs.
- No SEO-critical halaman depends pada CSR (raw HTML maximizes LLM-crawler coverage).
- ISR (jika digunakan) regenerates pada sebuah Sanity publish webhook, not hanya sebuah timer.
- Portable Text adalah serialized server-side dengan
@portabletext/reactatau@portabletext/to-html(not deprecatedblock-content-to-react).
konten model
- One reusable
seoobject pada setiap document jenis — not per-jenis duplication. - SEO fields adalah overrides via
coalesce(), dengan validation aturan enforcing judul/deskripsi length sebelum publish. - sebuah
hideFromSearch(ataunoIndex) boolean exists dan adalah filtered dari both sitemap GROQ kueri dan halaman’s robots metadata.
Frontend outputs
- Metadata wired dari GROQ ke
generateMetadata()(atau framework equivalent) — one reusable helper. - Sitemap generated dari GROQ, drafts/hidden filtered,
_updatedAtdigunakan untuklastModified, regenerated pada sebuah webhook. - Canonicals adalah absolute URLs dari sebuah single
SITE_URL, per-halaman dan self-referencing oleh default. - robots.txt exists di frontend;
.js/.cssadalah not blocked. - JSON-LD generated programmatically dari existing fields (artikel, Breadcrumb, FAQ, Organization), verified dengan Rich hasil Test.
Draft / preview safety
- Production API panggilan gunakan
publishedperspective. - setiap draft/preview respons mengirim sebuah
X-Robots-Tag: noindexheader. - Preview secret validated server-side dan scoped untuk Studio origin.
AEO & monitoring
- Bing Webmaster alat siapkan (Bing feeds ChatGPT browse); IndexNow pada publish.
- (Optional) markdown disajikan via konten negotiation untuk AI crawler.
mental models
1. Sanity stores, frontend publishes. konten Lake holds JSON; Anda framework produces setiap byte dari HTML dan setiap SEO signal. sebelum debugging apa pun Sanity SEO masalah, tanyakan: what adalah frontend actually sending crawler? Almost everything resolves untuk itu.
2. rendering mode adalah product. Pick oleh how konten perubahan:
- Mostly static (blog, docs, marketing) → SSG (rebuild atau ISR pada publish).
- Frequently changing, harus menjadi fresh → SSR.
- Hours/days cadence, ingin static speed → ISR (webhook-triggered).
- Behind sebuah login, not dimaksudkan untuk menjadi terindeks → CSR adalah acceptable.
- Public konten Anda ingin diperingkatkan atau cited oleh AI → tidak pernah CSR.
3. Overrides, not requirements.
SEO fields default untuk primary konten dan hanya override when sebuah editor fills them
di — implemented dengan coalesce(). ini mempertahankan editing experience clean dan
guarantees setiap halaman memiliki something untuk -nya judul dan deskripsi.
4. Generate, don’t author, markup. Sitemaps, JSON-LD, hreflang, dan canonicals adalah semua derived dari existing fields di code di render time. sebuah separate editor surface untuk apa pun dari them hanya membuat drift. “Derive from existing fields, at render time, in code.” (terjemahan) “Derive dari existing fields, di render time, di code.”
5. Defense secara mendalam untuk drafts.
published perspective di production adalah layer one; sebuah X-Robots-Tag: noindex header
pada setiap preview respons adalah layer two. tidak pernah rely pada sebuah single control untuk pertahankan
unpublished konten out dari indeks.
Sanity SEO — cheat sheet
rendering modes di sebuah glance
| Mode | Where HTML adalah dibangun | SEO | Best untuk | Watch out untuk |
|---|---|---|---|---|
| SSG | bangun time → static files | ✅ Best | Blogs, docs, marketing | Stale until rebuild |
| SSR | server, per permintaan | ✅ Best | Frequently-updated konten | Higher infra cost |
| ISR | Static + webhook regen | ✅ baik | Hourly/daily konten | Configure publish webhook |
| CSR | di browser | ⚠️ Risky | Logged-di dashboards | Invisible untuk AI crawler |
What’s dibangun di frontend (not di Sanity)
| Output | How |
|---|---|
| Body copy HTML | Serialize Portable Text (@portabletext/react / -to-html) |
| Meta tags | generateMetadata() dari sebuah GROQ hasil |
| Sitemap | GROQ kueri → XML; filter drafts; _updatedAt untuk lastmod |
| Canonicals | Absolute URLs dari one SITE_URL, per-halaman |
| robots.txt | Static frontend file (robots.ts di Next.js) |
| JSON-LD | Generated dari existing fields; schema-dts untuk jenis |
| Redirects | Sanity documents → frontend middleware / Worker |
GROQ snippets worth memorizing
- Override dengan fallback:
coalesce(seo.title, title, "") - Plain text dari Portable Text:
pt::text(body) - Sitemap filter:
*[... && defined(slug.current) && hideFromSearch != true]
Fast aturan
- LLM-crawler rendering varies oleh provider → hindari CSR-hanya public konten.
- Dynamic rendering adalah deprecated — gunakan SSR/static/hydration.
- Drafts:
publishedperspective +X-Robots-Tag: noindexheader. - Plugin:
sanity-plugin-seo✅ /sanity-plugin-seo-pane(Yoast) ❌ deprecated. - “SEO success in Sanity comes from intentional structure, not plugins.” (terjemahan) “SEO success di Sanity comes dari intentional structure, not plugins.”
Draft atau preview konten appeared di Search Console
gunakan ini runbook when sebuah unpublished Sanity document memiliki sebuah discoverable preview URL atau menampilkan up di Google Search Console.
- Confirm which respons leaked. Fetch reported URL without Studio
credentials dan inspect both status dan
X-Robots-Tagheader. jika ini mengembalikan published konten, continue untuk langkah 2. jika ini exposes sebuah draft, disable preview entry poin while Anda continue. - periksa production perspective. Trace halaman’s GROQ permintaan dan confirm
production menggunakan
publishedperspective. jika ini menggunakandrafts, fix itu kueri pertama; jika ini sudah menggunakanpublished, continue untuk respons layer. - tambahkan pengindeksan backstop. kirim
X-Robots-Tag: noindexpada setiap preview dan draft-mode respons. jika header adalah missing pada apa pun preview route, fix shared preview middleware alih-alih patching one halaman. - Validate preview access. Confirm preview secret adalah diperiksa server-side, adalah not reflected ke destination URL, dan accepts permintaan hanya dari intended Studio origin. jika sebuah public preview URL masih berfungsi, rotate secret dan close itu route.
- hapus terindeks copy. setelah respons adalah safe, gunakan Search Console’s
removal workflow when exposure adalah urgent, lalu permintaan sebuah fresh crawl. jika
URL seharusnya tidak pernah exist publicly, pertahankan
noindexrespons available panjang enough untuk crawler untuk see ini alih-alih blocking ini di robots.txt. - Verify fix. Fetch URL while logged out dan run pemeriksaan URL.
draft harus menjadi absent dari body dan preview respons harus carry
noindex.
Sanity SEO mistakes untuk hindari
Expecting Sanity untuk emit SEO HTML
Why ini adalah wrong: Sanity stores JSON; ini melakukan not publish judul, canonicals, sitemaps, atau halaman HTML. melakukan ini instead: membuat frontend responsible untuk setiap output dan verify generated respons alih-alih Studio fields.
Choosing CSR untuk public konten
Why ini adalah wrong: initial respons adalah sebuah empty shell, dan banyak AI crawler melakukan not execute JavaScript di semua. melakukan ini instead: ship public konten dengan SSG, SSR, atau webhook-triggered ISR.
Assuming unpublished berarti unindexable
Why ini adalah wrong: sebuah shared preview URL dapat leak dan menjadi di-crawl. melakukan ini instead:
gunakan published perspective di production dan kirim sebuah X-Robots-Tag: noindex
header pada setiap preview respons.
Treating Portable Text sebagai HTML
Why ini adalah wrong: Portable Text adalah sebuah JSON AST, so un-serialized konten tidak pernah
becomes dapat di-crawl body copy. melakukan ini instead: serialize ini pada server dengan
@portabletext/react atau @portabletext/to-html.
Maintaining JSON-LD di sebuah separate editor
Why ini adalah wrong: sebuah kedua copy dari product, artikel, atau organization facts drifts dari terlihat halaman. melakukan ini instead: derive JSON-LD dari yang sama Sanity fields di render time dan validate rendered output.
periksa apakah sebuah Sanity halaman ships nyata HTML
Run ini setelah changing rendering mode, Portable Text serialization, atau halaman data memuat. ini memeriksa initial respons, sebelum client-side JavaScript dapat fill gaps.
macOS / Linux — compare normal dan Googlebot respons
URL="https://example.com/article-slug"
curl -sL "$URL" -o /tmp/sanity-page.html
curl -sL -A "Googlebot" "$URL" -o /tmp/sanity-googlebot.html
grep -Ei '<title>|rel="canonical"|<h1|application/ld\+json' /tmp/sanity-page.html
diff -u /tmp/sanity-page.html /tmp/sanity-googlebot.htmlpertama command seharusnya temukan halaman’s nyata judul, canonical, H1, dan JSON-LD di
raw HTML. sebuah meaningful konten difference di diff deserves investigation;
crawler dan pengguna seharusnya not menerima berbeda canonical konten.
Windows PowerShell — inspect initial respons
$url = "https://example.com/article-slug"
$html = (Invoke-WebRequest -Uri $url).Content
$html | Select-String -Pattern '<title>|rel="canonical"|<h1|application/ld\+json'DevTools Console — confirm Portable Text became semantic elements
[...document.querySelectorAll('main article p, main article h2, main article li')]
.map((node) => node.textContent.trim())
.filter(Boolean)
.slice(0, 20)Run snippet di browser Console. ini adalah sebuah rendered-DOM periksa, so pair ini dengan
curl test: konten appearing hanya here tetapi not di initial respons adalah masih
client-rendered.
alat untuk Sanity SEO
- pemeriksaan URL (Google Search Console) — see how sebuah single URL adalah di-crawl dan rendered. rendered HTML tells Anda whether Anda Portable Text actually dibuat ini di — essential untuk catching CSR gaps pada sebuah Sanity frontend.
- Rich hasil Test — confirm Anda programmatic JSON-LD adalah present di rendered output setelah apa pun rendering atau template perubahan.
- Screaming Frog SEO Spider — crawl dengan JavaScript rendering pada/off untuk compare raw HTML vs. rendered HTML; ini adalah how Anda prove whether Anda konten adalah server- rendered atau client-rendered.
- Ahrefs situs Audit — surfaces missing metadata, broken canonicals, redirect chains, dan indexability issues di seluruh whole frontend.
- Bing Webmaster alat — submit Anda sitemap dan monitor Bing pengindeksan (ini feeds ChatGPT browse), plus where IndexNow submissions tampilkan up.
sanity-plugin-seo— di-Studio live SEO score, meta/OG preview, dan robots control so editors get feedback di authoring time.
Test yourself: Sanity SEO
Five quick pertanyaan pada how SEO berfungsi pada sebuah Sanity-backed situs. Pick sebuah jawaban untuk setiap, lalu periksa.
Resources worth Anda time
My related writing
- JavaScript SEO Issues & Best Practices — my primary reference pada rendering modes, which decide everything pada sebuah Sanity frontend.
- Beginner’s Guide untuk SEO teknis — where rendering dan crawling fit di bigger picture.
My speaking
- JavaScript SEO — Ungagged 2019 (SlideShare) — my walkthrough dari how headless/decoupled CMSes split frontend dari backend, plus Googlebot’s stateless rendering. (Standing disclaimer: dynamic-rendering recommendation di itu deck adalah now outdated — Google deprecated ini.)
pada ini situs
- SEO untuk sebuah CMS headless — sibling guide; Sanity adalah sebuah spesifik application dari yang sama headless aturan.
- JavaScript SEO — rendering deep dive.
- Canonicalization — consolidation mechanics behind Anda frontend’s tag canonical.
- AI Search — how AI crawler dan jawaban mesin behave.
dari sekitar industry
- SEO dengan Sanity (Sanity) — Sanity’s own master SEO guide; start here untuk platform-saat ini perilaku.
- SEO Optimization course (Sanity Learn) — hands-pada Next.js course covering SEO object, dynamic sitemaps, dan JSON-LD.
- Sanity SEO (Webstacks, Devon Wood) — agency guide membuat “frontend handles SEO output” (terjemahan) “frontend handles SEO output” poin clearly.
- AEO & SEO best practices untuk Sanity (Roboto Studio, Jono Alford) — AEO angle dan “derive JSON-LD from existing fields” (terjemahan) “derive JSON-LD dari existing fields” aturan.
- SEO best practices untuk Sanity CMS (Yanatiev) — “structure, not plugins” (terjemahan) “structure, not plugins” framing.
- cara sajikan konten untuk agents: sebuah field guide (Knut Melvær, Sanity) — konten negotiation dan case terhadap llms.txt untuk besar situs.
- CMS headless SEO (Ahrefs, Despina Gavoyannis) — broader headless playbook (konten/code/design dioptimalkan independently) itu Sanity sits inside.
- turbo-start-sanity (Roboto Studio, GitHub) — sebuah open-source Sanity SEO starter dengan nyata
query.ts,seo-fields.ts, danseo.tsimplementations.
Log perubahan
Diperbarui 19 Jul 2026.
Ringkasan editorial dan detail perubahan yang tercatat.Detail perubahan
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
Perbandingan lengkap tidak tersedia — tidak ada cuplikan sebelumnya yang diarsipkan untuk revisi ini.