Documentation Index
Fetch the complete documentation index at: https://docs.siftly.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
This guide is for Sanity users who want to publish Siftly-generated GEO content and apply SEO/GEO field recommendations (meta tags, JSON-LD, keywords) directly to their Sanity schema. After following it, you’ll have a complete SEO schema, working field mapping, and frontend rendering code for all GEO-critical fields. Difficulty: ❌ Requires developer — Sanity is headless; you build the schema and the frontend rendering yourself. Sanity is a headless CMS built around structured content and a powerful API. The Siftly–Sanity integration pushes content directly to your Sanity Content Lake as new documents, using the unified 3-tier field mapping system and Sanity’s GROQ-powered API under the hood. This integration is ideal for teams using Sanity to power content-heavy websites, documentation, or multi-channel publishing pipelines.Prerequisites
Before connecting, you’ll need:- A Sanity project with a schema that includes a document type for your content (e.g.,
post,article) - A Sanity API token with Editor or Deploy Studio write permissions
- Your Sanity Project ID and Dataset name
Step 1: Get your Sanity credentials
Project ID and Dataset
- Log in to sanity.io/manage
- Select your project
- Copy the Project ID from the project overview page
- Note your Dataset name (usually
production)
API Token
- In Sanity Manage, go to API -> Tokens
- Click Add API Token
- Give it a descriptive name (e.g., “Siftly Integration”)
- Set the permission level to Editor
- Click Save and copy the token
The Editor permission level includes asset upload access. Siftly uploads hero images and inline content images to the Sanity Assets API automatically at publish time — no additional permissions are needed.
Step 2: Connect Sanity in Siftly
- In Siftly, go to Settings -> Integrations
- Click Connect next to Sanity
- Enter your:
- Project ID
- Dataset name
- API Token
- Click Verify Connection
Step 3: Schema Mapping
After credentials are validated, Siftly discovers your schema and presents the mapping interface.Document Type Selection
Choose the Sanity document type that Siftly should create when publishing. Siftly automatically discovers all document types in your schema and presents them as a dropdown. You can also enter a custom type name. When you select a type, Siftly fetches a sample document via GROQ and discovers all available fields — including nested fields inside objects (e.g.,seo.metaTitle, schemaOrg.datePublished).
Field Mapping
Siftly uses a 3-tier field mapping system. Select fields from the dropdown (discovered from your schema) for each field you want Siftly to populate.Required Fields
| Siftly Field | Typical Sanity Field | Notes |
|---|---|---|
| Title | title | Plain text |
| Slug | slug | Sanity handles the {_type: "slug", current: "..."} format automatically |
| Body | body | Rich text — maps to Portable Text or HTML embed (see below) |
Optional Fields
Leave any of these blank to skip them. When mapped, they are auto-populated from your content data.| Siftly Field | Typical Sanity Field | Notes |
|---|---|---|
| Meta Title | seo.metaTitle | Dot-notation supported for nested objects |
| Meta Description | seo.metaDescription | Dot-notation supported for nested objects |
| Keywords | tags | Array of strings or comma-separated string |
| Categories | category | String value |
| JSON-LD | schema | String or JSON — controlled by the type toggle |
| Word Count | wordCount | Number field |
| Hero Image | featuredImage | Image field |
JSON-LD Type Toggle
When a JSON-LD field is mapped, a text/json toggle appears:- json (default): Sends as a parsed JSON object (with
@prefixes stripped for Sanity compatibility) - text: Sends as a serialized JSON string
Nested Field Discovery
Siftly recursively discovers fields inside nested objects up to 3 levels deep. For example, an SEO settings object with sub-fields appears as:seo.metaTitle(String)seo.metaDescription(String)seo.ogImage(Image)schemaOrg.datePublished(String)
> separators: SEO > Meta Title.
Body Format
Toggle Store body as HTML embed to control how body content is stored:- Off (default): Content is converted to Portable Text blocks (headings, paragraphs, lists, links)
- On: Content is stored as an
htmlEmbedblock containing the full HTML. Your schema needs anhtmlEmbedtype defined in the body array, and your frontend should render it with proper styling.
Portable Text
When HTML embed is off, Siftly automatically converts generated HTML content to valid Portable Text:- Headings (H2, H3, H4)
- Bold, italic, and inline code
- Ordered and unordered lists
- Hyperlinks (including internal links generated by Siftly)
- Block quotes
Custom Portable Text block types (e.g., call-out cards, custom embeds) are not supported by the auto-converter.
Custom Fields
Add extra fields your Sanity document type requires that aren’t part of Siftly’s standard content schema.Field Types
| Type | Description | Example |
|---|---|---|
| String | Plain text | Author name, subtitle |
| Number | Numeric value | Priority, reading time |
| Boolean | True/false | Featured post, comments enabled |
| JSON | Structured object | SEO config, social media metadata |
| Select | Pick from predefined options | Category, status, content type |
Select Options with Separate Labels and Values
When adding a Select custom field, you define the available options in a textarea. Each option can have a separate value (sent to CMS) and label (shown in the dropdown):Health, Tech, etc., but Siftly sends 1, 2, etc. to the CMS API.
Example — Labels same as values:
: is present, the option text is used as both the label and value. This is backward-compatible with existing configurations.
Default Values
Set a default value when adding a custom field. This value pre-fills at publish time — you can override it for each post.Use Existing Field (Source Fields)
Instead of setting a manual default, link a custom field to an existing content source. The value is auto-populated at publish time — no manual input needed. Available sources:- Title, Slug, Meta Title, Meta Description, Excerpt
- Keywords, Categories, Word Count
- JSON-LD, Hero Image
- Date Published, Date Modified (extracted from the JSON-LD graph)
seo.metaTitle-> Use Existing: Meta Titleseo.wordCount-> Use Existing: Word CountschemaOrg.dateModified-> Use Existing: Date Modified
Editing Custom Fields
Click the pencil icon on any existing custom field to edit its configuration (field path, label, type, source, default value).Auto-Populated Fields
Siftly automatically sets these fields on every document if not already provided by a custom field mapping:| Field | Value |
|---|---|
status | "published" or "draft" based on your publish choice |
publishedAt | ISO timestamp (only for published, not draft) |
Publishing
Draft vs Published
When publishing, choose between:- Draft — the document is created with
drafts.prefix ID, visible only in Studio - Published — the document is created as a live document with
publishedAtset
Custom Fields at Publish Time
Custom fields with Use Existing Field set show as “Auto-populated from [source]” in the publish dialog — no input needed. Manual custom fields appear with their default values pre-filled and editable.Republishing
Siftly usescreateOrReplace for idempotent updates. Republishing the same content updates the existing Sanity document (same ID: siftly-{content_id}). Publishing also deletes any stray draft/published counterpart to avoid duplicates.
GROQ Previewing
After publishing, verify the document in Sanity Studio’s Vision tool:Webhooks (optional)
For teams with automated publishing workflows, Siftly can call a Sanity webhook after creating a document — for example, to trigger a re-build of your Next.js or Remix frontend.- In Sanity Manage, go to API → Webhooks → Add Webhook
- Set the URL to your frontend’s webhook endpoint
- Copy the webhook URL
- In Siftly → Settings → Integrations → Sanity → Advanced, paste the webhook URL in Post-publish webhook
Where to apply Siftly’s recommendations on Sanity
Sanity is fully headless — you define the schema, Siftly pushes data into it, and your frontend renders it as HTML meta tags and structured data. Below is the complete recommended schema and rendering setup.Recommended SEO schema object
Create a reusableseo object type that you can add to any document type:
Meta Title
Schema location:seo.metaTitle
Siftly mapping: Map Siftly’s Meta Title field to seo.metaTitle in your integration settings.
Frontend rendering (Next.js App Router):
Meta Description
Schema location:seo.metaDescription
Siftly mapping: Map Siftly’s Meta Description field to seo.metaDescription.
Rendered via the same generateMetadata function above.
Open Graph Image
Schema location:seo.ogImage (Sanity image type with asset reference)
Siftly does not push image uploads to Sanity. After publishing, upload your OG image to the document in Sanity Studio. Alternatively, use a text field (
seo.ogImageUrl) for external image URLs.Canonical URL
Schema location:seo.canonicalUrl
Frontend rendering:
Tags & Categories
Schema location:tags (array of strings at document root)
Siftly mapping: Map Siftly’s Keywords field to tags.
Tags are rendered in your frontend for navigation, filtering, or as meta keywords:
JSON-LD Structured Data
Schema location:seo.jsonLd (text field storing raw JSON)
Siftly mapping: Map Siftly’s JSON-LD field to seo.jsonLd (or jsonLd at root).
Frontend rendering:
Keywords
Schema location:seo.keywords (array of strings) or tags at the document root.
Siftly pushes keywords as an array. Your frontend renders them in a <meta name="keywords"> tag or uses them for internal search/filtering.
Pushing Siftly recommendations automatically
Generate content in Siftly
Siftly produces your article plus meta title, meta description, keywords, JSON-LD, and word count.
All fields pushed in one API call
Siftly creates a new document in your Content Lake with all mapped fields populated — body (as Portable Text), SEO object fields, tags, and JSON-LD.
GROQ query for all SEO fields
Use this query to fetch everything your frontend needs for a complete GEO-optimized page:Platform-specific quirks & limitations
Portable Text conversion: Siftly converts HTML to Portable Text automatically when publishing. Standard formatting (headings, lists, links, bold, italic, blockquotes) is preserved. Custom block types in your schema are NOT supported by the auto-converter.
- Image fields: Siftly cannot upload images to Sanity’s asset pipeline. Use text URL fields for OG images or upload images manually in Sanity Studio after publishing.
- References: If your schema uses references (e.g.,
author→ Author document), Siftly cannot create or link references. Keep these fields optional or set them manually. - Array of objects: Complex nested arrays (e.g., FAQ items as an array of
{question, answer}objects) cannot be mapped from Siftly’s flat field structure. Store FAQ schema as JSON-LD in theseo.jsonLdtext field instead. - Real-time preview: Sanity’s real-time preview (via
next-sanityor@sanity/preview-kit) will show new Siftly-published documents immediately in draft mode without a page refresh. - Dataset isolation: If you use multiple datasets (e.g.,
productionandstaging), make sure Siftly is connected to the correct dataset for your publishing workflow.
Validating the setup
After publishing your first document from Siftly:Check in Sanity Studio
Open Sanity Studio → find your new document → verify all fields (title, body, SEO object, tags, JSON-LD) are populated.
Run your GROQ query
Open Vision in Sanity Studio and run the GROQ query above with your test slug. Confirm all SEO fields return data.
View the live frontend page source
Open the rendered page. Right-click → View Page Source. Search for:
<title>— should contain your meta title from Sanity<meta name="description"— should contain your meta description<script type="application/ld+json">— should contain your JSON-LD
Run Google Rich Results Test
Go to Google Rich Results Test and paste your URL. Confirm structured data is detected and valid.
Run Schema.org Validator
Go to Schema.org Validator for additional validation.
Difficulty & setup recap
Sanity Setup Summary
| Aspect | Rating |
|---|---|
| Initial setup | ❌ Developer required — schema design + frontend code |
| Applying SEO fields | ❌ Must build schema object and frontend rendering |
| JSON-LD | ❌ Stored as text; frontend must render <script> tag explicitly |
| Ongoing editing | ✅ Easy — publish from Siftly, review in Sanity Studio |
| Developer needed? | Yes — for schema and frontend. Not for ongoing content publishing. |
| GEO control level | ✅ Maximum — you control every field and rendering detail |
Related
CMS Integrations Overview
Compare all supported platforms and the unified field mapping system.
Quickstart Guide
Set up your brand and run your first GEO analysis.
Content Generation
How Siftly generates GEO-optimized content and recommendations.
Choosing a CMS for AI Visibility
Our guide to picking the right CMS for GEO optimization.
Troubleshooting
403 Forbidden on connection
403 Forbidden on connection
Your API token doesn’t have write access to the selected dataset. Regenerate the token with Editor permissions in Sanity Manage.
Document created but fields are empty
Document created but fields are empty
Check your field mapping. Fields with Use Existing Field require the source data to exist in your content. Verify the mapping dropdown matches your actual schema field names.
Slug field isn't saving correctly
Slug field isn't saving correctly
Siftly automatically wraps slugs in Sanity’s
{_type: "slug", current: "your-slug"} format. Just map to the slug field name.JSON-LD shows 'Unknown fields' warning in Studio
JSON-LD shows 'Unknown fields' warning in Studio
When JSON-LD type is set to json, the
@ prefixes are stripped (@type becomes type). Your Sanity schema needs matching sub-fields (e.g., context, graph) defined on the object, or use text mode to store as a string.Two versions of the document appear (draft + published)
Two versions of the document appear (draft + published)
This can happen from failed previous attempts. Republish the content — Siftly now automatically deletes the opposite version when publishing.