# What is Generative Engine Optimization? Source: https://docs.siftly.ai/concepts/geo-explained Understand how GEO differs from traditional SEO and why it's the next frontier for brand visibility. ## The shift in search For decades, ranking on Google meant optimizing for a crawler — a bot that read your HTML, indexed your keywords, and matched your page to search queries. SEO was about signals: backlinks, page speed, keyword density, structured data. That model is changing fast. AI-powered search engines like **ChatGPT**, **Perplexity**, **Google AI Overviews**, and **Microsoft Copilot** don't return a list of links. They generate an answer. When someone asks "What's the best tool for tracking brand mentions in AI?" — the AI reads, synthesizes, and responds. Your page either gets cited or it doesn't. **Generative Engine Optimization (GEO)** is the discipline of ensuring your brand, content, and expertise are what AI models reach for when generating those answers. *** ## GEO vs. traditional SEO Side-by-side comparison: Traditional SEO ten-blue-links vs GEO AI-generated cited answers | | Traditional SEO | Generative Engine Optimization | | ----------------- | -------------------------- | ---------------------------------------- | | **Target** | Search engine crawlers | AI language models | | **Goal** | Rank on page 1 | Get cited in AI answers | | **Metric** | Keyword rankings, clicks | Citations, share of voice | | **Content focus** | Keyword density, backlinks | Authority, clarity, structured knowledge | | **Measurement** | SERP position | Citation frequency, visibility score | | **Competition** | 10 blue links | A single synthesized answer | GEO doesn't replace SEO — it extends it. A well-optimized page that ranks well in traditional search often gets cited in AI results too. But the signals that drive AI citation are different enough that GEO deserves its own strategy. *** ## How AI models decide what to cite AI search systems draw from two sources: ### 1. Training data Large language models are trained on large corpora of text. Brands with strong, authoritative content published before and during training windows have a higher baseline presence. ### 2. Retrieval-Augmented Generation (RAG) Most modern AI search tools retrieve live content at query time using semantic search. When a user asks a question, the AI fetches relevant documents from the web, then synthesizes an answer using those documents as grounding context. **This is where GEO has the most leverage.** By optimizing your content for retrieval — clear entity definitions, structured answers, authoritative tone — you improve your odds of being retrieved and cited. *** ## The GEO playbook Find the prompts and topics where your competitors are being cited but you're not. These are your highest-leverage opportunities. Review existing pages for GEO signals: clear entity definitions, direct answers to common questions, structured data, and authoritative tone. Publish content that directly answers the questions AI systems are asked. Structured formats (FAQs, listicles, comparisons) perform well in AI retrieval. Monitor your citation rate and visibility score over time. GEO is iterative — what works changes as models are updated and competitors adapt. *** ## Key GEO metrics in Siftly The percentage of AI responses to tracked prompts that include a mention or recommendation of your brand. Higher is better. A composite score (0–100) combining citation frequency, sentiment, and competitive share of voice. Your headline metric for AI visibility. Your brand's citation percentage relative to the total citations in your market. A brand cited in 30 out of 100 responses has 30% SOV for that topic. How many of the prompts Siftly tracks for your market include your brand in the response. Low coverage = opportunity. When your brand is cited alongside competitors in a single response, what position is it mentioned at? First mention carries more weight. *** GEO is an emerging field and AI search platforms evolve rapidly. Siftly's analysis engine is continuously updated to reflect changes in how major AI systems retrieve and cite content. # Brand Visibility Source: https://docs.siftly.ai/features/brand-visibility Understand your overall AI visibility score and track how your brand's presence in AI-generated search evolves over time. ## What is the Visibility Score? The **Visibility Score** is Siftly's headline metric — a single number (0–100) that represents how prominent your brand is in AI-generated search results across your tracked topics. Visibility Score dashboard — composite score with citation frequency, SOV, sentiment, and rank breakdown It's calculated from: * **Citation frequency** — How often your brand appears across all tracked prompts * **Share of voice** — Your citations relative to total citations in your market * **Sentiment weight** — Positive citations count more than neutral; negative citations reduce the score * **Position bias** — Citations where your brand is mentioned first carry more weight A score of **0** means your brand is never cited. A score of **100** would mean your brand appears positively and first in every tracked AI response — theoretical, but directionally useful. *** ## The Overview dashboard The **Overview** page is your visibility command center. Here's what you'll find: ### Visibility Score card Your current score with a trend indicator showing change vs. the previous period (week, month, or quarter — configurable). ### Visibility trend chart A line chart showing your visibility score over time. Use this to: * Correlate score changes with content you published * Spot the impact of competitor activity * Identify seasonal patterns in your market ### Citation breakdown A breakdown of your citations by: * **Platform** — Which AI platforms cite you most * **Topic** — Which topics drive the most mentions * **Sentiment** — The ratio of positive to neutral to negative ### Competitor comparison See your visibility score plotted against your top competitors. This is your share-of-voice view — who's winning the AI search landscape in your market. *** ## Improving your visibility score AI retrieval systems favor content that directly answers specific questions. Create pages structured as clear Q\&A, FAQs, and how-to guides around your high-opportunity prompts. AI models form "knowledge" about brands from structured, consistent information across the web. Make sure your brand name, description, founding year, and category are consistent across your website, Wikipedia, LinkedIn, Crunchbase, and press coverage. If your brand has abbreviations, former names, or product sub-brands, add them in **Settings → Brand → Aliases**. This ensures citations using alternate names are counted and attributed correctly. Use Siftly's website crawling feature to index your brand's website into the RAG pipeline. This increases the chance that your content is retrieved when AI systems look for supporting sources. Review negative citations in the Citations tab and identify the root cause. Often a single piece of content — a comparison page, an FAQ, or a case study — can shift the framing. *** ## Scheduled analysis and trend tracking Your visibility score is only as useful as the cadence at which it's measured. Set up a **scheduled analysis** to track trends automatically: * **Weekly** — Recommended for most brands; balances signal quality with change velocity * **Daily** — For brands in fast-moving markets or during active content campaigns * **Monthly** — For brands with lower publishing frequency or stable markets Navigate to **Settings → Scheduled Analysis** to configure your schedule. # Citation Analysis Source: https://docs.siftly.ai/features/citation-analysis Track every time your brand appears in AI-generated search responses and understand the full context of each mention. ## Overview Citation Analysis is the core of Siftly's GEO platform. It continuously monitors how AI search engines — ChatGPT, Perplexity, Google AI Overviews, and others — respond to prompts in your market, and captures every mention of your brand. Citation tracking pipeline — from prompt library to enriched dashboard data For each citation, Siftly records: * The exact prompt that triggered the response * The full AI-generated response text * Your brand's position in the response (first mention vs. secondary) * Sentiment (positive, neutral, or negative) * Which competitors were mentioned in the same response * The platform the response came from *** ## How citation tracking works Siftly maintains a library of prompts for each topic in your market. These are the questions real users ask AI systems: "What's the best tool for X?", "Compare A vs B", "How do I solve Y?". New prompts are continuously added as user behavior evolves. At each analysis run, Siftly sends prompts to AI platforms and captures the full response. Queries are run across multiple platforms to give you cross-platform coverage. Siftly's detection engine scans every response for your brand name, aliases, website URL, and product names. Fuzzy matching catches variations like abbreviations and common misspellings. Each detected citation is enriched with sentiment analysis, competitive co-mentions, and position data, then stored in your brand's citation history. *** ## The Citations dashboard Navigate to **Citations** in the sidebar to see all mentions of your brand. ### Filters | Filter | Description | | -------------- | ---------------------------------------------------------- | | **Date range** | View citations from a specific time window | | **Platform** | Filter by AI platform (ChatGPT, Perplexity, etc.) | | **Topic** | Filter by the topic category the prompt belongs to | | **Sentiment** | Show only positive, neutral, or negative citations | | **Rank** | Filter by whether your brand was cited first, second, etc. | ### Citation cards Each citation card shows: * The prompt text * A snippet of the AI response with your brand highlighted * Sentiment badge and position indicator * Competitors co-cited in the same response * Timestamp and platform Click any citation to expand the full response text. *** ## Sentiment analysis Siftly classifies each citation as: The AI response recommends, praises, or ranks your brand favorably. Example: *"Siftly is widely regarded as the leading GEO platform for enterprise teams."* Your brand is mentioned factually without a clear positive or negative framing. Example: *"Tools in this space include Siftly, BrandX, and CompanyY."* The AI response includes a criticism, limitation, or comparison that frames your brand unfavorably. These are your highest-priority items to address through content. Negative citations aren't always bad — being mentioned alongside better-known competitors is still brand presence. Focus on the context, not just the label. *** ## Competitive co-mentions When your brand appears in the same AI response as a competitor, Siftly records the relationship. Over time, this data shows you: * Which competitors are most frequently cited alongside you * Whether you're typically ranked above or below them * Which topics trigger competitor mentions without including you Use this data to identify where competitors have stronger GEO footing and target those gaps with content. *** ## Export Export your citation data from the Citations page: * **CSV** — Full citation export with all metadata fields * **PDF report** — Formatted citation summary for sharing with stakeholders # Content Generation Source: https://docs.siftly.ai/features/content-generation Generate GEO-optimized content grounded in your brand's data, with automatic citations and internal links. ## Overview Siftly's content generation engine turns your GEO analysis into actionable content. Instead of starting from a blank page, you start from data — the exact prompts where you have citation gaps, the competitors outranking you, and the questions your audience is asking AI systems. Content generation workflow — from citation gap to AI editor to CMS publishing Generated content is: * Grounded in your brand's website and published materials (via RAG) * Structured to maximize AI retrieval and citation likelihood * Annotated with internal links to your existing content * Ready to publish or export to your CMS *** ## Creating content from a gap The fastest path to GEO content is directly from a citation gap: 1. Go to **Rankings → \[Topic] → Gaps** 2. Click any prompt where you don't appear 3. Click **Generate Content for this Prompt** Siftly will generate a content brief and a full draft optimized for that specific query, drawing on your indexed website content and brand profile. *** ## The content editor The content editor gives you a full draft with: ### Suggested title and meta An H1 and meta description optimized for both traditional SEO and AI retrieval. ### Body content Structured content (headings, lists, Q\&A sections) that directly addresses the target prompt. GEO-optimized content tends to be specific, authoritative, and directly answerable. ### Brand citations References to your own brand, products, and case studies pulled from your indexed website content. These ground the content in your specific expertise rather than generic information. ### Internal links Suggested links to existing pages on your website that are semantically related. Internal linking strengthens topical authority signals for both traditional SEO and AI retrieval. ### Competitor differentiation Where relevant, the generator identifies opportunities to contrast your approach against competitors — without being explicitly comparative in a way that could read as defensive. *** ## Website indexing for RAG Content generation quality improves significantly when Siftly has indexed your website. Indexing allows the generator to pull specific facts, case studies, and product details from your actual content rather than relying on generic knowledge. To index your website: 1. Go to **Settings → Website Crawling** 2. Enter your domain URL 3. Click **Start Crawl** Siftly will crawl and index your website using semantic chunking. Indexing typically takes 10–30 minutes for most websites. Re-index your website whenever you publish significant new content. Siftly doesn't auto-crawl — trigger a new crawl manually or set up a scheduled crawl to keep the index fresh. *** ## Exporting content Once you're happy with a draft, export it to your publishing workflow: | Format | Use case | | ------------ | ----------------------------------------------------- | | **Markdown** | Paste into any CMS that accepts Markdown | | **HTML** | Copy into a page builder or WYSIWYG editor | | **DOCX** | Share with stakeholders or hand off to a content team | | **PDF** | Archive or present to clients | Or use one of Siftly's native **CMS integrations** to push content directly to WordPress, Ghost, Webflow, Strapi, Sanity, Wix, or Framer. See [CMS Integrations →](/integrations/overview) *** ## Content versioning Every draft is versioned. Use the **Compare** view to see a side-by-side diff between versions: * Track edits made after generation * Compare performance of different content approaches over time * Restore a previous version if needed # Rankings & Share of Voice Source: https://docs.siftly.ai/features/rankings See where you stand versus competitors for every topic in your market and track your share of AI search presence. ## Overview The Rankings feature answers the competitive question at the heart of GEO: **when AI systems respond to prompts in your market, who gets cited, in what order, and how often?** Siftly tracks this across every topic you monitor and surfaces it as structured leaderboards and share-of-voice metrics. *** ## Leaderboards AI Rankings leaderboard — brand visibility scores, citation rates, share of voice, and trends Navigate to **Rankings** to see the competitive leaderboard for your market. Each leaderboard row shows a brand with: * **Visibility score** — Their composite AI visibility for this topic * **Citation rate** — Percentage of tracked prompts that include them * **Average rank** — Their average position when cited (lower = better) * **SOV %** — Their share of all citations in this topic * **Trend** — Change vs. the previous period Your brand is always highlighted. Use the topic selector to switch between the topics you're tracking. Sort the leaderboard by **Citation Rate** to find who's being cited most frequently. Sort by **Average Rank** to see who gets the top-of-response position. These tell different stories. *** ## Share of Voice (SOV) Share of Voice answers: **of all brand citations in my market, what percentage belong to me?** If AI systems produce 1,000 brand citations across tracked prompts, and your brand appears in 220 of them, your SOV is 22%. SOV is a zero-sum metric — if your SOV goes up, someone else's goes down. Track it over time to see whether you're gaining or losing ground relative to your market. ### SOV by topic Break down your share of voice by topic to find where you're overperforming and where you have gaps: * Topics where your SOV is **above** your overall average are strengths to maintain * Topics where your SOV is **below** your average are gaps to close with targeted content *** ## Prompt-level analysis Drill into any topic to see a prompt-by-prompt breakdown of who was cited for each individual query. This view shows you: * The exact AI prompt * Which brands appeared in the response * The order they were mentioned * Whether your brand was present at all **Prompts where you don't appear** are your most direct content opportunities. Siftly surfaces these as **"Gaps"** — click any gap to get AI-generated content recommendations for that specific prompt. *** ## Tracking competitors Siftly automatically detects competitors from your market category. You can also manually add competitors: 1. Go to **Settings → Competitors** 2. Click **Add Competitor** 3. Enter the brand name and website URL Once added, the competitor will appear in all leaderboards, SOV charts, and prompt-level breakdowns on the next analysis run. Competitor data reflects what AI systems say about them — Siftly doesn't have access to their internal analytics. Treat competitor metrics as AI-perceived reputation, not ground-truth performance data. # Introduction Source: https://docs.siftly.ai/index Welcome to Siftly — the Generative Engine Optimization platform that puts your brand in front of AI. Siftly Dashboard — Visibility Score, Citation Tracking, and AI Rankings Siftly Dashboard — Visibility Score, Citation Tracking, and AI Rankings ## What is Siftly? Siftly is a **Generative Engine Optimization (GEO)** platform that helps brands understand and improve how they appear in AI-generated search results — from ChatGPT and Perplexity to Google AI Overviews and beyond. As search shifts from ten blue links to AI-generated answers, the brands that win are the ones that AI systems actively cite, recommend, and reference. Siftly gives you the data and tools to become one of them. ## Why GEO matters Traditional SEO optimizes for search engine crawlers. GEO optimizes for AI language models. When a user asks an AI assistant "What's the best project management tool?" — the AI doesn't scroll through results. It synthesizes an answer from the content it was trained on and the sources it can retrieve. **Siftly answers the questions that matter:** * Is my brand being cited in AI responses? * Which topics and prompts surface my competitors instead of me? * How is my share of voice trending over time? * What content should I publish to increase my AI visibility? How GEO works — from AI query to citation tracking ## Core capabilities Track every time your brand is mentioned, cited, or recommended in AI-generated responses across the most popular AI search platforms. Measure your overall AI visibility score and see how it changes week over week as you publish new content and optimize existing pages. See exactly where you rank versus competitors for any topic or search prompt. Understand your share of voice in your market. Generate SEO and GEO-optimized content backed by your brand's data, with automatic citation integration and internal linking. ## Who is Siftly for? Siftly is built for teams that need to stay visible as search evolves: * **Marketing teams** tracking brand presence in AI-generated answers * **SEO specialists** expanding their strategy from traditional search to generative AI * **Content strategists** identifying gaps and opportunities in AI citation coverage * **Agencies** managing GEO for multiple brands and clients ## How it works ```mermaid theme={null} flowchart LR A[Connect Your Brand] --> B[Run Citation Analysis] B --> C[Track Visibility & Rankings] C --> D[Generate Optimized Content] D --> B ``` 1. **Connect your brand** — Add your company name, website, and relevant topics 2. **Analyze** — Siftly queries AI models with hundreds of prompts relevant to your market 3. **Monitor** — Track citations, rankings, and visibility trends on your dashboard 4. **Optimize** — Use AI-assisted content generation to close gaps and increase citations *** Ready to get started? [Set up your first brand →](/quickstart) # Duda Integration Source: https://docs.siftly.ai/integrations/duda Publish GEO-optimized content from Siftly to your Duda website via Zapier. Supported CMS platforms including Duda ## Overview This guide walks you through connecting Siftly to Duda using Zapier as a bridge. After following it, you'll be able to publish GEO-optimized content from Siftly directly to your Duda blog with a single click. **Difficulty:** ✅ Non-tech friendly — no coding required. Setup takes about 10 minutes. Duda's direct API requires an enterprise-tier plan. Zapier is the only automation platform with a native Duda "Create Blog Post" action, so Siftly uses a Zapier webhook to bridge the connection. One Zapier account can handle all your Duda sites. *** ## How it works When you click **Publish → Duda** in Siftly, it sends your article (title, body, description, author, site name) to a Zapier webhook URL. Your Zap receives the data and uses Duda's "Create Blog Post" action to create the post on your Duda site. The blog post is created on your Duda website. You can edit slug, tags, and SEO fields in the Duda editor if needed. *** ## Prerequisites Before starting, you'll need: * A **Duda** website with a blog enabled (Agency plan or higher) * A **Zapier Pro** account (\$30/month — [start a 14-day free trial](https://zapier.com/app/pricing)) * About 10 minutes for the one-time setup Zapier Pro is required because the "Webhooks by Zapier" trigger is a premium feature. One Zapier Pro account covers **all** your Duda sites — no per-site cost. *** ## Step 1: Create a Zap in Zapier Log in to [zapier.com](https://zapier.com/app/zaps) and click **Create Zap**. 1. Search for **"Webhooks by Zapier"** as the trigger app 2. Choose **"Catch Hook"** as the trigger event 3. Click **Continue** — no configuration needed 4. Zapier shows your webhook URL: ``` https://hooks.zapier.com/hooks/catch/123456/abcdef/ ``` 5. **Copy this URL** — you'll paste it into Siftly in Step 2 6. Click **Continue** (skip the test for now — Siftly will send test data when you connect) 1. Click the **+** to add an action step 2. Search for **"Duda"** and select it 3. Choose **"Create Blog Post"** as the action event 4. Click **Continue** 5. Click **Connect Account** — a Duda login popup opens 6. Log in with your **Duda Agency credentials** 7. Authorize Zapier and click **Continue** Zapier shows the Duda blog post fields. Map them to the webhook data: | Duda Field | Select from trigger | | -------------------------- | ---------------------------------------------------------------------------------------------- | | **Site Name** (required) | Select `site_name` from the dropdown — OR hardcode your site name (e.g., `www.srgaglobal.com`) | | **Title** (required) | Select `title` | | **Description** (required) | Select `description` | | **Content** (required) | Select `content` | | **Author** (optional) | Select `author_name` | | **Thumbnail** | Leave empty | | **Main Image** | Leave empty | **Multi-site tip:** Map **Site Name** to the `site_name` field from the webhook data instead of hardcoding it. This way, one Zap handles all your Duda sites — Siftly sends the correct site name with each publish. The webhook fields may not appear in the dropdown until Zapier receives at least one payload. Complete Step 2 first (connect Siftly), then come back to Zapier and re-map the fields. Click **Publish** to activate the Zap. It's now waiting for data from Siftly. *** ## Step 2: Connect Duda in Siftly 1. In Siftly, go to **Settings → Integrations** 2. Click **Connect** next to **Duda** 3. Paste the **Zapier webhook URL** from Step 1 4. Enter your **Duda Site Name** (e.g., `www.srgaglobal.com`) — this is sent with each publish so the Zap knows which site to create the post on 5. Optionally enter your **Blog Base URL** (e.g., `https://www.yoursite.com/blog`) — used to show the published post link in Siftly 6. Click **Connect Duda** Siftly sends a test payload to verify the webhook is active. If your Zap is turned on, you'll see a success confirmation. After connecting, go back to Zapier and edit your Zap's action step — the webhook fields (title, content, description, site\_name, author\_name) will now appear in the mapping dropdowns. *** ## Step 3: Publish from Siftly 1. Open any content piece in Siftly's content editor 2. Click **Publish → Duda** 3. Click **Publish** Siftly sends the content to Zapier, which creates the blog post in Duda within seconds. *** ## Multiple Duda sites One Zapier Pro account handles all your client sites: **Option A — One Zap for all sites (recommended):** * Map the **Site Name** field in Zapier to `site_name` from the webhook * Each Siftly org stores its own Duda site name * One Zap dynamically routes to the correct site **Option B — One Zap per site:** * Create separate Zaps for each site, each with its own webhook URL * Hardcode the site name in each Zap's Duda action * Each Siftly org connects with its site-specific webhook URL *** ## Fields sent to Duda Siftly sends these fields automatically on every publish: | Field | Description | | ------------- | -------------------------------------------- | | `site_name` | Your Duda site name (for multi-site routing) | | `title` | Article title | | `content` | Full HTML body | | `description` | Meta description / excerpt | | `author_name` | Content author | Duda's Zapier action does not support slug/path, meta title, tags, or draft/published status control. Posts are created with Duda's default settings. Edit slug, tags, and SEO fields directly in the Duda editor after publishing. *** ## Troubleshooting Your Zap may not be turned on. Go to Zapier → your Zap → check it shows **ON** (green). If you just created it, click **Publish** to activate. Check Zapier's **Zap History** (Zapier → your Zap → History tab). If the trigger fired but the action failed, common causes: * Duda account disconnected in Zapier — reconnect it * Site not selected — edit the Zap and hardcode or map the site name * Field mapping is empty — re-map the fields after Siftly sends a test payload Zapier needs at least one webhook payload to detect the field structure. Connect Siftly first (sends a test), then go back to Zapier → edit the action → fields will now appear. Go to Siftly → **Settings → Integrations → Duda** → **Disconnect**, then reconnect with the new webhook URL. No. One Zapier Pro account (\$30/month) covers all your Duda sites. Use the `site_name` field to route content to the correct site dynamically. *** ## Difficulty & setup recap | Aspect | Rating | | ---------------------- | -------------------------------------------------- | | **Initial setup** | ✅ Easy — paste a webhook URL, no coding | | **Zapier setup** | ⚠️ One-time 10-minute setup + Zapier Pro (\$30/mo) | | **Ongoing publishing** | ✅ Easy — one-click publish from Siftly | | **Multiple sites** | ✅ One Zap handles all sites via `site_name` | | **JSON-LD** | ❌ Not supported via Duda's Zapier action | | **Developer needed?** | No | *** ## Related Compare all supported platforms and the unified field mapping system. Set up your brand and run your first GEO analysis. How Siftly generates GEO-optimized content and recommendations. Our guide to picking the right CMS for GEO optimization. # Framer Integration Source: https://docs.siftly.ai/integrations/framer Connect Siftly to your Framer site and publish GEO-optimized content directly to your Framer CMS collections. Supported CMS platforms including Framer ## Overview This guide is for Framer users who want to publish Siftly-generated content and apply GEO/SEO recommendations (meta tags, JSON-LD, keywords) to their Framer site. After following it, you'll know how to connect Siftly, map CMS fields, and add structured data to your pages. **Difficulty:** ⚠️ Some technical setup — SEO fields are visual, but JSON-LD and dynamic structured data require custom code injection. Framer is a visual website builder with a built-in CMS. The Siftly–Framer integration lets you create content in Siftly's editor and publish it directly to a Framer CMS collection using the unified 3-tier field mapping system — no copy-pasting required. This is especially useful for teams that manage blog posts, landing pages, or resource libraries in Framer and want to keep their publishing workflow inside Siftly. *** ## Prerequisites Before connecting, you'll need: * A Framer site with a **CMS collection** already created (e.g., a "Blog" collection) * A Framer account with **Editor** or **Owner** permissions * Your Framer **API token** (see below) * Your Framer **Project ID** *** ## Step 1: Get your Framer credentials ### API Token 1. Open your Framer project 2. Click the **Project Settings** gear icon (top-right) 3. Go to **Integrations -> API** 4. Click **Generate Token** and copy the token ### Project ID Your Project ID is visible in the project URL or in Project Settings. It looks like a long alphanumeric string. Treat your Framer API token like a password. Anyone with the token can create and modify content in your Framer CMS. Store it securely and never share it publicly. *** ## Step 2: Connect Framer in Siftly 1. In Siftly, go to **Settings -> Integrations** 2. Click **Connect** next to **Framer** 3. Enter your: * API Token * Project ID * Blog Base URL (optional — for building published URLs) 4. Click **Verify Connection** Siftly connects to your Framer project via the SDK and **automatically discovers all CMS collections**. You'll select which collection to use in the next step. *** ## Step 3: Schema Mapping ### Collection Selection After credentials are validated, Siftly shows a **dropdown of all CMS collections** discovered from your Framer project. Select the collection you want to publish to (e.g., "Blog Posts"). When you select a collection, Siftly fetches its field schema and presents them for mapping. ### Field Mapping Select fields from the dropdown for each mapping: #### Required Fields | Siftly Field | Description | Notes | | ------------ | ------------------------------------ | -------------------------------------- | | **Title** | The page or post title (H1) | Map to your collection's title field | | **Slug** | URL-friendly version of the title | Map to your collection's slug field | | **Body** | Full body content (rich text / HTML) | Map to your collection's content field | #### Optional Fields Leave any of these blank to skip them. When mapped, they are auto-populated from your content data. | Siftly Field | Suggested Framer Field Type | Notes | | -------------------- | ---------------------------- | ------------------------- | | **Meta Title** | Plain Text | SEO page title | | **Meta Description** | Plain Text | SEO description / excerpt | | **Keywords** | Plain Text (comma-separated) | Target keywords | | **Categories** | Plain Text (comma-separated) | Content categories | | **JSON-LD** | Plain Text (long) | Structured data markup | | **Word Count** | Number | Total word count | | **Hero Image** | Image | Featured image | #### JSON-LD Type Toggle When a JSON-LD field is mapped, a **text/json** toggle appears: * **json** (default): Sends as a parsed JSON object * **text**: Sends as a serialized JSON string For Framer, **text** is typically the right choice since Framer fields are usually plain text. If your Framer collection has different field names (e.g., `headline` instead of `title`), select the correct field from the dropdown. *** ## Custom Fields Add extra fields your Framer collection 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. Use the `value:label` format when your CMS expects specific IDs, slugs, or enum values that differ from the human-readable names shown to content editors. ### Use Existing Field (Source Fields) Link a custom field to auto-populate from existing content data: * **Title**, **Slug**, **Meta Title**, **Meta Description**, **Excerpt** * **Keywords**, **Categories**, **Word Count** * **JSON-LD**, **Hero Image** * **Date Published**, **Date Modified** (from JSON-LD graph) ### Editing Custom Fields Click the **pencil icon** on any existing custom field to edit its configuration inline. *** ## Publishing ### Draft vs Published When publishing, choose between: * **Draft** — content appears in your Framer CMS collection as a draft item for review * **Published** — content is created and published to your live Framer site ### Custom Fields at Publish Time Fields with **Use Existing Field** show as "Auto-populated from \[source]" in the publish dialog — no input needed. Manual custom fields appear pre-filled and editable. Standard fields (title, slug, body, meta data, keywords, categories, JSON-LD, word count) are auto-populated from your content — no manual input needed. *** ## Updating existing items By default, each publish from Siftly creates a **new** CMS item in Framer. To update an existing item instead: 1. In the Siftly content editor, click **Publish -> Framer -> Advanced** 2. Toggle **Update existing item** 3. Paste the **Framer item ID** of the item you want to update *** ## Troubleshooting Your API token is invalid or expired. Regenerate the token in Framer's Project Settings and update it in Siftly. Make sure your Framer project has at least one CMS collection created. The collection must exist before connecting. Check the Framer CMS panel for the item in **Drafts**. If published with Draft status, it won't be live. If a required field isn't mapped, the publish will fail. Ensure all required fields are mapped via the dropdown or have a default value set. Ensure you're on the latest version. Source fields are auto-populated server-side — no user input needed. *** ## Where to apply Siftly's recommendations on Framer Framer has visual SEO settings for basic meta fields, plus a custom code feature for advanced structured data. Here's where each field lives. ### Meta Title **Location:** CMS item → **SEO** tab → **Title** field When you open a CMS item in Framer's editor, the SEO tab shows the page title. This renders as the `` tag. **Via Siftly:** If you create a plain text field in your CMS collection (e.g., `meta-title`) and map Siftly's **Meta Title** to it, you can then bind that CMS field to the page's SEO Title in Framer's page settings. To bind a CMS field to the SEO title: 1. Open your CMS template page 2. Go to **Page Settings → SEO** 3. Click the variable icon (⚡) next to the Title field 4. Select your `meta-title` CMS field ### Meta Description **Location:** CMS item → **SEO** tab → **Description** field Same binding approach as meta title — create a CMS field, map it in Siftly, then bind it in Framer's page settings. ### Open Graph Image **Location:** CMS item → **SEO** tab → **Social Image** Framer uses the page's designated social image for OG tags. You can bind a CMS **Image** field to the social image slot. <Note> Siftly does not push image files to Framer. After publishing, upload your OG image to the CMS item in Framer's editor, or set a default social image in the page template. </Note> ### Canonical URL Framer auto-generates canonical URLs for all pages. No override is available via the CMS — it always points to the page's own URL. ### Tags & Categories Framer doesn't have a native tag/category taxonomy. Use a **Plain Text** CMS field with comma-separated values. Siftly pushes keywords as a comma-separated string to whatever plain text field you map. ### JSON-LD Structured Data Framer does NOT auto-generate JSON-LD. You must add it manually. **For static JSON-LD (same schema on all pages of a template):** 1. Open your CMS template page in Framer 2. Click **Page Settings → Custom Code → Head** 3. Paste the JSON-LD: ```html theme={null} <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "headline": "Your Article Title", "author": { "@type": "Organization", "name": "Your Brand" } } </script> ``` **For dynamic JSON-LD (unique per CMS item):** <Warning> Framer's custom code injection does NOT support CMS field variables. You cannot dynamically insert CMS field values into the Head code section. This means per-page dynamic JSON-LD is extremely limited in Framer. </Warning> **Workaround — Store JSON-LD in a CMS field and render via code component:** 1. Create a `json-ld` plain text (long) CMS field in your collection 2. Map Siftly's **JSON-LD** field to this CMS field 3. Create a Framer **Code Component** that reads the CMS field and renders it: ```tsx theme={null} // Framer Code Component import { useEffect } from "react"; export default function JsonLdInjector({ jsonLd }: { jsonLd?: string }) { useEffect(() => { if (!jsonLd) return; const script = document.createElement("script"); script.type = "application/ld+json"; script.textContent = jsonLd; document.head.appendChild(script); return () => { document.head.removeChild(script); }; }, [jsonLd]); return null; } ``` 4. Place this code component on your CMS template page and connect the `jsonLd` prop to your CMS field. <Note> Client-side injected JSON-LD (via JavaScript) may not be reliably crawled by all search engines. Google generally processes it, but some AI crawlers may not execute JavaScript. For maximum GEO impact, static head injection is preferred — but Framer's limitations make this difficult for dynamic content. </Note> ### Keywords Framer does not render a `<meta name="keywords">` tag natively. Store keywords in a CMS field for internal organization. If you need a keywords meta tag, use the same code component approach to inject it. *** ## Pushing Siftly recommendations automatically <Steps> <Step title="Generate content in Siftly"> Siftly produces your article plus meta title, meta description, keywords, and JSON-LD. </Step> <Step title="Click Publish → Framer"> Select your collection. Choose Draft or Published status. </Step> <Step title="Fields pushed via API"> All mapped fields (title, slug, body, meta title, meta description, keywords, JSON-LD, word count) are sent in a single call. The CMS item is created with all text fields populated. </Step> <Step title="Review in Framer"> Open the CMS item in Framer. Verify SEO fields are bound correctly in the template. Publish the site if changes are pending. </Step> </Steps> *** ## Platform-specific quirks & limitations <Warning> **Dynamic JSON-LD is severely limited.** Framer's Custom Code → Head section does NOT support CMS field variables. Per-page JSON-LD requires a code component that injects via JavaScript — which may not be reliably crawled by all AI engines. </Warning> <Warning> **No server-side rendering for code components.** Framer renders code components client-side. JSON-LD injected via code components is NOT in the initial HTML response — it requires JavaScript execution. This reduces reliability for AI crawlers. </Warning> <Note> **CMS plan required.** Framer's CMS feature requires at least the **Mini** plan (or higher). Free plans do not include CMS collections. </Note> * **SEO field binding:** Framer's SEO title and description can be bound to CMS fields, but you must set this up manually in the Framer Designer. Siftly pushes to the CMS field — Framer's template bindings render it. * **No categories/tags taxonomy:** Framer has no built-in taxonomy. Use plain text fields with comma-separated values. * **Publishing delay:** After creating a CMS item via API, Framer may need a site publish to reflect the change on your live domain. * **Image handling:** Framer CMS supports image fields, but Siftly cannot upload images via API. Upload images manually in Framer. * **Rich text limitations:** Framer's rich text field supports standard formatting but may strip unsupported HTML elements (tables, custom embeds). *** ## Validating the setup After publishing your first CMS item from Siftly: <Steps> <Step title="Check in Framer CMS panel"> Open your Framer project → CMS → find the new item. Verify all fields (title, body, meta fields, JSON-LD) are populated. </Step> <Step title="Preview the page"> Click the CMS item and preview the rendered page in Framer. Check that the SEO title and description appear in the page settings. </Step> <Step title="View the live page source"> After publishing the site, open the live page. Right-click → **View Page Source**. Search for: * `<title>` — should contain your meta title * `<meta name="description"` — should contain your meta description * `<script type="application/ld+json">` — should contain your JSON-LD (if using static head code or code component) </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your page URL. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) for additional validation. </Step> </Steps> *** ## Difficulty & setup recap <Card title="Framer Setup Summary" icon="frame"> | Aspect | Rating | | ----------------------- | ------------------------------------------------------------------------------------------------ | | **Initial setup** | ⚠️ Medium — API token + collection setup + field binding | | **Applying SEO fields** | ✅ Easy for meta title/description (visual binding) | | **JSON-LD** | ❌ Hard — static only in Head code; dynamic requires code component with JS-injection limitations | | **Ongoing editing** | ✅ Easy — publish from Siftly, items appear in Framer CMS | | **Developer needed?** | For JSON-LD code component — not for basic meta fields | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> # Ghost Integration Source: https://docs.siftly.ai/integrations/ghost Publish GEO-optimized content from Siftly directly to your Ghost blog using the Ghost Admin API. <Frame> <img alt="Supported CMS platforms including Ghost" /> </Frame> ## Overview This guide is for Ghost users who want to publish Siftly-generated GEO content and apply Siftly's SEO/GEO field recommendations. After following it, you'll be able to push optimized content to Ghost and understand where each meta field lives in the platform. **Difficulty:** ✅ Non-tech friendly — Ghost has built-in SEO fields, no plugins needed. Ghost is an open-source publishing platform built for professional blogs and newsletters. The Siftly–Ghost integration connects to your Ghost site via the **Ghost Admin API** and publishes content directly — either as a live post or a draft — using the unified 3-tier field mapping system. This integration is ideal for teams running Ghost-powered blogs who want to close the loop between SEO/GEO analysis and content execution inside a single workflow. *** ## Prerequisites Before connecting, you'll need: * A Ghost site (Ghost Pro or self-hosted Ghost 5.x+) * **Admin** access to your Ghost dashboard * A **Custom Integration** created in Ghost (see Step 1) <Note> The Ghost Admin API is available on all Ghost plans, including Ghost Pro and self-hosted installations. There is no plan restriction. </Note> *** ## Step 1: Create a Custom Integration in Ghost Ghost uses **Custom Integrations** to generate API credentials for third-party tools like Siftly. 1. Log in to your Ghost Admin dashboard (e.g., `https://yoursite.ghost.io/ghost`) 2. Go to **Settings** (bottom-left gear icon) 3. Click **Integrations** 4. Scroll to the bottom and click **Add custom integration** 5. Give it a name — e.g., **Siftly** 6. Click **Create** After creation, Ghost displays four pieces of information. You need **two** of them: | Field | Where to find it | Example | | ----------------- | -------------------------------- | ------------------------------------ | | **Admin API key** | Shown under the integration name | `69d9c7eeb369ab00013a5f2b:dde97d...` | | **API URL** | Shown below the Admin API key | `https://yoursite.ghost.io` | <Warning> The **Admin API key** grants full read/write access to your Ghost site, including image uploads to the Ghost media library — treat it like a password. Never share it publicly or commit it to source control. Siftly encrypts and stores it securely at rest. </Warning> <Note> The Admin API includes image upload access. Siftly uploads hero images and inline content images to Ghost's media library automatically at publish time — no additional configuration needed. </Note> The Admin API key is in the format `id:hex_secret` separated by a colon. Copy the entire string including both parts. *** ## Step 2: Connect Ghost in Siftly 1. In Siftly, go to **Settings → Integrations** 2. Under **CMS Integrations**, click **Ghost** 3. Enter your: * **API URL** — the base URL of your Ghost site (e.g., `https://yoursite.ghost.io`) * **Admin API key** — the full `id:hex_secret` string copied from Ghost * **Blog Base URL** *(optional)* — the public-facing URL of your blog (e.g., `https://mycompany.com/blog`) 4. Click **Connect Ghost** Siftly validates your credentials by making a test call to the Ghost Admin API. If validation succeeds, you'll see the **Connected** screen with your site URL confirmed. <Tip> If your Ghost site is on a custom domain (e.g., `https://blog.mycompany.com`), use that as the API URL — not the `.ghost.io` subdomain, unless that's your primary domain. </Tip> ### Blog Base URL (optional) The **Blog Base URL** field lets you set the public-facing domain for your blog, separate from the Ghost Admin API URL. This is useful when: * Your Ghost instance is hosted at `yoursite.ghost.io` but your public blog lives at `mycompany.com/blog` * You want Siftly to track and display the correct canonical post URL after publishing When set, Siftly builds the published post URL as: ``` {Blog Base URL}/{slug}/ ``` For example, if your Blog Base URL is `https://mycompany.com/blog` and your post slug is `intro-to-geo`, the tracked URL will be `https://mycompany.com/blog/intro-to-geo/`. If left blank, Siftly uses the post URL returned directly by the Ghost API. *** ## How Ghost authentication works Ghost's Admin API does not accept plain API keys in HTTP headers. Instead, it requires a **short-lived JWT token** signed from your Admin API key on every request. Siftly handles this automatically: 1. When you publish, Siftly splits your Admin API key into its `id` and `hex_secret` parts 2. It generates a JWT token signed with **HS256** using `bytes.fromhex(hex_secret)` as the signing key 3. The JWT carries a 5-minute expiry (`exp = iat + 300`) and the audience claim `"/admin/"` 4. Each request uses a freshly generated token — no token caching or refresh needed This is handled entirely server-side. Your Admin API key never leaves Siftly's backend after being saved. *** ## Field Mapping Ghost uses the unified 3-tier field mapping system. Ghost's built-in fields have fixed API names, so the required fields are pre-configured. ### Required Fields | Siftly Field | Ghost Post Field | Notes | | ------------ | ---------------- | --------------------------------------------- | | **Title** | `title` | Pre-configured — Ghost's built-in title field | | **Slug** | `slug` | Pre-configured — Ghost's built-in slug field | | **Body** | `html` | Pre-configured — sent via `?source=html` | ### Optional Fields When mapped, these are auto-populated from your content data. | Siftly Field | Ghost Post Field | Notes | | -------------------- | ---------------- | ------------------------------------------ | | **Meta Title** | `meta_title` | SEO page title | | **Meta Description** | `custom_excerpt` | Truncated to 300 characters | | **Keywords** | `tags` | Up to 10 tags, created if they don't exist | | **Categories** | — | Not natively supported by Ghost | | **JSON-LD** | — | Not natively supported by Ghost | | **Word Count** | — | Not natively supported by Ghost | <Note> Ghost has a fixed post schema — you map optional fields to the available Ghost post fields. Fields marked with "—" are not supported by Ghost's API and will be skipped. </Note> ### HTML content handling Siftly wraps the post body in Ghost's **HTML card** comments before sending: ```html theme={null} <!--kg-card-begin: html--> <your content here> <!--kg-card-end: html--> ``` This preserves your HTML exactly as Siftly generated it, preventing Ghost's Lexical editor from modifying headings, lists, links, or custom formatting during the conversion process. *** ## Custom Fields Add extra fields your Ghost posts require that aren't part of Siftly's standard content schema. Custom fields are sent as additional properties in the Ghost API payload. ### 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. <Tip> Use the `value:label` format when your CMS expects specific IDs, slugs, or enum values that differ from the human-readable names shown to content editors. </Tip> ### 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 Instead of setting a manual default, you can link a custom field to an existing content field. For example, map Ghost's `og_description` field to use the same value as **Meta Description**. This is useful when your Ghost setup has multiple fields that should contain the same data (e.g., `custom_excerpt` and `og_description` both using your meta description). *** ## Publishing ### Draft vs Published When publishing, choose between: * **Draft** — content is pushed to Ghost as a draft post for review in Ghost Admin * **Published** — the post is created and immediately published to your live site ### Custom Fields at Publish Time If you've defined custom fields, they appear in the publish dialog pre-filled with their default values (or auto-filled from linked fields). You can edit them before publishing. Standard fields (title, slug, body, meta data, keywords) are auto-populated from your content — no manual input needed. *** ## After publishing Once published, the post appears on your Ghost site (immediately if you chose Published, or in Ghost Admin drafts if you chose Draft). From Siftly you can: * **View the post** — click the published URL link in the content editor * **Track performance** — the post URL is saved to Siftly for citation and visibility analysis To make further edits, go to your Ghost Admin dashboard → **Posts** → find the post and edit it in Ghost's editor. <Note> Siftly does not support updating an existing Ghost post. Each publish creates a new post. To revise published content, edit it directly in Ghost Admin. </Note> *** ## Where to apply Siftly's recommendations on Ghost Ghost has built-in SEO fields on every post — no plugins required. Here's where each field lives and how Siftly's recommendations map to them. ### Meta Title **Location:** Post editor → click the gear icon (⚙️) → **Meta data → Meta title** Ghost renders this as the `<title>` tag and OG title. If left empty, Ghost uses the post title. Siftly auto-pushes the meta title to Ghost's `meta_title` field when you map it in your integration settings. ### Meta Description **Location:** Post editor → gear icon (⚙️) → **Meta data → Meta description** Ghost renders this as `<meta name="description">` and `og:description`. If left empty, Ghost auto-generates an excerpt from the first 500 characters of your post. Siftly maps this to `custom_excerpt` by default, which Ghost uses as both the visible excerpt and the meta description. ### Open Graph Image / Social Share Image **Location:** Post editor → gear icon (⚙️) → **Twitter card** and **Facebook card** sections Ghost supports separate OG images for Twitter and Facebook. Upload or paste an image URL in each section. <Tip> Ghost also uses the **Feature image** (the hero image at the top of the post) as the default OG image if no specific social images are set. Set a Feature Image and you get social sharing coverage automatically. </Tip> ### Canonical URL **Location:** Post editor → gear icon (⚙️) → **Meta data → Canonical URL** Ghost auto-generates a canonical URL pointing to the post's own URL. Override this field only for syndicated or cross-posted content. <Note> Siftly does not push canonical URL overrides. Ghost's default canonical (the post permalink) is correct for original content. </Note> ### Tags & Categories **Location:** Post editor → gear icon (⚙️) → **Tags** Ghost uses **Tags** for both categories and tags (there is no separate category system). The first tag is treated as the "primary tag" and often used by themes for navigation. Siftly pushes keywords as Ghost tags automatically. Tags that don't exist are created. Up to 10 tags per post. ### JSON-LD Structured Data **Ghost auto-generates Article JSON-LD** for every post. This includes: * `@type: Article` * `headline`, `datePublished`, `dateModified` * `author` with name and URL * `publisher` with logo * `image` from the feature image **You do NOT need to add Article schema manually.** Ghost handles it. **Supplemental schema (FAQ, HowTo, Product) — pushed automatically by Siftly:** When you map Siftly's **JSON-LD** field in your integration settings, Siftly wraps your JSON-LD in a `<script type="application/ld+json">` tag and pushes it directly to Ghost's `codeinjection_head` field on publish. This renders in the `<head>` of the post page automatically. No manual Code Injection editing is needed when the JSON-LD field mapping is configured. <Warning> Do NOT add an Article schema via Siftly's JSON-LD field — Ghost already generates one. Siftly's JSON-LD recommendations are designed to supplement with FAQ, HowTo, or Product schema, not duplicate the base Article schema. </Warning> <Note> If you prefer to add JSON-LD manually (or need to edit what Siftly pushed), go to: Post editor → gear icon (⚙️) → **Code injection → Post Header**. The `<script>` tag will already be there from Siftly's push. </Note> ### Keywords Ghost does not render a `<meta name="keywords">` tag. Keywords are handled through the **Tags** system, which Ghost exposes in its structured data and RSS feed. Siftly maps content keywords to Ghost tags automatically. *** ## Pushing Siftly recommendations automatically Siftly pushes all SEO fields to Ghost in a single publish action when mapped: <Steps> <Step title="Generate content in Siftly"> Use Siftly's content editor to generate or optimize your article. Siftly produces meta title, meta description, keywords, and JSON-LD recommendations. </Step> <Step title="Click Publish → Ghost"> In the content editor, click **Publish** and select **Ghost**. Choose Draft or Published status. </Step> <Step title="All mapped fields pushed automatically"> Title, slug, body (HTML), meta title (`meta_title`), meta description (`meta_description`), excerpt (`custom_excerpt`), tags, and JSON-LD (`codeinjection_head`) are all sent in one API call. No manual copy-paste needed. </Step> </Steps> <Tip> When JSON-LD is mapped, Siftly automatically wraps it in a `<script type="application/ld+json">` tag and pushes it to Ghost's `codeinjection_head` field. This renders in the `<head>` of your post page without any manual Code Injection editing. </Tip> *** ## Platform-specific quirks & limitations <Warning> **Article JSON-LD is auto-generated.** Ghost produces its own Article structured data. Do NOT add competing Article schema via Code Injection or you'll get duplicate schema warnings. </Warning> <Note> **No categories system.** Ghost uses Tags only. The first tag assigned to a post becomes the "primary tag," which many Ghost themes use for navigation sections. Order your Siftly keywords with the most important one first. </Note> * **Code Injection scope:** Siftly pushes JSON-LD to per-post `codeinjection_head`. Ghost also offers site-wide Code Injection (Settings → Code Injection) — use that for Organization schema that applies to all pages. * **No native Open Graph override via API:** Ghost's Admin API does not accept `og_image` directly on post creation. Feature images serve as OG images. Set your feature image after publishing from Siftly. * **Excerpt length:** Ghost truncates `custom_excerpt` at 300 characters. Siftly's meta description is auto-trimmed to fit. * **Members-only content:** If you use Ghost's membership features, posts published via Siftly default to "Public" visibility. Change visibility to "Members" or "Paid" in Ghost Admin after publishing if needed. *** ## Validating the setup After publishing your first post with Siftly's recommendations: <Steps> <Step title="View the live page source"> Open your published Ghost post in a browser. Right-click → **View Page Source**. Search for: * `<title>` — should contain your Siftly meta title (or post title if no meta title was set) * `<meta name="description"` — should contain your meta description * `<script type="application/ld+json">` — should show Ghost's auto-generated Article schema plus any supplemental schema you added </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your post URL. Confirm Article schema is valid and any FAQ/HowTo schema is detected. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) and paste your post URL. Check for errors or warnings. </Step> <Step title="Check social sharing"> Use [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/) to confirm OG image, title, and description. Ghost generates these from your post's feature image and meta data. </Step> </Steps> *** ## Difficulty & setup recap <Card title="Ghost Setup Summary" icon="ghost"> | Aspect | Rating | | ----------------------- | -------------------------------------------------------------------------------------------- | | **Initial setup** | ✅ Easy — Admin API key, no OAuth flow | | **Applying SEO fields** | ✅ Easy — Ghost has built-in meta title/description fields | | **JSON-LD** | ✅ Auto-generated Article schema; ✅ Siftly pushes supplemental schema to `codeinjection_head` | | **Ongoing editing** | ✅ Easy — publish from Siftly, edit in Ghost Admin | | **Developer needed?** | No | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> *** ## Disconnect Ghost To remove the Ghost integration: 1. Go to **Settings → Integrations → Ghost** 2. Click **Disconnect** This removes your stored credentials from Siftly. The posts already published to Ghost remain untouched — disconnecting does not delete any content. *** ## Troubleshooting <AccordionGroup> <Accordion title="Connection fails with 401 Unauthorized"> Your Admin API key is invalid or has been revoked. Go to Ghost Admin → **Settings → Integrations → Siftly** and verify the Admin API key matches what's entered in Siftly. If in doubt, delete the integration and create a new one to get a fresh key. </Accordion> <Accordion title="API URL is rejected"> The API URL must use **HTTPS** and must be publicly reachable. Common mistakes: * Using `http://` instead of `https://` * Including a trailing slash (Siftly strips it, but double-check) * Using an internal or localhost address (blocked for security) </Accordion> <Accordion title="Admin API key format error"> The Admin API key must contain exactly one colon separating the key ID and the hex secret. Example format: `69d9c7eeb369ab00013a5f2b:dde97da248911d15686a4d10...` Do not use the **Content API key** — that key is read-only and cannot create posts. Use the **Admin API key** only. </Accordion> <Accordion title="Post publishes but slug conflicts"> If a post with the same slug already exists in Ghost, the publish will fail with a 422 error. Either delete the existing post in Ghost or adjust the slug in your Siftly content draft before republishing. </Accordion> <Accordion title="Post content looks different in Ghost"> Siftly wraps content in Ghost HTML card comments (`<!--kg-card-begin: html-->`) to preserve formatting. If you see raw HTML comments in the editor, Ghost may not have processed the source correctly — ensure your Ghost version is 5.x or later, which has full HTML card support. </Accordion> <Accordion title="Tags are not appearing on the post"> Ghost creates tags automatically from the names Siftly sends. If tags aren't showing, check your Ghost Admin → **Tags** to confirm they were created. Ensure the keywords in your Siftly content are not empty. </Accordion> </AccordionGroup> *** ## Security Siftly takes the following measures to protect your Ghost credentials: * **Encryption at rest** — the Admin API key is encrypted using Fernet symmetric encryption before being stored in the database. The plaintext key is never persisted. * **SSRF protection** — the Ghost API URL is validated on both connect and publish. Private IP ranges, localhost, and non-HTTPS URLs are blocked. * **Short-lived tokens** — JWT tokens are generated fresh on every API call with a 5-minute expiry. No tokens are stored. * **Never returned to the client** — the Admin API key is never included in any response sent to the browser. # CMS Integrations Source: https://docs.siftly.ai/integrations/overview Publish Siftly-generated content directly to your website from your favorite CMS platform. ## Why integrate your CMS? Siftly generates GEO-optimized content — but that content only works when it's published. CMS integrations close the gap between analysis and execution, letting you push content from Siftly directly to your website without copying, pasting, or switching tabs. <Frame> <img alt="Supported CMS platforms — WordPress, Ghost, Webflow, Strapi, Sanity, and Framer" /> </Frame> ## Supported platforms <CardGroup> <Card title="WordPress" icon="wordpress" href="/integrations/wordpress"> Publish posts directly to your WordPress.com blog using secure OAuth2. No API keys required. </Card> <Card title="Ghost" icon="ghost" href="/integrations/ghost"> Publish posts live to your Ghost blog instantly using the Ghost Admin API with JWT auth. </Card> <Card title="Webflow" icon="code" href="/integrations/webflow"> Create CMS items in any Webflow collection via the Webflow Data API v2. </Card> <Card title="Strapi" icon="database" href="/integrations/strapi"> Push content into Strapi 5 collections via the REST API with full Draft & Publish support. </Card> <Card title="Sanity" icon="circle-dot" href="/integrations/sanity"> Create and update documents in Sanity Studio with structured content and rich text blocks. </Card> <Card title="Wix" icon="w" href="/integrations/wix"> Publish articles directly to Wix blog and pages via Wix's Headless CMS API. </Card> <Card title="Framer" icon="frame" href="/integrations/framer"> Push pages and blog posts to Framer sites with full CMS collection support. </Card> <Card title="Duda" icon="webhook" href="/integrations/duda"> Publish blog posts to Duda websites via Make.com webhook automation. </Card> </CardGroup> ## Platform comparison | Platform | Difficulty | Image Upload | JSON-LD Support | Meta Fields | Siftly Push Method | Guide | | ------------- | ----------- | -------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------- | ---------------------------------- | | **WordPress** | ✅ Easy | ✅ Media library | Via Yoast/Rank Math plugin or Custom HTML block | Via SEO plugin fields | REST API + Application Passwords / OAuth | [Guide →](/integrations/wordpress) | | **Ghost** | ✅ Easy | ✅ Media library | Auto-generated Article; Siftly pushes supplemental schema to `codeinjection_head` | Built-in `meta_title`, `custom_excerpt` | Admin API + JWT | [Guide →](/integrations/ghost) | | **Webflow** | ⚠️ Medium | ✅ Assets CDN | Manual Embed element with `{{wf ...}}` syntax | CMS field bindings in Page Settings | Data API v2 + token | [Guide →](/integrations/webflow) | | **Strapi** | ⚠️ Medium | ✅ Media library | Stored in schema; frontend renders | `@strapi/plugin-seo` component or custom fields | REST API + token | [Guide →](/integrations/strapi) | | **Sanity** | ❌ Developer | ✅ Assets API | Stored in schema; frontend renders | Custom `seo` object type; frontend renders | Content Lake API + token | [Guide →](/integrations/sanity) | | **Wix** | ✅ Easy | ✅ Media (URL import) | SEO → Advanced (paid plan only) | Built-in SEO panel per post | Content Manager API + key | [Guide →](/integrations/wix) | | **Framer** | ⚠️ Medium | ❌ No upload API | Static in Head code; dynamic requires code component (JS) | CMS field bound to page SEO settings | CMS API + token | [Guide →](/integrations/framer) | | **Duda** | ✅ Easy | ❌ No upload API | Not supported via automation | Description field only | Make.com webhook | [Guide →](/integrations/duda) | <Tip> **Not sure which CMS to use?** Read our [guide to choosing a CMS for AI visibility](https://siftly.ai/blog/cms-and-ai-visibility) — it compares platforms through the lens of GEO optimization. </Tip> *** ## How integrations work All CMS integrations follow the same basic flow: <Steps> <Step title="Enter credentials"> In Siftly's **Settings -> Integrations**, provide your CMS credentials (API key, token, project ID). Siftly validates the connection and discovers available collections. </Step> <Step title="Select collection and map fields"> Choose which collection or document type to publish to (shown as a dropdown of discovered types). Siftly discovers all fields — including nested ones — and suggests mappings via AI. Edit or add custom fields as needed. </Step> <Step title="Publish from the content editor"> In the Siftly content editor, click **Publish -> \[Your CMS]** and choose whether to publish live or save as a draft. Fields with "Use Existing" sources are auto-filled. </Step> <Step title="Review in your CMS"> Depending on your chosen status, content either goes live immediately or lands as a draft in your CMS for review. </Step> </Steps> *** ## Unified Field Mapping Every CMS integration (except Wix, which uses fixed API fields) shares the same 3-tier field mapping system. This gives you a consistent experience regardless of which CMS you use. ### Tier 1 — Required Fields These three fields must be mapped during setup. They define where Siftly writes the core content. | Siftly Field | Description | | ------------ | ------------------------------ | | **Title** | The article or page title | | **Slug** | URL-friendly identifier | | **Body** | Full HTML or rich-text content | ### Tier 2 — Optional Fields Optional fields are auto-populated from your content data when mapped. Leave any field unmapped to skip it. | Siftly Field | Description | | -------------------- | --------------------------------------------------- | | **Meta Title** | SEO page title | | **Meta Description** | SEO description / excerpt | | **Keywords** | List of target keywords | | **Categories** | Content categories | | **JSON-LD** | Structured data markup (with text/json type toggle) | | **Word Count** | Total word count of the content | | **Hero Image** | Featured/banner image | ### Tier 3 — Custom Fields Add any extra fields your CMS schema requires that aren't part of Siftly's standard content model. Custom fields support five types: | Type | Description | | ----------- | -------------------------------------- | | **String** | Plain text value | | **Number** | Numeric value | | **Boolean** | True or false | | **JSON** | Structured object or array | | **Select** | Pick from a predefined list of options | Each custom field can have a **default value** that pre-fills at publish time, or it can be linked to an existing content source using **Use Existing Field** — so you can reuse the same data in multiple CMS fields without entering it twice. Available sources: Title, Slug, Meta Title, Meta Description, Excerpt, Keywords, Categories, JSON-LD, Word Count, Hero Image, **Date Published**, **Date Modified**. Custom fields are **editable** after creation — click the pencil icon to change any field's configuration. <Tip> For example, if your CMS has a nested `seo.metaDescription` field AND a top-level `excerpt` field that should both contain the same text, map one as the optional Meta Description field and add the other as a custom field with source linked to **Meta Description**. </Tip> *** ## Draft vs Published When publishing to any CMS, you can choose between: * **Draft** — content is pushed to your CMS as a draft for review before going live * **Published** — content goes live immediately This toggle appears in the publish dialog for every CMS integration. <Note> Some CMS platforms (like Wix) always create content as drafts regardless of the status you select. Check the individual CMS integration page for platform-specific behavior. </Note> # Sanity Integration Source: https://docs.siftly.ai/integrations/sanity Connect Siftly to your Sanity Studio and publish GEO-optimized content as structured documents using Sanity's Content Lake API. <Frame> <img alt="Supported CMS platforms including Sanity" /> </Frame> ## 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 1. Log in to [sanity.io/manage](https://sanity.io/manage) 2. Select your project 3. Copy the **Project ID** from the project overview page 4. Note your **Dataset** name (usually `production`) ### API Token 1. In Sanity Manage, go to **API -> Tokens** 2. Click **Add API Token** 3. Give it a descriptive name (e.g., "Siftly Integration") 4. Set the permission level to **Editor** 5. Click **Save** and copy the token <Warning> Sanity API tokens with Editor permissions can create, modify, and delete documents, and upload assets (images) to the Content Lake. Store the token securely and restrict it to the minimum dataset it needs access to. </Warning> <Note> 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. </Note> *** ## Step 2: Connect Sanity in Siftly 1. In Siftly, go to **Settings -> Integrations** 2. Click **Connect** next to **Sanity** 3. Enter your: * Project ID * Dataset name * API Token 4. Click **Verify Connection** Siftly will connect to your Content Lake and validate the credentials. If successful, you move to the schema mapping step. *** ## 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 Choose based on your Sanity schema's field type for this field. ### 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) These are shown in the dropdown with `>` 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 `htmlEmbed` block containing the full HTML. Your schema needs an `htmlEmbed` type 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 <Note> Custom Portable Text block types (e.g., call-out cards, custom embeds) are not supported by the auto-converter. </Note> *** ## 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. <Tip> Use the `value:label` format when your CMS expects specific IDs, slugs, or enum values that differ from the human-readable names shown to content editors. </Tip> ### 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) This is especially useful for nested fields. For example: * `seo.metaTitle` -> Use Existing: **Meta Title** * `seo.wordCount` -> Use Existing: **Word Count** * `schemaOrg.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 `publishedAt` set ### 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 uses `createOrReplace` 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: ```groq theme={null} *[_type == "post" && slug.current == "your-slug"][0] { title, slug, body, publishedAt, status } ``` *** ## 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. 1. In Sanity Manage, go to **API → Webhooks → Add Webhook** 2. Set the URL to your frontend's webhook endpoint 3. Copy the webhook URL 4. In Siftly → **Settings → Integrations → Sanity → Advanced**, paste the webhook URL in **Post-publish webhook** Siftly will call this URL with a POST request after each successful publish. *** ## 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 reusable `seo` object type that you can add to any document type: <CodeGroup> ```typescript sanity/schemaTypes/objects/seo.ts theme={null} import { defineType, defineField } from 'sanity'; export const seo = defineType({ name: 'seo', title: 'SEO & GEO Fields', type: 'object', fields: [ defineField({ name: 'metaTitle', title: 'Meta Title', type: 'string', description: 'Page title for search engines and AI citations (50-60 characters ideal)', validation: (Rule) => Rule.max(70).warning('Keep under 60 characters for best results'), }), defineField({ name: 'metaDescription', title: 'Meta Description', type: 'text', rows: 3, description: 'Page description for search engines and social sharing (150-160 characters ideal)', validation: (Rule) => Rule.max(160).warning('Keep under 160 characters'), }), defineField({ name: 'ogImage', title: 'Open Graph Image', type: 'image', description: 'Social sharing image (1200x630px recommended)', options: { hotspot: true }, }), defineField({ name: 'canonicalUrl', title: 'Canonical URL', type: 'url', description: 'Override canonical URL (leave empty to use default page URL)', }), defineField({ name: 'keywords', title: 'Keywords', type: 'array', of: [{ type: 'string' }], description: 'Target keywords for this content', options: { layout: 'tags' }, }), defineField({ name: 'jsonLd', title: 'JSON-LD Structured Data', type: 'text', rows: 10, description: 'Paste Siftly\'s JSON-LD recommendation here. Must be valid JSON.', }), ], }); ``` ```typescript sanity/schemaTypes/documents/post.ts theme={null} import { defineType, defineField } from 'sanity'; export const post = defineType({ name: 'post', title: 'Blog Post', type: 'document', fields: [ defineField({ name: 'title', type: 'string' }), defineField({ name: 'slug', type: 'slug', options: { source: 'title' } }), defineField({ name: 'body', type: 'array', of: [{ type: 'block' }] }), defineField({ name: 'publishedAt', type: 'datetime' }), defineField({ name: 'tags', type: 'array', of: [{ type: 'string' }], options: { layout: 'tags' } }), defineField({ name: 'wordCount', type: 'number' }), // SEO object — all GEO fields in one place defineField({ name: 'seo', title: 'SEO & GEO', type: 'seo', }), ], }); ``` </CodeGroup> ### 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):** ```tsx theme={null} // app/blog/[slug]/page.tsx import { client } from '@/sanity/lib/client'; export async function generateMetadata({ params }) { const post = await client.fetch( `*[_type == "post" && slug.current == $slug][0]{ title, "metaTitle": seo.metaTitle, "metaDescription": seo.metaDescription, "ogImage": seo.ogImage.asset->url }`, { slug: params.slug } ); return { title: post.metaTitle || post.title, description: post.metaDescription, openGraph: { title: post.metaTitle || post.title, description: post.metaDescription, images: post.ogImage ? [{ url: post.ogImage }] : [], }, }; } ``` ### 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) <Note> 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. </Note> ### Canonical URL **Schema location:** `seo.canonicalUrl` **Frontend rendering:** ```tsx theme={null} export async function generateMetadata({ params }) { const post = await client.fetch(`*[_type == "post" && slug.current == $slug][0]{ "canonicalUrl": seo.canonicalUrl, "slug": slug.current }`, { slug: params.slug }); return { alternates: { canonical: post.canonicalUrl || `/blog/${post.slug}`, }, }; } ``` ### 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: ```tsx theme={null} <meta name="keywords" content={post.tags?.join(', ')} /> ``` ### 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:** ```tsx theme={null} // app/blog/[slug]/page.tsx export default async function PostPage({ params }) { const post = await client.fetch( `*[_type == "post" && slug.current == $slug][0]{ title, body, "jsonLd": seo.jsonLd }`, { slug: params.slug } ); return ( <> {post.jsonLd && ( <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: post.jsonLd }} /> )} <article> {/* Render post.body with PortableText */} </article> </> ); } ``` <Tip> For maximum GEO impact, Siftly's JSON-LD recommendations typically include Article, FAQ, or HowTo schema. Store the entire JSON-LD object in the `seo.jsonLd` field and render it verbatim in your frontend's `<head>`. </Tip> ### 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 <Steps> <Step title="Generate content in Siftly"> Siftly produces your article plus meta title, meta description, keywords, JSON-LD, and word count. </Step> <Step title="Click Publish → Sanity"> Select your document type. Choose Draft or Published status. </Step> <Step title="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. </Step> <Step title="Frontend picks up new content"> Your frontend queries the new document via GROQ and renders all meta tags, JSON-LD, and content from the populated fields. </Step> </Steps> *** ## GROQ query for all SEO fields Use this query to fetch everything your frontend needs for a complete GEO-optimized page: ```groq theme={null} *[_type == "post" && slug.current == $slug][0] { title, "slug": slug.current, body, publishedAt, tags, wordCount, "seo": { "metaTitle": seo.metaTitle, "metaDescription": seo.metaDescription, "ogImage": seo.ogImage.asset->url, "canonicalUrl": seo.canonicalUrl, "keywords": seo.keywords, "jsonLd": seo.jsonLd } } ``` *** ## Platform-specific quirks & limitations <Warning> **Nothing renders automatically.** Sanity stores structured content — it does NOT generate any HTML, meta tags, or JSON-LD output. Your frontend is 100% responsible for reading these fields and rendering them as proper HTML `<meta>` tags and `<script type="application/ld+json">` blocks. </Warning> <Note> **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. </Note> * **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 the `seo.jsonLd` text field instead. * **Real-time preview:** Sanity's real-time preview (via `next-sanity` or `@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., `production` and `staging`), make sure Siftly is connected to the correct dataset for your publishing workflow. *** ## Validating the setup After publishing your first document from Siftly: <Steps> <Step title="Check in Sanity Studio"> Open Sanity Studio → find your new document → verify all fields (title, body, SEO object, tags, JSON-LD) are populated. </Step> <Step title="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. </Step> <Step title="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 </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your URL. Confirm structured data is detected and valid. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) for additional validation. </Step> </Steps> *** ## Difficulty & setup recap <Card title="Sanity Setup Summary" icon="circle-dot"> | 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 | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> *** ## Troubleshooting <AccordionGroup> <Accordion title="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. </Accordion> <Accordion title="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. </Accordion> <Accordion title="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. </Accordion> <Accordion title="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. </Accordion> <Accordion title="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. </Accordion> </AccordionGroup> # Strapi Integration Source: https://docs.siftly.ai/integrations/strapi Connect Siftly to your Strapi CMS and publish GEO-optimized content directly to your collections via the Strapi REST API. ## Overview This guide is for Strapi users who want to publish Siftly-generated content and apply GEO/SEO field recommendations (meta tags, JSON-LD, keywords) directly to their Strapi collections. After following it, you'll be able to push optimized content with full SEO metadata into your Strapi schema and render it correctly on your frontend. **Difficulty:** ⚠️ Some technical setup — Strapi is headless, so you control the schema and frontend rendering. Strapi is an open-source headless CMS that lets you design your own content types and serve them through a REST or GraphQL API. The Siftly–Strapi integration pushes content directly into your collection using the Strapi REST API, respecting your schema's field names and Draft & Publish settings. <Frame> <img alt="Siftly to Strapi publish flow — content editor to REST API to live entry" /> </Frame> This integration is built for **Strapi 5** (self-hosted and Strapi Cloud). Strapi 4 instances will also work for basic fields, but new features like the `?status=` query parameter and `documentId` responses require Strapi 5. *** ## Prerequisites Before connecting, you'll need: * A running Strapi 5 instance — either Strapi Cloud or a self-hosted deployment reachable over the public internet * Admin access to the Strapi dashboard so you can create an API token * A **collection type** with at least a title, slug and content/body field (e.g. the default `articles` collection) <Note> Local Strapi instances on `http://localhost:1337` can only be used by Siftly when running Siftly in development mode. Production Siftly requires an HTTPS endpoint reachable from the internet, such as `https://cms.yourdomain.com`. </Note> *** ## Step 1: Create a Strapi API token Siftly authenticates with Strapi using a **server-to-server API token** — no OAuth involved. You generate this token once inside the Strapi admin panel. 1. Log in to your Strapi admin panel (`https://your-strapi-host/admin`) 2. Go to **Settings -> Global Settings -> API Tokens** 3. Click **Create new API Token** 4. Fill out the form: * **Name**: `Siftly` (or anything memorable) * **Description**: *optional* * **Token duration**: **Unlimited** is recommended so publishing doesn't break when the token silently expires * **Token type**: **Full access** (recommended) or **Custom** (see below) 5. Click **Save** 6. Copy the token shown on the confirmation screen — **Strapi only displays it once** <Warning> Strapi shows the token only on the creation screen. If you navigate away before copying it, you'll need to regenerate the token. Store it in a password manager. </Warning> ### Required permissions | Siftly action | Strapi permission | API call | | -------------------------- | ---------------------------------- | ---------------------------------------------- | | Validate the connection | `find` on your collection | `GET /api/{collection}?pagination[pageSize]=1` | | Publish content | `create` on your collection | `POST /api/{collection}?status=published` | | Save as draft | `create` on your collection | `POST /api/{collection}?status=draft` | | Publish now (D\&P enabled) | `publish` on your collection | part of the same `POST` above | | Upload images | `upload` on Upload (Media Library) | `POST /api/upload` | #### Option A — Full access (easiest) Select **Full access** when creating the token. This grants every permission on every content type, including the Upload (Media Library) API. #### Option B — Custom token (least privilege) 1. Set **Token type** to **Custom** 2. Expand your collection (e.g. `Article`) 3. Tick: `find`, `create`, and `publish` (if Draft & Publish is enabled) 4. Expand **Upload** (Media Library) 5. Tick: `upload` — required so Siftly can upload hero images and inline content images to your Strapi Media Library <Warning> If the **Upload** permission is missing, Siftly can still publish text content, but images will reference external URLs instead of being hosted in your Strapi Media Library. For best results, always grant the `upload` permission. </Warning> *** ## Step 2: Connect Strapi in Siftly 1. In Siftly, go to **Settings -> Integrations** 2. Click **Connect** next to **Strapi** 3. Fill in: | Field | Description | Example | | ------------- | ---------------------------------------------------------------------------- | --------------------------- | | **Base URL** | Root URL of your Strapi instance. No trailing slash, no `/admin`, no `/api`. | `https://cms.mycompany.com` | | **API Token** | The Full access or custom token from Step 1. | `f0a1...` | 4. Click **Next** Siftly validates that the URL is reachable and attempts to discover available content types. If discovery succeeds, you'll see a dropdown of collection types in the next step. *** ## Step 3: Schema Mapping ### Collection Type Selection After credentials are validated, select which collection to publish into: * **Dropdown** (if Siftly discovered your collections): Select from the list * **Text input** (if discovery wasn't possible with your token): Enter the **plural API ID** (e.g., `articles`) Find the API ID in Strapi under **Content-Type Builder -> your type -> Advanced Settings -> API ID (Plural)**. ### Content Field Format Strapi 5 has two common rich-text field types: | Format | When to pick it | What Siftly sends | | ---------------------- | --------------------------------------------------------------------------------- | ------------------ | | **HTML / Markdown** | Content field is `Text (long)`, `Rich text (Markdown)`, or any plain-string field | Raw HTML string | | **Rich text (Blocks)** | Content field is the Strapi 5 **Rich text (Blocks)** type | Strapi Blocks JSON | ### Field Mapping Siftly discovers your collection's fields by fetching a sample document. Fields inside **Strapi components** are recursively flattened into dot-notation paths (e.g., `seo.metaTitle`). Select fields from the dropdown for each mapping: #### Required Fields | Siftly Field | Default Strapi Name | Notes | | ------------ | ------------------- | --------------------------------------- | | **Title** | `title` | Plain text | | **Slug** | `slug` | Typically a Strapi **UID** field | | **Body** | `content` | Format controlled by the selector above | #### Optional Fields | Siftly Field | Typical Strapi Name | Field Type | | -------------------- | --------------------- | ------------------------------------ | | **Meta Title** | `seo.metaTitle` | Text, inside an SEO component | | **Meta Description** | `seo.metaDescription` | Text (long), inside an SEO component | | **Keywords** | `keywords` | JSON array of strings | | **Categories** | `categories` | JSON array of strings | | **JSON-LD** | `jsonLd` | JSON field or Text (long) | | **Word Count** | `wordCount` | Number (integer) | | **Hero Image** | `cover` | Image/media 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 (Strapi JSON fields accept this natively) * **text**: Sends as a serialized JSON string #### Dot Notation for Components Strapi Components live under a named key. Siftly supports dot notation: ``` seo.metaTitle -> data.seo.metaTitle seo.metaDescription -> data.seo.metaDescription ``` *** ## Custom Fields Add extra fields your Strapi collection requires that aren't part of Siftly's standard 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 | ### 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. <Tip> Use the `value:label` format when your CMS expects specific IDs, slugs, or enum values that differ from the human-readable names shown to content editors. </Tip> ### Use Existing Field (Source Fields) Link a custom field to auto-populate from existing content data: * **Title**, **Slug**, **Meta Title**, **Meta Description**, **Excerpt** * **Keywords**, **Categories**, **Word Count** * **JSON-LD**, **Hero Image** * **Date Published**, **Date Modified** (from JSON-LD graph) ### Editing Custom Fields Click the **pencil icon** on any existing custom field to edit its configuration inline. *** ## Publishing ### Draft vs Published | Siftly Status | Strapi Behavior | Visible on public site? | | ------------- | ------------------------------------------ | ---------------------------- | | **Published** | Document created and immediately published | Yes | | **Draft** | Document created as a draft | No — publish in Strapi Admin | ### Custom Fields at Publish Time Fields with **Use Existing Field** show as "Auto-populated from \[source]" — no input needed. Manual fields appear pre-filled and editable. ### Idempotency Every publish creates a new entry. Re-publishing sends a fresh `POST` and Strapi assigns a new `documentId`. *** ## Troubleshooting <AccordionGroup> <Accordion title="401 Invalid Strapi API token"> Regenerate a **Full access** token and paste the complete token. </Accordion> <Accordion title="403 Insufficient permissions"> Your token lacks `find`, `create`, or `publish`. Switch to Full access or add permissions. </Accordion> <Accordion title="404 Collection not found"> The collection type must be the **plural API ID** (e.g., `articles`, not `Article`). </Accordion> <Accordion title="400 "must be an array" or "must be a string""> Content-field format mismatch. Switch between **HTML / Markdown** and **Rich text (Blocks)** in the mapping step. </Accordion> <Accordion title="Fields with Use Existing show empty values"> This was fixed — ensure you're on the latest version. Fields with source\_field are auto-populated server-side at publish time. </Accordion> </AccordionGroup> *** ## Where to apply Siftly's recommendations on Strapi Strapi is headless — it stores data but doesn't render HTML. You control where SEO fields live in your schema and how your frontend renders them. Here's the recommended setup. ### Recommended: Use the `@strapi/plugin-seo` plugin Strapi has an official SEO plugin that adds a reusable **SEO component** to your content types: ```bash theme={null} npm install @strapi/plugin-seo # or yarn add @strapi/plugin-seo ``` After installing, add the SEO component to your article collection type in the Content-Type Builder. This gives you: * `seo.metaTitle` — Meta title field * `seo.metaDescription` — Meta description field * `seo.metaImage` — OG image (media field) * `seo.keywords` — Keywords * `seo.canonicalURL` — Canonical URL override * `seo.structuredData` — JSON-LD structured data (JSON field) Siftly maps directly to these fields using dot notation (e.g., `seo.metaTitle`). ### Meta Title **Schema location:** `seo.metaTitle` (via SEO plugin) or a custom `metaTitle` text field. **Frontend rendering (Next.js example):** ```tsx theme={null} // app/blog/[slug]/page.tsx export async function generateMetadata({ params }) { const article = await getArticle(params.slug); return { title: article.seo?.metaTitle || article.title, }; } ``` ### Meta Description **Schema location:** `seo.metaDescription` (via SEO plugin) or a custom `metaDescription` text field. **Frontend rendering:** ```tsx theme={null} export async function generateMetadata({ params }) { const article = await getArticle(params.slug); return { title: article.seo?.metaTitle || article.title, description: article.seo?.metaDescription || article.excerpt, }; } ``` ### Open Graph Image **Schema location:** `seo.metaImage` (media field via SEO plugin) or a custom image URL text field. <Note> Siftly uploads hero images to your Strapi Media Library and links them to media fields automatically. Map your hero image field to `cover` or `seo.metaImage` and Siftly handles the upload and relation linking at publish time. </Note> ### Canonical URL **Schema location:** `seo.canonicalURL` or a custom `canonicalUrl` text field. **Frontend rendering:** ```tsx theme={null} export async function generateMetadata({ params }) { const article = await getArticle(params.slug); return { alternates: { canonical: article.seo?.canonicalURL || `/blog/${article.slug}`, }, }; } ``` ### Tags & Categories **Schema location:** Use a JSON array field (`keywords`) or a Relation field linking to a Tags collection. Siftly pushes keywords as a JSON array of strings. Your frontend can render them as `<meta name="keywords">` or use them for internal filtering/navigation. ### JSON-LD Structured Data **Schema location:** `seo.structuredData` (JSON field via SEO plugin) or a custom `jsonLd` text (long) field. Siftly pushes the full JSON-LD object as a stringified JSON value. Your frontend renders it in the `<head>`: ```tsx theme={null} // app/blog/[slug]/page.tsx export default async function ArticlePage({ params }) { const article = await getArticle(params.slug); return ( <> {article.seo?.structuredData && ( <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(article.seo.structuredData), }} /> )} <article>{/* content */}</article> </> ); } ``` ### Keywords **Schema location:** `keywords` JSON array field, or `seo.keywords` if using the SEO plugin. **Frontend rendering:** ```html theme={null} <meta name="keywords" content={article.keywords?.join(', ')} /> ``` *** ## Pushing Siftly recommendations automatically <Steps> <Step title="Generate content in Siftly"> Siftly produces your article plus meta title, meta description, keywords, and JSON-LD. </Step> <Step title="Click Publish → Strapi"> Select your Strapi collection. Choose Draft or Published status. </Step> <Step title="All mapped fields pushed in one call"> Siftly sends a single `POST /api/{collection}` with all mapped fields — content body, SEO component fields, keywords, JSON-LD — in one API call. </Step> <Step title="Frontend picks up new content"> Your frontend (Next.js, Nuxt, Gatsby, etc.) fetches the new entry on the next request or build. All SEO metadata renders from the populated fields. </Step> </Steps> *** ## Platform-specific quirks & limitations <Warning> **Nothing is automatic.** Strapi is headless — it stores data but renders nothing. Every meta tag, JSON-LD block, and OG tag must be explicitly rendered by your frontend code. If your frontend doesn't read and render `seo.metaTitle`, it won't appear in HTML regardless of what Siftly pushes to Strapi. </Warning> <Note> **SEO plugin version:** The `@strapi/plugin-seo` component structure may vary between Strapi 4 and Strapi 5. Verify field paths in your Content-Type Builder after installation. </Note> * **Media uploads:** Siftly uploads hero images and inline content images to your Strapi Media Library automatically at publish time. The `upload` permission on the API token is required (included in Full access tokens). * **Relation fields:** If your categories/tags are a separate collection type with Relations, Siftly cannot create or link relations automatically. Use JSON array fields instead. * **Component validation:** If your SEO component has required fields (e.g., `metaTitle` is required), Siftly must map and populate them — otherwise the publish will fail with a 400 validation error. * **Draft & Publish:** When enabled, entries created as "Published" are immediately visible to your frontend's published-content queries. Draft entries require manual publish in Strapi Admin. * **Incremental Static Regeneration:** If your frontend uses ISR (Next.js) or similar, new content may take up to your revalidation period to appear. Trigger a revalidation webhook from Strapi for instant updates. *** ## Validating the setup After publishing your first entry from Siftly: <Steps> <Step title="Check the entry in Strapi Admin"> Open your Strapi Admin → collection → find the new entry. Verify all fields (title, slug, body, SEO component, JSON-LD) are populated correctly. </Step> <Step title="View the live page source"> Open the rendered page on your frontend. Right-click → **View Page Source**. Search for: * `<title>` — should contain your meta title value from Strapi * `<meta name="description"` — should contain your meta description * `<script type="application/ld+json">` — should contain your JSON-LD </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your page URL. Confirm JSON-LD is detected and valid. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) for additional validation. </Step> </Steps> *** ## Difficulty & setup recap <Card title="Strapi Setup Summary" icon="database"> | Aspect | Rating | | ----------------------- | ------------------------------------------------------------- | | **Initial setup** | ⚠️ Medium — API token + schema design + field mapping | | **Applying SEO fields** | ⚠️ Requires `@strapi/plugin-seo` or custom schema design | | **JSON-LD** | ⚠️ Stored in Strapi, but frontend must render it explicitly | | **Ongoing editing** | ✅ Easy — publish from Siftly, content appears in Strapi Admin | | **Developer needed?** | Yes — for initial schema setup and frontend rendering code | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> # Webflow Integration Source: https://docs.siftly.ai/integrations/webflow Publish GEO-optimized content from Siftly directly to a Webflow CMS collection using the Webflow Data API v2. <Frame> <img alt="Supported CMS platforms including Webflow" /> </Frame> ## Overview This guide is for Webflow users who want to publish Siftly-generated content to their CMS collections and apply GEO/SEO recommendations (meta tags, JSON-LD, keywords). After following it, you'll know how to connect Siftly, map fields, and ensure structured data renders correctly on your Webflow site. **Difficulty:** ⚠️ Some technical setup — Webflow's SEO fields are straightforward, but dynamic JSON-LD requires custom code embeds. The Siftly–Webflow integration uses the **Webflow Data API v2** to create and publish CMS collection items directly from Siftly's content editor. Your content fields are mapped to your Webflow collection schema using the unified 3-tier field mapping system — no copy-pasting required. *** ## Prerequisites Before connecting, you'll need: * A Webflow site with at least one **CMS Collection** set up * A **Webflow API v2 personal access token** with the correct permissions (see below) * Your Webflow **Site ID** * The **field slugs** of your collection's content fields *** ## Step 1: Create a Webflow API token Webflow uses personal access tokens to authenticate third-party integrations. 1. Log in to [webflow.com](https://webflow.com) and open your site 2. Go to **Site Settings → Integrations → API Access** 3. Under **Personal access tokens**, click **Generate API token** 4. Give it a name, e.g. `Siftly` 5. Set the token expiry (choose **No expiry** for a persistent connection) ### Required permissions When setting up the token you'll see a long list of permission scopes. **You need to enable three:** <Note> All other scopes (Pages, Ecommerce, Forms, etc.) can stay on **No access**. Granting unnecessary scopes is a security risk. </Note> | Scope | Permission level | Why it's needed | | ---------- | ---------------- | ------------------------------------------------------------- | | **CMS** | Read + Write | List collections, create items, publish items | | **Assets** | Read + Write | Upload hero images and inline content images to Webflow's CDN | | **Sites** | Read | Validate your Site ID and fetch site metadata | Here's exactly what to select in Webflow's token form: ``` CMS → Read and write (✓) Assets → Read and write (✓) Sites → Read only (✓) Everything else → No access (leave untouched) ``` 6. Click **Generate token** and **copy it immediately** — Webflow won't show it again. <Warning> Store the token securely. Siftly encrypts it at rest, but if you need to revoke access, delete the token from Webflow's API Access settings. </Warning> *** ## Step 2: Find your Site ID Your Webflow Site ID is a 24-character hex string found in **Site Settings → General → Site ID**. You can also copy it from the URL when you're in the Webflow Designer: ``` https://webflow.com/design/{YOUR_SITE_ID} ``` *** ## Step 3: Identify your collection's field slugs Webflow identifies each field by a **field slug** — a lowercase, hyphen-separated identifier. You'll need to know the slugs for the fields you want Siftly to populate. To find field slugs: 1. Open your Webflow site in the **Designer** 2. Click **CMS** in the left panel 3. Open your collection and click **Edit Fields** 4. Each field shows its slug below the display name (e.g. `post-body`, `summary`, `sitemap-indexed`) *** ## Step 4: Connect Webflow in Siftly 1. In Siftly, go to **Settings → Integrations → CMS** 2. Click **Connect** next to **Webflow** 3. Enter your **API token** and **Site ID**, then click **Validate & Continue** 4. Siftly will fetch your available CMS collections — select the one you want to publish to 5. Map your content fields (see Field Mapping below) 6. Optionally enter your **Blog Base URL** (e.g. `https://www.mysite.com/blog`) — used to construct the published post URL in Siftly 7. Click **Connect Webflow** *** ## Field Mapping Siftly uses a 3-tier field mapping system. Enter the Webflow **field slug** for each field you want to populate. ### Required Fields These fields must be mapped to publish content. | Siftly Field | Maps To | Description | | ------------ | ------------- | --------------------------------------------------------------------- | | **Title** | `title_field` | The post title. Webflow's built-in `name` field is used by default. | | **Slug** | `slug_field` | The URL slug. Webflow's built-in `slug` field is used by default. | | **Body** | `body_field` | The full post body. Must be a **Rich Text** field in your collection. | <Tip> Webflow has built-in `name` and `slug` fields on every CMS item. These are handled automatically — you only need to map the body field and any optional fields you want. </Tip> ### Optional Fields Leave any of these blank to skip them. When mapped, they are auto-populated from your content data. | Siftly Field | Suggested Webflow Field Type | Example Slug | | -------------------- | ---------------------------- | -------------- | | **Meta Title** | Plain Text | `meta-title` | | **Meta Description** | Plain Text | `post-summary` | | **Keywords** | Plain Text (comma-separated) | `keywords` | | **Categories** | Plain Text (comma-separated) | `categories` | | **JSON-LD** | Plain Text (long) | `json-ld` | | **Word Count** | Number | `word-count` | <Tip> If your collection doesn't have fields for optional data yet, add them in **CMS → Collection → Add Field** before connecting. </Tip> *** ## Custom Fields Add extra fields your CMS collection 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. <Tip> Use the `value:label` format when your CMS expects specific IDs, slugs, or enum values that differ from the human-readable names shown to content editors. </Tip> ### 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 Instead of setting a manual default, you can link a custom field to an existing content field. For example, map your collection's `post-summary` field to use the same value as **Meta Description**. This is useful when your CMS has multiple fields that should contain the same data (e.g., `post-summary` and `meta-description` both using your meta description). *** ## Publishing ### Draft vs Published When publishing, choose between: * **Draft** — content is pushed to your Webflow collection as a draft CMS item * **Published** — the CMS item is created and immediately published to your live site ### Custom Fields at Publish Time If you've defined custom fields, they appear in the publish dialog pre-filled with their default values (or auto-filled from linked fields). You can edit them before publishing. Standard fields (title, slug, body, meta data, keywords, categories, JSON-LD) are auto-populated from your content — no manual input needed. *** ## Troubleshooting <AccordionGroup> <Accordion title="401 / Access denied — invalid token"> The API token is incorrect or has been revoked. Generate a new token in Webflow **Site Settings → Integrations → API Access** and reconnect in Siftly. </Accordion> <Accordion title="403 — Insufficient permissions"> Your token is missing the **CMS: Read and Write** scope. Delete the token in Webflow, create a new one with CMS + Sites read permissions, and reconnect. </Accordion> <Accordion title="Site not found (404)"> The Site ID is incorrect. Copy it from **Site Settings → General → Site ID** — it's a 24-character hex string, not your site's domain or display name. </Accordion> <Accordion title="No collections appear in the dropdown"> Your site has no CMS collections, or the token lacks CMS read access. Create a collection in Webflow's Designer first, then validate again in Siftly. </Accordion> <Accordion title="Item created but body field is empty"> The body field slug you entered doesn't match the actual slug in Webflow. Open your collection in **CMS → Edit Fields** and copy the exact slug shown under the field name. </Accordion> <Accordion title="Item created but not published live"> Siftly creates items with `isDraft: false` and then calls the publish endpoint when you select **Published** status. If the item appears in Webflow as a draft, check that your token has CMS **Write** (not just Read) access. </Accordion> </AccordionGroup> *** ## Where to apply Siftly's recommendations on Webflow Webflow has two layers for SEO: **Page-level SEO settings** and **CMS Collection fields**. Here's where each Siftly recommendation goes. ### Meta Title **For CMS collection pages (blog posts):** Webflow auto-generates the `<title>` tag from a CMS field you bind in **Page Settings → SEO Settings → Title Tag**. Create a plain text field in your collection (e.g., `meta-title`) and bind it: 1. Open your CMS template page in the Designer 2. Click the gear icon → **SEO Settings** 3. In the **Title Tag** field, click the purple "+" icon and select your `meta-title` CMS field Siftly pushes the meta title value to this field on publish. **For static pages:** Page Settings → **SEO Settings → Title Tag**. Enter Siftly's recommendation manually. ### Meta Description **For CMS collection pages:** Same flow as meta title — bind a CMS field (e.g., `post-summary`) to **SEO Settings → Meta Description**: 1. CMS template page → gear icon → **SEO Settings** 2. In the **Meta Description** field, bind your `post-summary` CMS field Siftly maps its meta description to this field automatically. **For static pages:** Page Settings → **SEO Settings → Meta Description**. ### Open Graph Image / Social Share Image **For CMS collection pages:** Webflow has a dedicated **Open Graph Image** binding: 1. CMS template page → gear icon → **Open Graph Settings** 2. Bind a CMS **Image** field to the **OG Image** slot <Note> Siftly uploads hero images and inline content images to Webflow Assets automatically at publish time. Map the **Hero Image** field to your collection's image field and Siftly will upload and set the Webflow CDN URL. </Note> **For static pages:** Page Settings → **Open Graph Settings → OG Image**. Upload directly. ### Canonical URL Webflow auto-generates canonical URLs for all pages. No action needed for standard content published through Siftly. To override: Page Settings → **SEO Settings → Canonical URL**. This is rarely needed for original content. ### Tags & Categories Webflow doesn't have a native tag/category taxonomy. Instead, use: * A **Plain Text** field with comma-separated values (e.g., `keywords` field) * A **Reference** or **Multi-reference** field linking to a separate "Categories" collection Siftly pushes keywords and categories as comma-separated strings to plain text fields. For multi-reference fields, you'd need to create the referenced items in Webflow first. ### JSON-LD Structured Data Webflow does NOT auto-generate JSON-LD. You must add it manually. **For static pages:** Page Settings → **Custom Code → Head Code**. Paste the full `<script type="application/ld+json">` block. **For CMS collection pages (dynamic JSON-LD):** Use Webflow's embed element with CMS field bindings: 1. Add an **Embed** element to your CMS template page (inside the `<head>` via custom code, or at the bottom of the body) 2. Use Webflow's dynamic field syntax to inject CMS data: ```html theme={null} <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "headline": "{{wf {"path":"name","type":"PlainText"} }}", "description": "{{wf {"path":"post-summary","type":"PlainText"} }}", "datePublished": "{{wf {"path":"created-on","type":"PlainText"} }}", "author": { "@type": "Person", "name": "{{wf {"path":"author-name","type":"PlainText"} }}" } } </script> ``` <Warning> The `{{wf {...} }}` template syntax only works inside **Embed** elements on CMS template pages. It does NOT work in Page Settings → Custom Code. If you need per-page dynamic JSON-LD, you MUST use an Embed element in the page body. </Warning> **Alternative — Store full JSON-LD in a CMS field:** Create a `json-ld` plain text (long) field in your collection. Map Siftly's JSON-LD output to this field. Then add an Embed element that outputs it: ```html theme={null} <script type="application/ld+json"> {{wf {"path":"json-ld","type":"PlainText"} }} </script> ``` This lets Siftly push fully-formed JSON-LD that renders dynamically per post. ### Keywords Webflow does not render a `<meta name="keywords">` tag by default. If you want one: 1. Add an Embed element in your CMS template page's `<head>` section (via custom code): ```html theme={null} <meta name="keywords" content="{{wf {"path":"keywords","type":"PlainText"} }}"> ``` For most use cases, keywords stored as tags in a CMS field are sufficient for AI crawlers that parse page content. *** ## Pushing Siftly recommendations automatically <Steps> <Step title="Generate content in Siftly"> Siftly produces your article plus meta title, meta description, keywords, categories, and JSON-LD. </Step> <Step title="Click Publish → Webflow"> Select your Webflow collection. Choose Draft or Published status. </Step> <Step title="Fields pushed via API"> All mapped fields (title, slug, body, meta title, meta description, keywords, categories, JSON-LD, word count) are sent in a single API call. CMS item is created with all data populated. </Step> <Step title="Publish the site (if needed)"> Webflow CMS items are live immediately if you chose Published. If your site has unpublished changes in the Designer, you may need to click **Publish** in Webflow to push the latest template changes. </Step> </Steps> *** ## Platform-specific quirks & limitations <Warning> **Dynamic JSON-LD requires Embed elements.** Webflow's Page Settings → Custom Code does not support CMS field bindings (`{{wf ...}}`). For per-post JSON-LD, you MUST use an Embed element in the template page body. </Warning> <Note> **CMS item limits:** Webflow's CMS plans have item limits (e.g., 2,000 items on the Basic plan, 10,000 on Business). Check your plan's CMS item quota before bulk-publishing from Siftly. </Note> * **Publishing delay:** After creating a CMS item via API, it may take a few seconds for Webflow's CDN to reflect the change. New items are usually live within 30 seconds. * **Rich Text field quirks:** Webflow's Rich Text fields support a subset of HTML. Unsupported tags (e.g., `<table>`, `<iframe>`) are stripped. If Siftly generates tables, they'll be removed by Webflow. * **No API access to Page Settings SEO:** The Webflow Data API writes to CMS collection fields only — it cannot modify Page Settings (title tag bindings, meta description bindings). These bindings must be configured once in the Designer manually. * **Staging vs Production:** Webflow's staging environment shows unpublished items. Published items go live on your production domain immediately via API. *** ## Validating the setup After publishing your first CMS item from Siftly: <Steps> <Step title="View the live page source"> Open your published Webflow page in a browser. Right-click → **View Page Source**. Search for: * `<title>` — should contain your bound meta title CMS field value * `<meta name="description"` — should contain your meta description * `<script type="application/ld+json">` — should contain your JSON-LD (if using Embed element) </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your page URL. Confirm JSON-LD is detected and valid. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) and paste your URL. Check for errors. </Step> <Step title="Check CMS field bindings"> In the Webflow Designer, preview your CMS template page with a test item selected. Verify all bound fields (title, description, JSON-LD embed) render correctly. </Step> </Steps> *** ## Difficulty & setup recap <Card title="Webflow Setup Summary" icon="code"> | Aspect | Rating | | ----------------------- | --------------------------------------------------------------------------------- | | **Initial setup** | ⚠️ Medium — API token + field slug identification | | **Applying SEO fields** | ✅ Easy for meta title/description (CMS field bindings) | | **JSON-LD** | ⚠️ Requires Embed element with `{{wf ...}}` syntax or stored JSON-LD field | | **Ongoing editing** | ✅ Easy — publish from Siftly, items appear in Webflow CMS | | **Developer needed?** | For initial template setup (field bindings, Embed elements) — not for ongoing use | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> # Wix Integration Source: https://docs.siftly.ai/integrations/wix Publish GEO-optimized content from Siftly directly to your Wix blog or Wix Headless CMS using the Wix Content Manager API. <Frame> <img alt="Supported CMS platforms including Wix" /> </Frame> ## Overview This guide is for Wix users who want to publish Siftly-generated content and apply GEO/SEO recommendations. After following it, you'll know how to connect Siftly to Wix, where to find SEO fields in the Wix dashboard, and the limitations of Wix's platform for structured data. **Difficulty:** ✅ Non-tech friendly — Wix has a visual SEO panel. ⚠️ JSON-LD requires a paid plan. Wix is one of the world's most popular website builders, with millions of sites built on its platform. The Siftly–Wix integration uses the **Wix Content Manager API** (part of the Wix Headless platform) to create blog posts and CMS collection items directly from Siftly's content editor. <Note> Wix uses **fixed API fields** — no schema mapping is needed. Fields are pre-configured to match Wix's Blog API structure. This is different from other CMS integrations that use the 3-tier field mapping system. </Note> *** ## Prerequisites Before connecting, you'll need: * A Wix site with a **Blog** or a **CMS Collection** set up * A **Wix API key** with the necessary permissions (see below) * Your Wix **Site ID** <Note> The Wix integration requires your site to be on a **Wix Premium** plan. The Content Manager API is not available on free Wix sites. </Note> *** ## Step 1: Get your Wix API key Wix uses API keys to authenticate third-party integrations. 1. Log in to [manage.wix.com](https://manage.wix.com) 2. Select your site 3. Go to **Settings → Advanced → API Keys** 4. Click **Generate API Key** 5. Give it a name (e.g., "Siftly") 6. Under **Permissions**, enable: * **Wix Blog** → Read & Write * **Wix Media** → Read & Write (required for hero image and content image uploads) * **Wix Content Manager** → Read & Write (if using CMS Collections) 7. Click **Generate** and copy the API key ### Get your Site ID Your Site ID is in the URL when you're in the Wix dashboard: `https://manage.wix.com/dashboard/{YOUR_SITE_ID}/...` Copy the UUID string between `/dashboard/` and the next `/`. *** ## Step 2: Connect Wix in Siftly 1. In Siftly, go to **Settings → Integrations** 2. Click **Connect** next to **Wix** 3. Enter your: * API Key * Site ID 4. Click **Verify Connection** Siftly will verify your credentials and detect whether your site has a Blog and/or CMS Collections. *** ## Step 3: Choose your publish target Wix offers two content targets: ### Wix Blog Publish content as a **blog post** on your Wix blog. This is the simplest option — Siftly maps directly to Wix Blog fields. ### Wix CMS Collection Publish content to a custom **CMS Collection** (e.g., a "Resources" or "Case Studies" collection). You'll need to map Siftly's fields to your collection's fields. Select your preferred target in **Settings → Integrations → Wix → Configure**. *** ## Field Mapping (Fixed Fields) Wix uses a fixed API structure — fields are pre-configured and do not require manual schema mapping. Siftly maps content to Wix's built-in fields automatically. ### Pre-configured Fields | Siftly Field | Wix Blog Field | Notes | | -------------------- | --------------------------- | ------------------------------------------------------------ | | **Title** | Post title | Required — always sent | | **Slug** | Custom URL slug | Required — always sent | | **Body** | Post content (Ricos format) | Required — HTML is converted to Wix's Ricos rich-text format | | **Meta Description** | Excerpt | Auto-populated from content | | **Keywords** | Hashtags | Auto-populated from content keywords | <Note> Unlike other CMS integrations, Wix does not use the 3-tier field mapping system. The fields above are fixed by Wix's Blog API and cannot be remapped. </Note> *** ## Custom Fields You can define custom fields in Siftly for your Wix integration. These fields are stored locally and appear in the publish dialog for your reference, but they are **not sent to the Wix API** due to API limitations. <Warning> Wix's Blog API does not support arbitrary custom fields on blog posts. Custom fields you define in Siftly are saved locally for tracking purposes only. To add custom data to your Wix posts, use Wix's CMS Collection approach instead or edit posts directly in the Wix dashboard after publishing. </Warning> ### Field Types (local only) | 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. *** ## Publishing ### Draft vs Published When publishing to Wix, content is always created as a **draft** in the Wix dashboard. You'll need to open the Wix blog editor to review and publish it to your live site. <Note> Wix's Blog API creates posts as drafts regardless of the status you select in Siftly. This is a Wix API limitation. Open your Wix dashboard to publish the draft post. </Note> ### Standard Fields at Publish Time Standard fields (title, slug, body, excerpt, hashtags) are auto-populated from your content — no manual input needed. *** ## Rich text in Wix Wix Blog accepts rich text via its own editor format (Ricos). Siftly converts generated content to Wix-compatible format, preserving: * Headings (H1-H4) * Bold and italic formatting * Ordered and unordered lists * Hyperlinks (including Siftly-generated internal links) * Blockquotes <Tip> After publishing, open the post in Wix's blog editor to add a **cover image** and review the formatting. Images are not auto-generated — you'll need to upload or select a featured image manually. </Tip> *** ## SEO fields in Wix Siftly populates Wix's built-in SEO fields when publishing: * **Page title** — Mapped from Siftly's generated title * **Meta description** — Mapped from Siftly's meta description * **Slug** — Custom URL path These are set in Wix's **SEO Settings** panel for the post. Verify them after publishing to ensure they look correct. *** ## Troubleshooting <AccordionGroup> <Accordion title="API key rejected (401 error)"> Regenerate the API key in Wix **Settings → API Keys** and update it in Siftly. Make sure the key has **Blog Write** and/or **CMS Write** permissions enabled. </Accordion> <Accordion title="Site ID not found"> Copy the Site ID from the URL in Wix manage. It should be a UUID format like `a1b2c3d4-e5f6-...`. Do not use your site's display name or domain. </Accordion> <Accordion title="Post is created but body is empty"> This can happen if Wix rejects unsupported HTML tags during Ricos conversion. Check the Siftly publish log for any warnings. Try removing custom formatting from the content draft and republishing. </Accordion> <Accordion title="CMS collection doesn't appear in the dropdown"> Make sure your API key has **Wix Content Manager** write permissions enabled. Only collections with at least one text field will appear in Siftly's collection list. </Accordion> <Accordion title="Publish succeeds but post doesn't appear on the site"> Siftly creates posts as drafts in Wix. Go to your Wix blog dashboard → **Posts → Drafts** and click **Publish** to make it live. </Accordion> </AccordionGroup> *** ## Wix Headless (advanced) If you're using **Wix Headless** to power a custom frontend (Next.js, Nuxt, etc.) with Wix as the backend CMS, the integration works identically — content is created in your Wix Content Manager and consumed by your frontend via the Wix SDK. No additional configuration is needed in Siftly. Your frontend will pick up new content the next time it fetches from Wix's Content Manager API. *** ## Where to apply Siftly's recommendations on Wix Wix has a built-in **SEO panel** for each page and blog post. Here's where each field lives and how to apply Siftly's values. ### Meta Title **Location:** Blog post editor → click **SEO** (left sidebar) → **Basics → SEO Title** Wix renders this as the `<title>` tag. If left empty, Wix uses the post title. Siftly pushes the post title via the API, which Wix uses as the default SEO title. To use a different meta title, edit it in the Wix SEO panel after publishing. ### Meta Description **Location:** Blog post editor → **SEO → Basics → SEO Description** Wix renders this as `<meta name="description">`. Siftly maps its meta description to the post excerpt, which Wix often uses as the default SEO description. After publishing from Siftly, open the post in Wix and verify the SEO Description matches Siftly's recommendation. ### Open Graph Image / Social Share Image **Location:** Blog post editor → **SEO → Social Share** Wix auto-generates OG tags using the post's cover image and title. To override: 1. Open the post in Wix blog editor 2. Click **SEO → Social Share** 3. Upload a custom image for Facebook/Twitter sharing <Tip> Set a **cover image** on your Wix blog post — Wix uses it as the default OG image. Upload it in the post editor header area. </Tip> ### Canonical URL **Location:** Blog post editor → **SEO → Advanced → Canonical URL** Wix auto-generates canonical URLs. Override only for syndicated content. <Note> Siftly does not push canonical URL overrides to Wix. The default permalink is correct for original content. </Note> ### Tags & Categories **Location:** Blog post editor → **Categories** and **Tags** panels in the right sidebar. Siftly pushes keywords as Wix **Hashtags** automatically. After publishing, you can add Wix-native categories in the post editor. ### JSON-LD Structured Data Wix auto-generates basic structured data (Article schema) for blog posts. For supplemental schema (FAQ, HowTo, Product): **Location:** Blog post editor → **SEO → Advanced → Additional structured data markup** (or **Structured Data** section) <Warning> Custom JSON-LD / structured data markup requires a **Wix Premium plan** (Business or higher). Free plans do not expose the Advanced SEO settings. </Warning> To add Siftly's JSON-LD recommendation: 1. Open the post in Wix blog editor 2. Click **SEO → Advanced** 3. In the **Structured Data** section, paste Siftly's JSON-LD: ```json theme={null} { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "What is generative engine optimization?", "acceptedAnswer": { "@type": "Answer", "text": "GEO is the practice of optimizing content to be cited by AI-powered search engines." } } ] } ``` <Note> Wix expects raw JSON (no `<script>` tags) in the Structured Data field. It wraps it in the `<script type="application/ld+json">` tag automatically. </Note> ### Keywords Wix does not render a `<meta name="keywords">` tag. Keywords are handled through the Hashtags system, which appears in the post URL and helps with Wix's internal search. *** ## Pushing Siftly recommendations automatically <Steps> <Step title="Generate content in Siftly"> Siftly produces your article plus meta title, meta description, keywords, and JSON-LD. </Step> <Step title="Click Publish → Wix"> Content is created as a draft in your Wix blog. </Step> <Step title="Fields auto-populated"> Title, slug, body, excerpt (meta description), and hashtags (keywords) are pushed automatically. </Step> <Step title="Apply remaining fields manually in Wix"> Open the draft in Wix blog editor. Apply Siftly's JSON-LD in **SEO → Advanced → Structured Data**. Upload a cover image. Review the SEO title. Then click **Publish** in Wix. </Step> </Steps> *** ## Platform-specific quirks & limitations <Warning> **All posts are created as drafts.** Wix's Blog API creates posts in draft status regardless of what you select in Siftly. You MUST open Wix to publish the post live. </Warning> <Warning> **Structured Data requires paid plan.** The Advanced SEO panel (including custom JSON-LD) is only available on Wix Business plans and higher. Free and basic plans cannot add custom structured data. </Warning> <Note> **No API access to SEO fields.** Wix's Blog API does not accept meta title, meta description, or JSON-LD values directly. These must be set manually in the Wix editor after Siftly creates the draft. </Note> * **Custom fields not supported:** Wix's Blog API has a fixed schema. Custom CMS fields defined in Siftly are stored locally for reference only — they are not sent to Wix. * **Ricos format:** Wix uses its own rich text format (Ricos). Siftly converts HTML to Ricos automatically, but complex HTML (tables, iframes) may be stripped. * **Cover image:** Must be uploaded manually in Wix after publishing from Siftly. * **SEO auto-generation:** Wix generates basic Article schema automatically. Do NOT duplicate Article schema in the Structured Data field. * **Multilingual:** Wix Multilingual sites require separate posts per language. Siftly publishes to the default language only. *** ## Validating the setup After publishing from Siftly and making the post live in Wix: <Steps> <Step title="View the live page source"> Open your published Wix post in a browser. Right-click → **View Page Source**. Search for: * `<title>` — should contain your SEO title * `<meta name="description"` — should contain your meta description * `<script type="application/ld+json">` — should show Wix's auto-generated schema plus any custom schema you added </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your post URL. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) for additional validation. </Step> <Step title="Check Wix SEO panel"> In Wix editor, open the post → **SEO** panel. Verify the title, description, and structured data are all populated correctly. </Step> </Steps> *** ## Difficulty & setup recap <Card title="Wix Setup Summary" icon="w"> | Aspect | Rating | | ----------------------- | ----------------------------------------------------------- | | **Initial setup** | ✅ Easy — API key generation, no code | | **Applying SEO fields** | ✅ Easy — visual SEO panel in post editor | | **JSON-LD** | ⚠️ Requires paid plan; must be added manually after publish | | **Ongoing editing** | ⚠️ Posts created as drafts — requires manual publish in Wix | | **Developer needed?** | No | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> # WordPress Integration Source: https://docs.siftly.ai/integrations/wordpress Connect Siftly to WordPress.com or a self-hosted WordPress.org site and publish GEO-optimized content directly as blog posts. <Frame> <img alt="Supported CMS platforms including WordPress" /> </Frame> ## Overview This guide is for WordPress users who want to publish Siftly-generated GEO content and apply Siftly's SEO/GEO recommendations directly from their dashboard. After following it, you'll be able to push optimized content to WordPress and ensure all meta fields, structured data, and tags are correctly applied. **Difficulty:** ✅ Non-tech friendly — no coding required for basic setup. Siftly supports two WordPress connection methods so you can publish regardless of how your site is hosted: | Connection type | Who it's for | Auth method | | ------------------------------- | ---------------------------------------------- | ------------------------------- | | **WordPress.com** | Sites hosted at wordpress.com or using Jetpack | OAuth2 — no passwords needed | | **Self-hosted (WordPress.org)** | Your own server running WordPress | Application Passwords (WP 5.6+) | Once connected, you can publish Siftly-generated content to WordPress with a single click from the content editor. *** ## Which connection type do I need? **Use WordPress.com if:** * Your site URL ends in `.wordpress.com`, or * You use Jetpack to connect a self-hosted site to WordPress.com's infrastructure **Use Self-hosted (WordPress.org) if:** * You installed WordPress on your own server or a managed host (e.g., WP Engine, Kinsta, Flywheel, SiteGround), or * Your site URL is a custom domain and you manage your own hosting <Tip> Not sure which you have? Log in to your WordPress dashboard. If the URL is `wordpress.com/home/yoursite`, you're on WordPress.com. If it's `yoursite.com/wp-admin`, you're self-hosted. </Tip> *** ## Connecting WordPress.com (OAuth2) ### Prerequisites * A **WordPress.com** account * A WordPress.com site with a blog enabled (free and paid plans are both supported) ### Step 1: Start the OAuth connection Siftly uses WordPress.com's official OAuth2 flow — you never share your password with Siftly. 1. In Siftly, go to **Settings → Integrations** 2. Click **Connect** next to **WordPress** 3. On the type selection screen, click **Connect WordPress.com** 4. You'll be redirected to **WordPress.com** to authorize access 5. Log in with your WordPress.com credentials if prompted 6. Click **Approve** to grant Siftly permission to publish posts on your behalf WordPress.com redirects you back to Siftly automatically once authorized. <Tip> The authorization grants Siftly **post write** and **media upload** access — it can create posts and upload images to your media library. It cannot read your private data, change your account settings, or access other sites on your WordPress.com account. </Tip> ### Step 2: Verify the connection After authorizing, Siftly displays your connected site URL. If you see an error instead, see [Troubleshooting](#troubleshooting). *** ## Connecting a Self-hosted Site (WordPress.org) Self-hosted WordPress sites use **Application Passwords** — a built-in WordPress feature since version 5.6 that lets you grant API access without sharing your main account password. ### Prerequisites Before connecting, make sure your site meets these requirements: <Steps> <Step title="WordPress 5.6 or later"> Application Passwords are built into WordPress 5.6+. Check **Dashboard → Updates** to confirm your version. Most managed hosts keep WordPress updated automatically. </Step> <Step title="Pretty permalinks enabled"> The WordPress REST API requires pretty permalinks (any setting except **Plain**). Go to **Settings → Permalinks** and select any option other than **Plain** (e.g., **Post name** is recommended). Click **Save Changes**. <Warning> If permalinks are set to **Plain**, the REST API routes are not registered and Siftly will not be able to connect or publish — you'll see a "REST API not found" error. </Warning> </Step> <Step title="Generate an Application Password"> 1. Log in to your WordPress admin panel 2. Go to **Users → Your Profile** (or **Users → All Users → Edit** for another user) 3. Scroll down to the **Application Passwords** section 4. Enter a name for the password (e.g., `Siftly`) 5. Click **Add New Application Password** 6. **Copy the generated password immediately** — it is shown only once <Warning> Application Passwords look like `xxxx xxxx xxxx xxxx xxxx xxxx` (24 characters with spaces). Copy it exactly as shown — spaces are part of the password and must be included. </Warning> </Step> <Step title="HTTPS enabled (strongly recommended)"> Application Passwords send credentials over HTTP Basic Auth. Without HTTPS, credentials are transmitted in plain text. Most managed WordPress hosts include SSL by default. You can verify by checking that your site loads at `https://`. <Note> On some WordPress configurations, Application Passwords are disabled when HTTPS is not detected. If you don't see the **Application Passwords** section in your profile, this may be the cause. </Note> </Step> </Steps> ### Step 1: Connect in Siftly 1. In Siftly, go to **Settings → Integrations** 2. Click **Connect** next to **WordPress** 3. On the type selection screen, click **Connect Self-hosted** 4. Fill in the three fields: | Field | What to enter | | ------------------------ | ---------------------------------------------------------------- | | **Site URL** | The root URL of your WordPress site, e.g. `https://yoursite.com` | | **Username** | Your WordPress admin username (not your email address) | | **Application Password** | The password generated in your profile (spaces included) | 5. Click **Connect Site** Siftly validates your credentials immediately by calling your site's REST API. If validation succeeds, you'll see the connected confirmation with your site URL. ### Step 2: Verify the connection After connecting, Siftly displays your site URL and username. If you see an error, check the [Troubleshooting](#troubleshooting) section. *** ## Field Mapping WordPress uses the unified 3-tier field mapping system. WordPress post fields have fixed API names, so required fields are pre-configured. ### Required Fields | Siftly Field | WordPress Post Field | Notes | | ------------ | -------------------- | ------------------------------------- | | **Title** | `title` | Pre-configured — WordPress post title | | **Slug** | `slug` | Pre-configured — custom URL slug | | **Body** | `content` | Pre-configured — post content (HTML) | ### Optional Fields When mapped, these are auto-populated from your content data. | Siftly Field | WordPress Post Field | Notes | | -------------------- | -------------------- | ------------------------------------------------------------------ | | **Meta Title** | — | Not natively supported by WordPress REST API (requires SEO plugin) | | **Meta Description** | `excerpt` | Mapped to WordPress post excerpt | | **Keywords** | `tags` | Mapped to WordPress tags (created if they don't exist) | | **Categories** | `categories` | Mapped to WordPress categories | | **JSON-LD** | — | Not natively supported by WordPress REST API | | **Word Count** | — | Not natively supported by WordPress REST API | <Note> WordPress's REST API has limited support for SEO-specific fields like meta title and JSON-LD. If you use an SEO plugin (Yoast, Rank Math, etc.), those fields may be available through the plugin's API extensions. </Note> *** ## Custom Fields Add extra fields your WordPress posts require that aren't part of Siftly's standard content schema. Custom fields are sent as WordPress post meta. ### 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): ``` value:label ``` **Example — Labels differ from values:** ``` 1:Health 2:Tech 3:Food 4:Fashion ``` The dropdown shows `Health`, `Tech`, etc., but Siftly sends `1`, `2`, etc. to the CMS API. **Example — Labels same as values:** ``` food tech health fashion ``` When no `:` is present, the option text is used as both the label and value. This is backward-compatible with existing configurations. <Tip> Use the `value:label` format when your CMS expects specific IDs, slugs, or enum values that differ from the human-readable names shown to content editors. </Tip> ### 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 Instead of setting a manual default, you can link a custom field to an existing content field. For example, map a custom WordPress meta field to use the same value as **Meta Description**. This is useful when your WordPress setup has multiple fields that should contain the same data (e.g., a Yoast `_yoast_wpseo_metadesc` field and the post excerpt both using your meta description). *** ## Publishing ### Draft vs Published When publishing, choose between: * **Draft** — content is pushed to WordPress as a draft post for review in the WordPress editor * **Published** — the post is created and immediately published to your live site ### Custom Fields at Publish Time If you've defined custom fields, they appear in the publish dialog pre-filled with their default values (or auto-filled from linked fields). You can edit them before publishing. Standard fields (title, slug, body, excerpt, tags, categories) are auto-populated from your content — no manual input needed. *** ## Rich text and formatting Siftly publishes content as **HTML**. Standard formatting is preserved: * Headings (H1-H4) * Bold and italic text * Ordered and unordered lists * Hyperlinks (including internal links generated by Siftly) * Blockquotes Both the WordPress Block Editor (Gutenberg) and the Classic Editor render the HTML correctly. <Tip> Siftly uploads the hero image and all inline content images to your WordPress media library automatically at publish time. The hero image is set as the post's **featured image** when the field is mapped. No manual image uploads needed. </Tip> *** ## Where to apply Siftly's recommendations on WordPress Siftly generates recommendations for SEO/GEO fields alongside your content. Here's where each field lives in WordPress and how to apply Siftly's values. ### Meta Title WordPress doesn't have a native meta title field — it uses the post title as the page title by default. **With Yoast SEO:** Go to the post editor → scroll to the **Yoast SEO** panel → **SEO title** field. Paste Siftly's recommended meta title here. **With Rank Math:** Go to the post editor → click the **Rank Math** icon in the top bar → **Edit Snippet → SEO Title**. Paste Siftly's recommendation. **Without an SEO plugin:** The `<title>` tag defaults to your post title. To override it, you'd need a custom `wp_head` hook — we recommend using Yoast or Rank Math instead. ### Meta Description **With Yoast SEO:** Post editor → **Yoast SEO panel → Meta description** field. Paste Siftly's recommended description. **With Rank Math:** Post editor → **Rank Math → Edit Snippet → Description**. Paste Siftly's recommendation. **Without an SEO plugin:** WordPress has no native meta description. The post excerpt is used by some themes as a fallback. We recommend Yoast or Rank Math for proper meta description control. <Tip> Siftly auto-populates the WordPress `excerpt` field on publish using your content's meta description. For Yoast/Rank Math fields, you'll need to edit them directly in WordPress after publishing — the WordPress REST API does not expose SEO plugin fields natively. </Tip> ### Open Graph Image / Social Share Image **With Yoast SEO:** Post editor → **Yoast SEO → Social tab → Facebook image / Twitter image**. Upload or paste the URL of the image Siftly recommends. **With Rank Math:** Post editor → **Rank Math → Social tab → Facebook Thumbnail / Twitter Thumbnail**. **Without an SEO plugin:** WordPress uses the Featured Image as the Open Graph image in most themes. Set your Featured Image and most social platforms will pick it up. ### Canonical URL WordPress auto-generates canonical URLs for each post. Both Yoast and Rank Math add `<link rel="canonical">` automatically. To override (e.g., for syndicated content): * **Yoast:** Post editor → Yoast → **Advanced → Canonical URL** * **Rank Math:** Post editor → Rank Math → **Advanced → Canonical URL** <Note> Siftly does not currently push canonical URL overrides. The default WordPress canonical (your post's permalink) is correct for original content published through Siftly. </Note> ### Tags & Categories Siftly maps keywords to WordPress **Tags** and categories to WordPress **Categories** automatically during publish. These are set in the standard WordPress post sidebar panels. Tags created by Siftly that don't already exist in WordPress are created automatically. Categories must exist beforehand — if a category name doesn't match an existing WordPress category, it's skipped. ### JSON-LD Structured Data WordPress doesn't have native JSON-LD support. Here's how to add it: **With Yoast SEO (automatic):** Yoast auto-generates Article schema, Organization schema, and BreadcrumbList schema. Siftly's JSON-LD recommendation can supplement this with FAQ, HowTo, or other specialized schemas. To add Siftly's JSON-LD alongside Yoast's auto-generated schema, install the **Custom HTML** block in your post and paste: ```html theme={null} <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "Your question here", "acceptedAnswer": { "@type": "Answer", "text": "Your answer here" } } ] } </script> ``` **With Rank Math:** Rank Math has a built-in **Schema** tab in the post editor. Click **Schema Generator** to add FAQ, HowTo, Article, or custom schema types. Paste values from Siftly's JSON-LD recommendation into the relevant fields. **Without an SEO plugin:** Add a **Custom HTML** block at the bottom of your post with the full `<script type="application/ld+json">` tag. <Warning> If you use Yoast or Rank Math, do NOT duplicate the Article schema they already generate. Siftly's JSON-LD recommendations are designed to supplement (FAQ, HowTo, Product) — not replace — your plugin's base schema. </Warning> ### Keywords The HTML `<meta name="keywords">` tag is deprecated by Google but still parsed by some AI engines and internal search systems. * **Yoast SEO:** Does not support meta keywords (removed in 2018). * **Rank Math:** Post editor → Rank Math → **Focus Keyword** field. This is used for on-page optimization guidance, not rendered as a meta tag. * **For AI parsers:** If you want a keywords meta tag rendered in `<head>`, use a plugin like **Add Meta Tags** or add a custom field that your theme renders. Siftly maps keywords to WordPress Tags by default, which is sufficient for content organization and many AI crawlers. *** ## Pushing Siftly recommendations automatically Siftly pushes content to WordPress in a single publish action. However, WordPress's REST API has limited SEO field support — here's what's automated and what's manual: **Pushed automatically on publish:** * Title * Slug * Body (full HTML content with images hosted in WordPress media library) * Excerpt (from Siftly's meta description) * Hero image → set as featured image (uploaded to WordPress media library) * All inline content images (uploaded to WordPress media library) **Must be applied manually after publishing:** * Meta title (via Yoast/Rank Math in WordPress editor) * Meta description (via Yoast/Rank Math — the excerpt is pushed but the SEO plugin field is separate) * JSON-LD structured data (via Custom HTML block or SEO plugin schema) * Tags and categories (not currently pushed via API) <Steps> <Step title="Generate content in Siftly"> Use Siftly's content editor to generate or optimize your article. Siftly produces meta title, meta description, keywords, and JSON-LD recommendations alongside the content. </Step> <Step title="Click Publish → WordPress"> In the content editor, click **Publish** and select **WordPress**. Choose Draft or Published status. </Step> <Step title="Content + excerpt pushed automatically"> Siftly sends title, slug, body (HTML), and excerpt in a single API call to WordPress. </Step> <Step title="Apply SEO fields manually in WordPress"> Open the post in WordPress editor. Copy Siftly's recommendations for meta title, meta description, and JSON-LD into your SEO plugin (Yoast/Rank Math). Add tags and a featured image. </Step> </Steps> <Note> WordPress's REST API does not expose Yoast or Rank Math SEO fields. These must be set directly in the WordPress post editor after publishing from Siftly. </Note> *** ## Platform-specific quirks & limitations <Warning> **REST API limitations:** WordPress's REST API does not expose Yoast SEO or Rank Math fields. Siftly can push title, slug, body, and excerpt — but meta title, meta description (the SEO plugin field), JSON-LD, and tags must be applied manually in the WordPress editor after publishing. </Warning> <Note> **Excerpt vs Meta Description:** Siftly pushes your meta description as the WordPress `excerpt`. Some themes use the excerpt as the meta description fallback, but Yoast/Rank Math use their own separate field. After publishing, copy the excerpt into your SEO plugin's description field if they don't auto-sync. </Note> * **Block Editor vs Classic Editor:** Siftly's HTML content works in both editors. The Block Editor wraps it in a single Classic block. No action needed. * **Multisite:** Siftly connects to one site at a time. For WordPress Multisite, connect each subsite separately. * **Caching plugins:** After publishing, if your site uses WP Super Cache, W3 Total Cache, or a CDN, the new post may not appear immediately. Purge cache or wait for TTL expiry. * **Security plugins:** Wordfence and iThemes Security can block REST API access. Whitelist Siftly's server IP or ensure the REST API is not disabled. *** ## Validating the setup After publishing your first post with Siftly's recommendations applied: <Steps> <Step title="View the live page source"> Open your published post in a browser. Right-click → **View Page Source**. Search for: * `<title>` — should contain your Siftly meta title * `<meta name="description"` — should contain your Siftly meta description * `<script type="application/ld+json">` — should contain your JSON-LD </Step> <Step title="Run Google Rich Results Test"> Go to [Google Rich Results Test](https://search.google.com/test/rich-results) and paste your post URL. Confirm your JSON-LD is detected and valid. </Step> <Step title="Run Schema.org Validator"> Go to [Schema.org Validator](https://validator.schema.org/) and paste your post URL. Check for errors or warnings in your structured data. </Step> <Step title="Check Open Graph tags"> Use [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/) or [Twitter Card Validator](https://cards-dev.twitter.com/validator) to confirm OG image, title, and description are rendering correctly. </Step> </Steps> *** ## Difficulty & setup recap <Card title="WordPress Setup Summary" icon="wordpress"> | Aspect | Rating | | ----------------------- | ----------------------------------------------------- | | **Initial setup** | ✅ Easy — OAuth or Application Password, no code | | **Applying SEO fields** | ✅ Easy with Yoast/Rank Math, manual without | | **JSON-LD** | ⚠️ Requires SEO plugin or custom theme code | | **Ongoing editing** | ✅ Easy — publish from Siftly, edit in WordPress | | **Developer needed?** | No (unless you want automated JSON-LD via theme hook) | </Card> *** ## Related <CardGroup> <Card title="CMS Integrations Overview" icon="grid-2" href="/integrations/overview"> Compare all supported platforms and the unified field mapping system. </Card> <Card title="Quickstart Guide" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Content Generation" icon="file-pen" href="/features/content-generation"> How Siftly generates GEO-optimized content and recommendations. </Card> <Card title="Choosing a CMS for AI Visibility" icon="book" href="https://siftly.ai/blog/cms-and-ai-visibility"> Our guide to picking the right CMS for GEO optimization. </Card> </CardGroup> *** ## Reconnecting or switching sites **WordPress.com:** OAuth tokens can expire or be revoked (e.g., if you change your password). To reconnect, go to **Settings → Integrations → WordPress**, click **Disconnect**, then click **Connect** again to restart the OAuth flow. **Self-hosted:** Application Passwords remain valid until you delete them in WordPress. If credentials change (e.g., you regenerated the password), disconnect and reconnect using the new password. Each reconnect replaces the stored credential with the new one. You can also use this to switch to a different site. *** ## Disconnecting WordPress 1. Go to **Settings → Integrations** 2. Click **Disconnect** next to **WordPress** This permanently deletes your stored credentials from Siftly's database. It does not affect posts already published to WordPress. **For WordPress.com:** This does not revoke Siftly's app authorization on the WordPress.com side. To fully revoke access, go to [WordPress.com → Security → Connected Apps](https://wordpress.com/me/security/connected-applications) and remove **Siftly**. **For self-hosted:** To invalidate the Application Password entirely, go to **WordPress Admin → Users → Your Profile → Application Passwords** and delete the Siftly entry. *** ## Troubleshooting <AccordionGroup> <Accordion title="WordPress.com: I was redirected back with an error"> This happens if you clicked **Deny** on the WordPress.com authorization screen, or if the OAuth flow timed out (the authorization window is valid for 10 minutes). Go to **Settings → Integrations → WordPress** and click **Connect** again. </Accordion> <Accordion title="WordPress.com: Token invalid or expired (403 error when publishing)"> WordPress.com OAuth tokens are revoked when you change your account password or remove the app's access. Go to **Settings → Integrations → WordPress**, click **Disconnect**, then **Connect** again to get a fresh token. </Accordion> <Accordion title="Self-hosted: 'Basic Auth headers stripped' error (.htaccess fix)"> Some shared hosting environments (cPanel, Plesk, LiteSpeed) strip the HTTP `Authorization` header before it reaches WordPress, which means your Application Password is never actually checked — even though the REST API itself is reachable. Add the following lines to your `.htaccess` file inside the WordPress block, **before** the `RewriteRule . /index.php [L]` line: ```apache theme={null} RewriteCond %{HTTP:Authorization} ^(.*) [NC,OR] RewriteCond %{HTTP:Authorization} ^(.*) [NC] RewriteRule .* - [E=HTTP_AUTHORIZATION:%1] ``` Alternatively, if your host uses Apache's `mod_setenvif`, add this line anywhere in `.htaccess`: ```apache theme={null} SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 ``` After saving `.htaccess`, try connecting again in Siftly. </Accordion> <Accordion title="Self-hosted: 'REST API not found' error"> This means the WordPress REST API is not accessible at `{site_url}/wp-json/wp/v2/`. The most common cause is **Plain permalinks** being selected. Go to **Settings → Permalinks** in your WordPress admin, select any option other than **Plain** (e.g., **Post name**), and click **Save Changes**. Then try connecting again. Other causes include security plugins (e.g., Wordfence, iThemes Security) that disable the REST API, or a WAF/CDN that blocks API requests. </Accordion> <Accordion title="Self-hosted: Invalid credentials (401 error)"> Double-check your **username** (not your email address — use the username shown in your WordPress profile) and make sure you copied the **Application Password** exactly as generated, including the spaces. If you're unsure, go to **Users → Your Profile → Application Passwords**, delete the existing Siftly entry, generate a new one, and reconnect. </Accordion> <Accordion title="Self-hosted: Application Passwords section is missing from my profile"> This happens when: * Your site is not using HTTPS (Application Passwords require SSL on some configurations) * A security plugin has disabled Application Passwords * You are on WordPress.com with a plan that doesn't support this feature (use the OAuth connection instead) To re-enable via `wp-config.php`, add: `define('WP_APPLICATION_PASSWORDS_ENABLED', true);` </Accordion> <Accordion title="'WordPress not connected' error when publishing"> The integration was disconnected or the stored credentials are no longer valid. Go to **Settings → Integrations → WordPress** and reconnect. </Accordion> <Accordion title="Post published but content looks wrong in WordPress"> Open the post in your WordPress editor and switch to **HTML** or **Code Editor** view to inspect the raw markup. If formatting is broken, check for unsupported HTML tags in the generated content. You can edit the post directly in WordPress after publishing. </Accordion> <Accordion title="Post doesn't appear on my site after publishing"> If you published with **Published** status, posts should be live immediately. Check **WordPress → Posts → Published**. If you published as **Draft**, look under **WordPress → Posts → Drafts**. If the post isn't in either location, check the Siftly publish response for errors. </Accordion> <Accordion title="I connected the wrong site"> Go to **Settings → Integrations → WordPress**, click **Disconnect**, then click **Connect** and either log in with the correct WordPress.com account or enter the credentials for the correct self-hosted site. </Accordion> </AccordionGroup> # Connect to ChatGPT & Claude (MCP) Source: https://docs.siftly.ai/mcp/connect Connect Siftly to ChatGPT, Claude, and other AI assistants over MCP — then ask for your GEO data and run Siftly actions in plain language. Siftly runs a hosted **MCP server**. It lets AI assistants like ChatGPT and Claude read your GEO data and run Siftly actions in plain language — "What's my share of voice this week?" or "Draft a reply for today's top Reddit opportunity." You connect once with a URL, sign in with your Siftly account, and your assistant does the rest. MCP (Model Context Protocol) is the open standard these assistants use to reach outside tools. Siftly's server works with any MCP-compatible client. <Info> **Siftly MCP server URL** ``` https://mcp.siftly.ai/mcp ``` This is the only value you paste. No API key, client ID, or client secret — sign-in uses your existing Siftly login. </Info> ## Prerequisites * A Siftly account with an **active subscription**. The server declines workspaces with no active plan. * An AI client that supports **remote MCP connectors** (see the tabs below). ## Connection Details | Setting | Value | | ----------------- | ---------------------------------------------------- | | Server URL | `https://mcp.siftly.ai/mcp` | | Transport | Streamable HTTP (remote) | | Authentication | OAuth — sign in with your Siftly account | | Setup credentials | None — the connection registers itself automatically | When your client first reaches the server, Siftly returns the sign-in details and your client opens a Siftly login page. Approve access once, and the client refreshes its own access from then on. ## Connect Your Client <Tabs> <Tab title="ChatGPT"> Custom MCP connectors need **developer mode**. It's available on ChatGPT Plus, Pro, Business, Enterprise, and Education, in the web app. On Business, Enterprise, and Education, a workspace admin enables connectors first. <Steps> <Step title="Enable developer mode"> Open ChatGPT on the web. Go to **Settings → Apps → Advanced settings** and turn on **Developer mode**. </Step> <Step title="Add the connector"> In a chat, open the **+** menu, choose **Developer mode**, then **Add**. Paste `https://mcp.siftly.ai/mcp` as the server URL and continue. </Step> <Step title="Sign in to Siftly"> Approve access on the Siftly sign-in page. ChatGPT returns to your chat once connected. </Step> <Step title="Turn Siftly on for the chat"> Open the **+** menu and enable **Siftly** for the conversation. </Step> </Steps> <Note> ChatGPT reaches only public HTTPS servers. Use the `https://mcp.siftly.ai/mcp` URL — not a local address. </Note> </Tab> <Tab title="Claude"> **Pro or Max** <Steps> <Step title="Open Connectors"> In Claude on the web, go to **Settings → Connectors** (also shown under **Customize → Connectors**). </Step> <Step title="Add a custom connector"> Choose **Add custom connector** and paste `https://mcp.siftly.ai/mcp` as the remote MCP server URL. </Step> <Step title="Connect and sign in"> Choose **Connect** and sign in with your Siftly account. </Step> </Steps> <Note> Leave the OAuth client ID and secret blank under **Advanced settings** — the server registers your client for you. </Note> **Team or Enterprise** An **Owner** or **Primary Owner** adds the connector once, under organization **Settings → Connectors → Add custom connector**, using the same URL. Each member then connects and signs in with their own Siftly account. </Tab> <Tab title="Claude Code"> Add Siftly as a remote MCP server from the CLI: ```bash theme={null} claude mcp add --transport http siftly https://mcp.siftly.ai/mcp ``` Then run `/mcp` inside Claude Code and choose **Authenticate** to sign in with your Siftly account. </Tab> <Tab title="Other clients"> Any client that supports remote MCP over Streamable HTTP works. For clients that support only local (stdio) servers, bridge to the remote server with `mcp-remote`: ```json theme={null} { "mcpServers": { "siftly": { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.siftly.ai/mcp"] } } } ``` The bridge opens a browser window for the same Siftly sign-in on first use. </Tab> </Tabs> ## Choose Your Workspace The connection defaults to your **active** Siftly workspace. If you belong to more than one: * Ask your assistant to **"list my Siftly organizations"** to see every workspace, your role, and which one is active. * Then name the workspace in your request — for example, "get brand metrics for Acme Corp." Every response echoes the workspace it used, so you can confirm the scope. ## Verify the Connection Ask your assistant: **"Who am I connected to Siftly as?"** It returns your account, workspace, and access level. A clean response confirms sign-in, workspace, and data access are all working. ## What You Can Ask Reads are available to everyone in the workspace. Writes depend on your role, and any paid or outward action asks you to confirm first. | Area | Ask for… | | ---------------- | ----------------------------------------------------------------------------------- | | Visibility | Coverage, share of voice, and average rank, with the change vs. the previous period | | Leaderboard | How you rank against competitors by topic, engine, or location | | Citations | Which domains and pages cite your brand in AI answers | | Prompts & topics | The AI queries you track and how your brand performs on each | | Content | Recommendations, drafts, and full articles — and publishing them | | Search & traffic | Google Search Console performance and AI crawler activity on your site | | Reddit | Today's engagement queue, suggested replies, and streaks | | Account roll-up | A one-call summary for a meeting: visibility, blogs, Reddit, and outreach | **Example prompts** * "What's my coverage and share of voice over the last 7 days versus the week before?" * "Show my top cited domains and the pages they link to." * "Summarize my Siftly account for a call." * "Draft a Reddit reply for today's top opportunity." *(drafts only — see below)* ## Permissions, Spend & Safety * **Reads are open** to any member of the workspace. * **Writes follow your role.** Members get reversible changes; admins and owners get the full set. * **Paid and outward actions confirm first.** Generating an article, running analysis, publishing, and deletes show a preview and wait for your approval before anything runs or is charged. * **Nothing posts on your behalf.** The Reddit and LinkedIn tools draft and mark items as published — they never post to Reddit or LinkedIn for you. <Warning> Limits apply per workspace: up to 120 requests per minute, and up to 50 paid AI runs per day. You'll see a clear message if you reach either. </Warning> ## Troubleshooting <AccordionGroup> <Accordion title="It says my subscription is required"> The workspace has no active Siftly plan. Activate a plan, or switch to a workspace that has one. Ask your assistant to "list my Siftly organizations" to see which workspaces are entitled. </Accordion> <Accordion title="I'm asked to sign in again, or I get an authorization error"> The stored access expired or was revoked. Reconnect the Siftly connector in your client and sign in again. </Accordion> <Accordion title="It can't reach a workspace I named"> You can only reach workspaces you belong to. Use a name or ID from "list my Siftly organizations," then keep naming that workspace until you switch. </Accordion> <Accordion title="I hit a rate limit or spend cap"> You've passed 120 requests in a minute, or 50 paid AI runs in a day, for the workspace. Wait about a minute for the rate limit, or until the next day for the spend cap. </Accordion> <Accordion title="The connector won't add"> Confirm the URL is exactly `https://mcp.siftly.ai/mcp`, and that your plan supports custom connectors. ChatGPT needs developer mode; Claude needs Pro, Max, Team, or Enterprise. </Accordion> <Accordion title="A large workspace responds slowly"> Some metric queries scale with workspace size. Narrow the request — a shorter period, or a single brand — and try again. </Accordion> </AccordionGroup> ## Related <CardGroup> <Card title="Quickstart" icon="rocket" href="/quickstart"> Set up your brand and run your first GEO analysis. </Card> <Card title="Brand Visibility" icon="chart-bar" href="/features/brand-visibility"> Understand coverage, share of voice, and rank. </Card> <Card title="Citation Analysis" icon="quote-left" href="/features/citation-analysis"> See exactly where AI answers cite your brand. </Card> <Card title="AI Bot Traffic Tracking" icon="robot" href="/traffic-tracking/overview"> Track which AI crawlers read your site. </Card> </CardGroup> # Slack Integration Source: https://docs.siftly.ai/notifications/slack Get your daily Reddit reply queue delivered to Slack — one persistent thread per Reddit persona, with suggested replies and upvote targets threaded underneath. ## Overview Siftly's Slack integration turns your daily Reddit reply queue into a clean, scannable Slack conversation. Every morning at 7:00 UTC, each of your Reddit personas gets its own persistent thread in your chosen channel — with posts to comment on, AI-suggested replies, and upvote targets posted as threaded replies underneath. **Why the persistent thread?** * One thread per author, forever — the whole history of what "Alex" was asked to do is scrollable in one place. * Each morning appends a fresh date divider, so you can jump to any day. * Your team acts directly from Slack: every reply has an "Open Reddit thread" button. *** ## Prerequisites * An active Siftly subscription with at least one Reddit persona configured. * A Slack workspace where you have permission to install apps. *** ## Connect Slack <Steps> <Step title="Log in to Siftly"> Head to [app.siftly.ai](https://app.siftly.ai) and sign in. </Step> <Step title="Open Settings → Integrations"> From the left sidebar, click **Settings**, then switch to the **Integrations** tab. Find the **Slack** card under the Notifications section. </Step> <Step title="Click Connect with Slack"> Click the **Connect with Slack** button on the card. Siftly will redirect you to Slack's authorization screen. </Step> <Step title="Grant workspace access"> On the Slack screen, choose the workspace you want to connect. Review the requested permissions (post messages, read channel list) and click **Allow**. Siftly redirects you back to the Integrations tab automatically. </Step> <Step title="Pick a channel"> Once redirected, the Slack card shows a channel dropdown. Pick the channel where you want Siftly to post the daily Reddit reply queue. Private channels are supported — just make sure to `/invite @Siftly` the bot to them first. </Step> </Steps> You're connected. Click **Send test** on the card to post a sample thread so you can preview the exact layout your team will see each morning. *** ## What to expect Each morning at 7:00 UTC, per Reddit persona: * A **date divider** is posted as the first reply of the day (e.g. `📅 Jul 2 — 3 comments to write · 5 upvotes to give`). * Each **comment action** becomes its own threaded reply: subreddit, post title, AI-suggested reply, and two buttons — **Open Reddit thread** and **Manage in Siftly**. * **Upvote targets** for the day are collapsed into one threaded reply with a numbered list of clickable post titles. Tomorrow's queue lands in the same thread — no new top-level messages. Your channel stays quiet; the threads carry the volume. *** ## Managing the connection * **Change channel**: Disconnect and reconnect the Slack card, then pick the new channel. Old threads stay where they were (Slack doesn't allow moving messages across channels). * **Change workspace**: Reconnect from the Slack card and approve the new workspace. Siftly automatically starts fresh threads there. * **Disconnect**: Click **Disconnect** on the Slack card. Existing threads in Slack are preserved — Siftly just stops posting. *** ## Support Ran into an issue connecting Slack, or the daily thread isn't landing where you expect? [Mail us](mailto:virendra@siftly.ai) — we're happy to help. # Quickstart Source: https://docs.siftly.ai/quickstart Set up your brand on Siftly and run your first GEO analysis in under 10 minutes. <Frame> <img alt="Siftly setup progress — 6 steps to full GEO visibility" /> </Frame> ## Prerequisites Before you begin, make sure you have: * A Siftly account ([sign up free](https://app.siftly.ai/sign-up)) * Your brand's website URL * A list of 3–5 topics or categories your brand competes in *** ## Step 1: Create your organization When you first log in, Siftly will walk you through creating an **organization**. An organization is your workspace — it holds your brands, team members, and subscription. Enter your organization name and click **Continue**. <Tip> If you're an agency managing multiple clients, create one organization per client. Each organization has its own isolated brand data, users, and billing. </Tip> *** ## Step 2: Add your brand Inside your organization, click **Add Brand** and fill in the details: | Field | Description | | ----------------- | ------------------------------------------------------------ | | **Brand name** | The name as it appears in the market (e.g., "Acme Corp") | | **Website URL** | Your brand's primary domain | | **Industry** | The market category Siftly uses to find relevant prompts | | **Brand aliases** | Alternate names, abbreviations, or former names AI might use | <Warning> Brand aliases are important. If your brand is commonly abbreviated or has a parent/sub-brand relationship, add those here — otherwise citations using alternate names won't be counted. </Warning> Click **Save Brand** when done. *** ## Step 3: Select your topics Topics are the subject areas Siftly analyzes for your brand. They map to the kinds of questions AI users ask in your market. 1. From your brand page, click **Manage Topics** 2. Siftly will suggest topics based on your industry — select the ones relevant to you 3. Add custom topics using natural language (e.g., "best project management tools for remote teams") 4. Click **Save Topics** <Note> You can add or remove topics at any time. Changes take effect on the next analysis run. </Note> *** ## Step 4: Run your first analysis With your brand and topics configured, kick off an analysis: 1. Navigate to your brand's **Overview** page 2. Click **Run Analysis** 3. Siftly will query AI models with hundreds of prompts across your selected topics Analysis typically completes in **5–15 minutes** depending on the number of topics. You'll receive a notification when it's done. *** ## Step 5: Review your results Once the analysis completes, explore your dashboard: <CardGroup> <Card title="Overview" icon="gauge" href="/features/brand-visibility"> Your visibility score, citation rate, and trend vs. the previous period. </Card> <Card title="Citations" icon="quote-left" href="/features/citation-analysis"> Every AI response that mentioned your brand, with full context and sentiment. </Card> <Card title="Rankings" icon="list-ol" href="/features/rankings"> How you rank versus competitors for each topic. </Card> <Card title="Content" icon="file-pen" href="/features/content-generation"> AI-generated content recommendations to improve your citation rate. </Card> </CardGroup> *** ## Step 6: Schedule recurring analysis To track trends over time, set up a recurring analysis schedule: 1. Go to **Settings → Scheduled Analysis** 2. Choose a frequency: Daily, Weekly, or Monthly 3. Toggle the schedule on Siftly will automatically run analysis on your chosen schedule and email you a summary when results are ready. *** ## What's next? <CardGroup> <Card title="Understand your visibility score" icon="chart-bar" href="/features/brand-visibility"> Learn what the score means and how to improve it. </Card> <Card title="Invite your team" icon="users"> Go to **Settings → Team** to invite colleagues and set roles. </Card> <Card title="Connect your CMS" icon="plug" href="/integrations/overview"> Push GEO-optimized content directly from Siftly to your website. </Card> <Card title="Track AI bot traffic" icon="robot" href="/traffic-tracking/overview"> See which AI crawlers are visiting your site and how often. </Card> </CardGroup> # Notifications Source: https://docs.siftly.ai/shopping/account/notifications Stay on top of publish jobs, completed analyses, and alerts from the in-app notification center. ## Overview Siftly Shopping runs work in the background: analyses, bulk publishing, and more. The notification center keeps you posted so you don't have to watch a progress bar. ## Using the notification center The bell icon shows a badge when you have unread notifications. Open it to see your recent items; click one to jump to the related page, and mark items as read to clear the badge. ## What you'll be notified about | Notification | Means | | ---------------------------------------- | ------------------------------------------------------ | | **Publish started / completed / failed** | A bulk publish job changed status | | **Analysis ready** | A new analysis finished and your metrics are updated | | **Alerts** | Something needs your attention, like a job that failed | <Note> Some notifications are organization-wide, so every teammate sees them; others are specific to you. </Note> ## Related <CardGroup> <Card title="Team & settings" icon="users" href="/shopping/account/team-settings"> Manage your organization and team. </Card> <Card title="Content & optimization" icon="pen-nib" href="/shopping/content/overview"> Where bulk publish jobs come from. </Card> </CardGroup> # Plans & billing Source: https://docs.siftly.ai/shopping/account/plans-billing Compare Siftly Shopping plans, start a trial, and manage your subscription and usage. <Frame> <img alt="Plans & billing: trial and paid tiers with usage meters" /> </Frame> ## Overview Siftly Shopping is subscription-based. You start on a free trial and upgrade to a paid plan as your needs grow. This page covers the plans, how to start and manage a subscription, and how usage works. ## Plans | Plan | For | | -------------- | ---------------------------------------------------------------- | | **Try** | A free trial to explore Siftly Shopping, no credit card required | | **Starter** | Smaller catalogs getting started with AI shopping visibility | | **Growth** | Growing brands that need more tracking and more content | | **Pro** | High-volume brands wanting the full toolset and highest limits | | **Enterprise** | Custom scale, terms, and support; talk to our team | <Note> Plan names, limits, and included features are shown live on the plan-selection screen. Treat that screen as the source of truth for what each plan includes. </Note> ## Starting and upgrading After onboarding, you'll land on the plan-selection screen. <Steps> <Step title="Start your trial"> Choose **Try** to begin your free trial and go straight to your dashboard. </Step> <Step title="Upgrade when ready"> From **Settings → Billing**, pick a paid plan and complete checkout. Your plan and limits update immediately. </Step> <Step title="Manage anytime"> Cancel or reactivate from **Settings → Billing**. Cancellations remain active until the end of your billing period. </Step> </Steps> ## How you're billed Siftly Shopping supports two billing paths: * **Shopify Managed Pricing**: merchants who install from the Shopify App Store are billed through Shopify. * **Stripe**: existing merchants are billed through Stripe. Your billing path is set automatically based on how you signed up. ## Usage and limits Each plan includes limits on resources like monthly analysis and content generation. Track your usage against those limits in **Settings → Billing**. As you approach a limit you'll see a warning; upgrading raises your limits right away. ## Related <CardGroup> <Card title="Team & settings" icon="users" href="/shopping/account/team-settings"> Manage your organization and team. </Card> <Card title="Quickstart" icon="rocket" href="/shopping/quickstart"> New here? Set up and run your first analysis. </Card> </CardGroup> # Team & settings Source: https://docs.siftly.ai/shopping/account/team-settings Manage your organization, invite teammates, set roles, and configure the brand settings that power your analysis. ## Overview Your **organization** is your workspace in Siftly Shopping. It holds your brand, products, team, integrations, and subscription. This page covers managing your team and your organization settings. ## Organizations and sign-in Siftly Shopping uses single sign-on for authentication. Sign in once, and you can belong to one or more organizations, which is useful if you manage multiple brands. Each organization keeps its data, members, and billing separate. ## Team and roles Invite teammates and manage access from **Settings → Team**. | Role | Can do | | ---------- | ------------------------------------------------------------- | | **Owner** | Full control, including billing and deleting the organization | | **Admin** | Manage members, integrations, and settings | | **Member** | Use the product; limited administrative access | <Steps> <Step title="Invite a teammate"> Go to **Settings → Team → Invite** and enter their email. They'll receive an invitation to join your organization. </Step> <Step title="Set their role"> Assign Owner, Admin, or Member based on what they need to do. </Step> <Step title="Manage access"> Change roles or remove members at any time from the same screen. </Step> </Steps> ## Brand settings From **Settings**, configure the inputs that shape your analysis: * **Brand**: name, website, and industry * **Locations**: the markets you sell into * **Topics and personas**: the shopping intents and shopper types Siftly generates prompts for * **Competitors**: the brands you want to benchmark against <Tip> Keep topics, personas, and competitors current. They directly determine the prompts Siftly runs and who you're compared against on the shelf. </Tip> ## Related <CardGroup> <Card title="Plans & billing" icon="rocket" href="/shopping/account/plans-billing"> Manage your subscription and usage. </Card> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Connect your store and analytics. </Card> <Card title="Notifications" icon="bell" href="/shopping/account/notifications"> Stay on top of jobs and alerts. </Card> <Card title="Quickstart" icon="rocket" href="/shopping/quickstart"> Set up your organization from scratch. </Card> </CardGroup> # Citations Source: https://docs.siftly.ai/shopping/analytics/citations See which domains and pages AI shopping engines cite when recommending products in your market, and find the sources worth earning. <Frame> <img alt="Citations page: source mix by site type and page type, top domains, and most-cited URLs" /> </Frame> ## Overview When AI shopping engines recommend products, they draw on sources from across the web: reviews, buying guides, retailer pages, and more. The Citations page shows you exactly which sources they're citing in your market, so you can earn a place among them. ## Where AI gets its information * **Source mix**: citations grouped by site type (commerce, publisher, social, review, brand sites) * **Content signals**: citations grouped by page type (product pages, articles, reviews, category pages, and more) Together these tell you what *kind* of content is shaping recommendations on your shelf. ## Top sources * **Top domains**: the domains cited most often in your market, ranked by frequency * **Most cited URLs**: the individual pages that come up again and again * **Domain lookup**: click any domain to see its per-page breakdown and which of your products it's associated with ## Your content vs. the gaps Citations distinguishes your **own** pages that get cited from sources where competitors appear but you don't, a direct list of content opportunities. Pair this with [Content](/shopping/content/blog) and [Collection Pages](/shopping/content/collections) to close the gaps. ## Filters and export Filter by product, geography, and date range, and export the full citation list to CSV for deeper analysis or sharing. ## Related <CardGroup> <Card title="Content" icon="pen-nib" href="/shopping/content/blog"> Create content worth citing. </Card> <Card title="Conversations" icon="comments" href="/shopping/analytics/conversations"> See citations in the context of each response. </Card> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Track how earning citations moves your shelf share. </Card> <Card title="Google Search Console" icon="magnifying-glass" href="/shopping/integrations/google-search-console"> Compare against organic search performance. </Card> </CardGroup> # Commerce Control Source: https://docs.siftly.ai/shopping/analytics/commerce-control Measure operational control on the AI shelf: buy-button ownership, price competitiveness, and merchant breadth across your catalog. <Frame> <img alt="Commerce Control: buy-button share, price rank and premium, and availability by merchant" /> </Frame> ## Overview Being on the shelf is one thing; controlling the sale is another. Commerce Control measures how much **operational control** you have over the products that appear in AI shopping answers: who owns the buy button, how your pricing compares, and how widely your products are stocked. ## Key metrics | Metric | What it tells you | | ------------------------------ | -------------------------------------------------------------------------------------------------- | | **Buy-button owned share** | The share of your products where you own the primary buy button (versus a marketplace or retailer) | | **Merchant breadth** | The average number of merchants carrying each product, a read on distribution | | **Buy-button price rank** | Where your price ranks among sellers (1 = cheapest) | | **Buy-button price premium** | How much above or below the market median you're priced | | **Relative Price Index (RPI)** | Your price versus the competitive average | | **Value Hit Ratio** | The share of your products priced at or below the competitor average | ## Availability by merchant A table shows which merchants carry each product and their stock status, so you can spot out-of-stock or under-distributed items that are costing you shelf presence. ## Filters Scope everything by **geography** and drill into a single **product** to see its pricing position and competitor set. <Tip> High Share of Shelf with a weak buy-button share means AI is recommending your products but sending the sale elsewhere. That's a signal to prioritize owning the buy button on those items. </Tip> ## Related <CardGroup> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> See presence alongside control. </Card> <Card title="Products & readiness" icon="tags" href="/shopping/analytics/products"> Drill into per-product pricing and readiness. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Improve the product data behind the shelf. </Card> <Card title="What is Share of Shelf?" icon="circle-info" href="/shopping/concepts/share-of-shelf"> Understand RPI and Value Hit Ratio. </Card> </CardGroup> # Conversations Source: https://docs.siftly.ai/shopping/analytics/conversations Browse the prompts and AI responses behind your visibility, right down to the individual products that were recommended. <Frame> <img alt="Conversations page: a filterable list of prompts with the responses and recommended products behind each" /> </Frame> ## Overview Your metrics roll up from thousands of individual AI answers. Conversations is where you see the raw material: every **prompt** Siftly runs against AI shopping engines, and the **responses** behind your numbers. ## Prompts, responses, and recommended products Siftly's analysis follows a simple chain: 1. A **prompt** is the shopper question Siftly asks (for example, "best budget espresso machine"). 2. Running a prompt produces one or more **responses**: the AI's answers, across platforms and over time. 3. Each response contains **recommended products** (the tiles), each with a rank, plus the **citations** behind the answer. ## Browsing The prompts table lists each prompt with its product, brand, response count, and visibility metrics. Use the search box and the product, brand, and date filters to find what you need. ## Drilling into a prompt Click any prompt to open its detail view: * The full prompt text and its metadata * Every response, with the recommended products and citations it contained * Visibility for that prompt over time <Tip> Prompts where you never appear are pure opportunity. Use them to brief [Content](/shopping/content/blog) and [Product Optimization](/shopping/content/product-optimization). </Tip> ## Related <CardGroup> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> See the metrics these conversations roll up to. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> Analyze the sources cited across responses. </Card> <Card title="Products & readiness" icon="tags" href="/shopping/analytics/products"> Connect prompts to the products they mention. </Card> <Card title="Content" icon="pen-nib" href="/shopping/content/blog"> Turn gap prompts into content. </Card> </CardGroup> # Dashboard overview Source: https://docs.siftly.ai/shopping/analytics/overview Your brand's AI shopping health at a glance: appearances, reliability, top-3 rank, and the data-quality items worth resolving. <Frame> <img alt="Siftly Shopping dashboard: headline metrics, cited content, and data quality" /> </Frame> ## Overview The dashboard is your starting point each time you log in. It summarizes how your products are showing up in AI shopping answers, surfaces the content AI is already citing, and flags data worth cleaning up, each with a change versus the previous period. ## Headline metrics | Metric | What it tells you | | ------------------------ | ------------------------------------------------------------------------- | | **Appearances** | How often your products showed up as tiles across tracked prompts | | **Reliability** | The share of responses where your brand appeared at least once | | **Top-3 rank** | The share of responses where your product placed in the first three tiles | | **Relative Price Index** | How your pricing compares to the competitive average | | **Content performance** | How the content you've published is performing in AI answers | For precise definitions, see [What is Share of Shelf?](/shopping/concepts/share-of-shelf). ## Cited content The dashboard highlights your own pages that AI shopping engines have recently cited, a quick read on which content is earning its place on the shelf. Dig deeper on the [Citations](/shopping/analytics/citations) page. ## Data quality Siftly flags items it couldn't confidently match: products or brands seen in AI answers that don't line up with your catalog. Resolving these keeps your metrics accurate. Each item links into [Conversations](/shopping/analytics/conversations) so you can see the context. <Note> If you've just onboarded, some cards will be empty until your first analysis completes. Newly tracked products also spend their first 14 days in a warm-up cohort before counting toward headline Share of Shelf. </Note> ## Where to go next <CardGroup> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Track shelf share and competitive position over time. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See which sources AI engines cite in your market. </Card> <Card title="Products & readiness" icon="tags" href="/shopping/analytics/products"> Find untapped products to prioritize. </Card> <Card title="Conversations" icon="comments" href="/shopping/analytics/conversations"> Read the prompts and responses behind your metrics. </Card> </CardGroup> # Products & readiness Source: https://docs.siftly.ai/shopping/analytics/products Manage your tracked catalog and see how ready each product is to win a place in AI shopping answers. <Frame> <img alt="Products page: tracked catalog with readiness scores and untapped wins" /> </Frame> ## Overview The Products page manages the catalog Siftly tracks and scores how **ready** each product is to appear in AI shopping answers. It's where you decide what to track and find the products with the most upside. ## Your catalog * **Tracked vs. untracked**: choose which products Siftly analyzes; add or remove them at any time * **Sync**: pull the latest catalog from [Shopify](/shopping/integrations/shopify) or [Google Merchant Center](/shopping/integrations/google-merchant-center) * **Visibility score**: each product's current presence in AI answers, at a glance ## Product readiness Readiness scores how well-positioned a product is to win on the shelf, across signals such as: * **Content**: supporting blog posts, Collection Pages, and product pages * **SEO/GEO presence**: whether the product is discoverable and cited * **Pricing**: how competitive its price is * **Reviews and social**: the strength of third-party signals Open any product to see its readiness detail, linked content, top citing sources, and recent interventions. ## Untapped wins Siftly highlights products that aren't yet appearing in AI answers but look ready to. These are your highest-leverage candidates for [Product Optimization](/shopping/content/product-optimization) and [Content](/shopping/content/blog). <Tip> Start with untapped wins that already have strong product data. They often need only a content push or a feed cleanup to break onto the shelf. </Tip> ## Related <CardGroup> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Optimize a product's data for AI shopping. </Card> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> See how products contribute to shelf share. </Card> <Card title="Commerce Control" icon="scale-balanced" href="/shopping/analytics/commerce-control"> Check pricing and buy-button control per product. </Card> <Card title="Shopify" icon="shopify" href="/shopping/integrations/shopify"> Sync your catalog. </Card> </CardGroup> # Traffic Source: https://docs.siftly.ai/shopping/analytics/traffic See which AI crawlers read your store, and how much traffic AI assistants and organic search drive, via Cloudflare, Google Analytics 4, and Search Console. <Frame> <img alt="Traffic page: AI crawler activity from Cloudflare, AI referral traffic from GA4, and organic search from Search Console" /> </Frame> ## Overview Visibility on the AI shelf only matters if it turns into reads and then visits. The Traffic page brings both sides together: which AI and search crawlers read your pages (via **Cloudflare**), and how many shoppers then arrive from AI assistants and organic search (via **Google Analytics 4** and **Google Search Console**). <Note> Traffic covers two complementary signals. **Crawler activity** (from Cloudflare) is which AI and search bots read your pages at the edge. **Referral and search analytics** (from GA4 and Search Console) is which shoppers actually arrive. Crawls are the leading indicator; visits are the outcome. </Note> ## AI crawler activity (Cloudflare) With [Cloudflare connected](/shopping/integrations/cloudflare), the page shows which AI and search crawlers read your store at the edge: * **Crawler Activity** split into AI Citations, AI Indexing, and AI Training, with a per-bot breakdown * **Top Crawled Pages**, and per bot, the pages each one hits * A **Platform-to-Page Journey** view and a Published Articles table that ties crawler activity to AI referrals and Search Console data Crawler data starts accumulating when you connect, with no backfill, so connect early. On the Cloudflare Free plan this is hourly, user-agent-based data, which is enough for trend analysis; per-request logs need a Cloudflare Enterprise plan. ## AI referral traffic (GA4) With [GA4 connected](/shopping/integrations/ga4), the page shows: * Headline metrics: sessions, users, and engagement, with period-over-period change * **AI referral traffic** broken down by assistant (ChatGPT, Perplexity, and others) * Channel mix across your traffic sources * Your top pages by AI-assistant traffic ## Organic search (Search Console) With [Search Console connected](/shopping/integrations/google-search-console), the page shows: * Clicks and impressions over time * Click-through rate and average position * Top queries and pages driving organic search ## Getting set up If an integration isn't connected, the page shows a connect card; if access expires, you'll see a reconnect prompt. GA4 and Search Console connect with read-only Google OAuth, and Cloudflare uses a read-only API token you generate. <Tip> Watch AI referral traffic alongside your [Share of Shelf](/shopping/analytics/visibility). As shelf share rises, referral sessions from AI assistants should follow, confirming your gains are translating into visits. </Tip> ## Related <CardGroup> <Card title="Google Analytics 4" icon="chart-line" href="/shopping/integrations/ga4"> Connect GA4 for referral traffic. </Card> <Card title="Google Search Console" icon="magnifying-glass" href="/shopping/integrations/google-search-console"> Connect GSC for organic search. </Card> <Card title="Cloudflare" icon="cloudflare" href="/shopping/integrations/cloudflare"> Connect Cloudflare for AI crawler activity. </Card> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Correlate traffic with shelf share. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See which sources drive AI recommendations. </Card> </CardGroup> # Visibility & Share of Shelf Source: https://docs.siftly.ai/shopping/analytics/visibility Track your Share of Shelf, brand and product visibility, and competitive position in AI shopping answers over time. <Frame> <img alt="Visibility page: Share of Shelf trend with intervention markers and a competitor leaderboard" /> </Frame> ## Overview The Visibility page is where you track **Share of Shelf** (the share of product tiles in AI shopping answers that are yours) and how it moves as you publish content and optimize products. It's your main view of competitive standing on the AI shelf. New to the metric? Start with [What is Share of Shelf?](/shopping/concepts/share-of-shelf). ## The Share of Shelf trend The headline chart plots your Share of Shelf over time, with **intervention markers** showing when you published a blog post, a Collection Page, or a product optimization, so you can see the lift each change drove. * **Cohort toggle**: switch between **mature** (established products only) and **full portfolio** (including products still in their 14-day warm-up). * **Geography filter**: scope every metric on the page to a specific country. ## Brand and product visibility Alongside Share of Shelf, the page tracks: * **Visibility**: the breadth of shopping intents where your brand appears at all * **Reliability**: how consistently you appear when the same prompt is asked repeatedly * **Brand vs. product mentions**: whether your brand showed up, and which specific products did ## Competitive view * **Competitor leaderboard**: your Share of Shelf plotted against the top brands on your shelf * **Heatmap**: shelf share across brands by geography or by product, so you can spot strengths and gaps at a glance ## Per-product drill-down A table breaks visibility down by product (visibility, reliability, Share of Shelf, and rank) so you can see which products carry your shelf presence and which need work. Click a product to open its readiness detail. See [Products & readiness](/shopping/analytics/products). <Tip> When Share of Shelf dips right after you add products, switch to the **mature** cohort. New products warm up for 14 days, so the full-portfolio view can understate established performance during that window. </Tip> ## Related <CardGroup> <Card title="Commerce Control" icon="scale-balanced" href="/shopping/analytics/commerce-control"> Go beyond presence to pricing and buy-button control. </Card> <Card title="Conversations" icon="comments" href="/shopping/analytics/conversations"> See the prompts behind your shelf share. </Card> <Card title="Products & readiness" icon="tags" href="/shopping/analytics/products"> Drill into per-product readiness. </Card> <Card title="Content & optimization" icon="pen-nib" href="/shopping/content/overview"> Turn shelf gaps into published improvements. </Card> </CardGroup> # What is Share of Shelf? Source: https://docs.siftly.ai/shopping/concepts/share-of-shelf Understand GEO for commerce: how AI shopping engines choose products, and the metrics Siftly Shopping uses to measure your presence on the AI shelf. ## The shift in shopping search For years, winning ecommerce search meant ranking in a grid of results: optimize your product page, earn reviews, win the click. Shoppers scrolled, compared, and chose. That model is changing fast. AI assistants like **ChatGPT Shopping**, **Google AI Mode**, **Google Shopping**, and **Perplexity** now answer shopping questions directly. Ask one for "the best electric toothbrush for sensitive gums" and it returns a short, curated **carousel** of product recommendations, each product a **tile** on a digital shelf. There is no page two. A handful of products get recommended; everything else is invisible. **Share of Shelf** is the commerce equivalent of ranking: *of all the product tiles an AI assistant shows for prompts in your market, how many are yours?* ## SEO vs. GEO vs. GEO for commerce | | Traditional ecommerce SEO | GEO (brand visibility) | GEO for commerce | | ---------- | ------------------------- | ------------------------------- | ---------------------------------------- | | **Target** | Search engine crawlers | AI language models | AI shopping assistants | | **Goal** | Rank in the results grid | Get your brand cited in answers | Get your **products** on the shelf | | **Unit** | A web page | A brand mention | A product tile | | **Metric** | Keyword rank, clicks | Citations, share of voice | **Share of Shelf**, reliability, rank | | **Levers** | Backlinks, on-page SEO | Authority, structured content | Product feeds, content, pricing, reviews | GEO for commerce doesn't replace ecommerce SEO. It extends it. A strong product page still helps. But the signals that get a product onto an AI shelf are different enough to deserve their own strategy. ## How AI shopping engines pick products AI shopping answers are assembled from three sources. Each is a lever you can pull. ### 1. Product feeds and structured data Engines lean heavily on structured product data: your **Google Merchant Center** and **Google Manufacturer Center** feeds, and your **Shopify** catalog. Clean, complete, well-attributed products are far easier to recommend. See [Product Optimization](/shopping/content/product-optimization). ### 2. Retrieval from the web (citations) Most AI shopping engines retrieve live content at answer time (reviews, buying guides, listicles, and retailer pages) and cite them. The sources they cite are the sources shaping the recommendation. See [Citations](/shopping/analytics/citations). ### 3. Model knowledge Models carry baseline knowledge about well-established brands and products from training. A strong, consistent presence across the web raises your baseline likelihood of being recommended. ## The GEO-for-commerce playbook <Steps> <Step title="Find your shelf gaps"> Identify the prompts where competitors get recommended but you don't. These are your highest-leverage opportunities. Start on the [Visibility](/shopping/analytics/visibility) and [Conversations](/shopping/analytics/conversations) pages. </Step> <Step title="Strengthen your product data"> Make sure your feeds and catalog are complete and well-attributed. [Product Optimization](/shopping/content/product-optimization) rewrites titles, descriptions, and attributes for AI shopping and submits them to GMC and GMfC. </Step> <Step title="Earn the right citations"> See which sources AI engines cite for your market and create content that deserves a place among them, including [blog Content](/shopping/content/blog) and [Collection Pages](/shopping/content/collections). </Step> <Step title="Track and iterate"> Watch your Share of Shelf move after each change. GEO for commerce is iterative. What works shifts as engines update and competitors adapt. </Step> </Steps> ## Key metrics in Siftly Shopping <AccordionGroup> <Accordion title="Share of Shelf (SoS)"> The share of visible product tiles that are yours, across a set of AI shopping responses. If AI assistants show 1,000 product tiles across your tracked prompts and 180 are yours, your Share of Shelf is 18%. It's your headline metric. </Accordion> <Accordion title="Visibility"> The percentage of tracked prompts where your brand appears at least once. Visibility measures **breadth**: how many of the shopping intents in your market you show up for at all. </Accordion> <Accordion title="Reliability"> The percentage of responses (runs) where your brand appears at least once. Reliability measures **consistency**: when the same prompt is asked repeatedly, how dependably do you show up? </Accordion> <Accordion title="Top-3 rank"> The percentage of responses where your product appears in the first three tiles. Earlier tiles get far more shopper attention, so position matters as much as presence. </Accordion> <Accordion title="Relative Price Index (RPI) & Value Hit Ratio"> **RPI** compares your price to the competitive average for the same shelf. **Value Hit Ratio** is the percentage of your products priced at or below the competitor average, a quick read on how often you look like good value. Both live on [Commerce Control](/shopping/analytics/commerce-control). </Accordion> <Accordion title="Warm-up cohort (mature vs. full portfolio)"> Newly tracked products are in a **warm-up cohort** for their first 14 days and are excluded from your headline Share of Shelf, so adding products doesn't read as a sudden drop. Switch between the **mature** view (established products only) and the **full portfolio** view (including warming-up products) on the Visibility page. </Accordion> </AccordionGroup> <Note> GEO for commerce is an emerging field, and AI shopping platforms evolve rapidly. Siftly Shopping's analysis is continuously updated to reflect how the major engines retrieve, rank, and recommend products. </Note> # Content Source: https://docs.siftly.ai/shopping/content/blog Generate grounded, GEO-for-commerce blog posts and publish them straight to your Shopify blog. <Frame> <img alt="Content editor: a rendered blog post with chat editing, GEO quality metrics, and publishing" /> </Frame> ## Overview Content generates blog posts that are grounded in your brand and product data: buying guides, comparisons, and how-tos that answer the questions shoppers ask AI. Instead of starting from a blank page, you start from your products, your evidence, and the gaps where you're not yet showing up. Every post is built to earn citations from AI shopping engines, then published in a click to your Shopify blog. *** ## Creating a post <Steps> <Step title="Pick a product and topic"> Go to **Content → Generate new content**, choose the product to ground the post in, and give it a topic or angle. </Step> <Step title="Choose how involved you want to be"> Pick an interaction mode (see below), then start generation. </Step> <Step title="Let it generate"> The pipeline runs in the background and opens the editor when the draft is ready. </Step> </Steps> **Interaction modes** control how often the pipeline pauses for your input: | Mode | Behavior | | --------------- | ------------------------------------------- | | **Auto** | Runs end to end without pausing | | **Guided** | Pauses to review the topic and the draft | | **Interactive** | Pauses at every checkpoint for full control | *** ## The pipeline Content runs a five-phase pipeline. Each phase builds on the last. ```mermaid theme={null} flowchart LR A[Analysis] --> B[Topic strategy] B --> C[Research] C --> D[Writing] D --> E[Validation] ``` 1. **Analysis** collects signals about your product, market, competitors, and brand. 2. **Topic strategy** designs the post: its angle, headline, structure, and target length. 3. **Research** ranks the supporting evidence and finds gaps to fill. 4. **Writing** drafts the post, citing its evidence inline. 5. **Validation** checks that every claim is grounded and on-brand, rewriting where needed. *** ## Grounded evidence Every signal Siftly collects (a product detail, a competitor pattern, a brand fact) becomes a piece of evidence in a **Grounded Evidence Pool**. The writer cites that evidence inline as it drafts, and validation enforces that claims trace back to it. The result is content that's specific and defensible rather than generic. That's exactly what AI shopping engines prefer to cite. *** ## The editor The editor shows the rendered post on the left and tools on the right: * **Chat**: refine the draft in plain language, scoped to a section or the whole post. * **GEO Optimization**: quality signals like readability, keyword coverage, and internal links. * **Publish**: SEO metadata, hero image, and publishing options. * **History**: versioned snapshots of every accepted edit. * **Inputs**: the evidence, research, and citations behind the draft. *** ## Publishing When the post is ready, click **Approve** to unlock publishing, then publish to your **Shopify blog** as a **Draft** or **Published** article. After publishing, Siftly keeps the canonical URL so the post can be tracked in your [Citations](/shopping/analytics/citations). *** ## Related <CardGroup> <Card title="Collection Pages" icon="layer-group" href="/shopping/content/collections"> Build AI-ready Shopify collection pages. </Card> <Card title="Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Ground every post in your brand's facts and voice. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See which sources AI engines cite in your market. </Card> <Card title="Shopify" icon="shopify" href="/shopping/integrations/shopify"> Connect your store to publish posts. </Card> </CardGroup> # Collection Pages Source: https://docs.siftly.ai/shopping/content/collections Generate and optimize Shopify collection pages built around your products, with rationale-backed picks, descriptions, and FAQs, then publish in a click. <Frame> <img alt="Collection Page editor: rendered preview with product picks and rationale, plus chat-based editing" /> </Frame> ## Overview Collection Pages turns a product into a complete, AI-ready Shopify collection page: a curated set of products with a written introduction, rationale for each pick, and FAQs. Well-structured collection pages are exactly the kind of content AI shopping engines like to cite and recommend. You can **create** a brand-new collection or **optimize** one you already have, then refine it by chat and publish to your store. *** ## How a collection comes together ### It starts from where the product already lives When you pick a product, Siftly checks its current **coverage** and chooses the right path: | Coverage | What Siftly does | | -------------------------------------- | -------------------------------------------------- | | **Not in any collection** | Creates a new collection from scratch | | **In one of your Shopify collections** | Optimizes that existing collection | | **Already in a Siftly draft** | Opens the existing draft instead of duplicating it | | **Both** | Lets you pick which to work on | This means you never accidentally create a duplicate collection for a product that's already covered. ### The generation pipeline Once you choose, Siftly runs a short, multi-step pipeline in the background: <Steps> <Step title="Setup"> Siftly gathers context about the product, your catalog, and the competitive and citation signals in your market. </Step> <Step title="Routing"> Based on coverage, Siftly decides whether to write a full new collection or patch an existing one. </Step> <Step title="Writing"> Siftly drafts the collection (an introduction, the product picks with a rationale for each, and supporting copy) grounded in evidence. </Step> <Step title="Finishing"> The draft is humanized, checked against your brand rules, given SEO metadata and structured data, and validated. </Step> </Steps> You'll see the status move from **analyzing** to **generating** to **completed** as it runs. *** ## Creating a collection <Steps> <Step title="Pick a product"> Go to **Collections → Start a new collection** and choose the product to build around. </Step> <Step title="Choose create or optimize"> Siftly shows the product's coverage and offers the right action: create new, optimize an existing collection, or open an existing Siftly draft. </Step> <Step title="Let it generate"> The pipeline runs and opens the collection editor when it's ready. </Step> </Steps> *** ## The editor The editor shows a live **rendered preview** of the collection on the left: title, hero, description blocks, the product picks with their rationale, and FAQs. On the right are tabs: * **Chat**: make scoped edits in plain language. Pin a specific block to focus your edit on just that section. * **Publish**: set SEO metadata, the hero image, the URL handle, and where it publishes. * **History**: every accepted edit is versioned; click any version to compare. * **Inputs**: the analysis and signals that informed the draft. *** ## Validation and publishing When you're happy, click **Approve** to unlock publishing. On publish, Siftly validates the collection's structure and checks it against your brand rules. <Note> If validation finds issues, Siftly lists them in a dialog with a **Publish anyway** option, so you stay in control of what goes live. </Note> Collections publish to your Shopify **Online Store**. Once live, Siftly shows the collection's URL, and you can **republish** to push updates after further edits. *** ## Related <CardGroup> <Card title="Content & optimization overview" icon="layer-group" href="/shopping/content/overview"> See all three ways Siftly turns insight into published improvements. </Card> <Card title="Content" icon="pen-nib" href="/shopping/content/blog"> Generate blog posts grounded in your brand and products. </Card> <Card title="Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Ground every collection in your brand's facts and voice. </Card> <Card title="Shopify" icon="shopify" href="/shopping/integrations/shopify"> Connect your store to publish collections. </Card> </CardGroup> # Content & optimization overview Source: https://docs.siftly.ai/shopping/content/overview The three ways Siftly Shopping turns insight into action: blog content, Collection Pages, and Product Optimization. <Frame> <img alt="Content & optimization: blog content, Collection Pages, and Product Optimization" /> </Frame> ## Overview Analysis tells you where you're losing the shelf. Siftly Shopping's three generators help you do something about it, each turning insight into published improvements grounded in your [Knowledge Hub](/shopping/knowledge-hub/overview). <CardGroup> <Card title="Content" icon="pen-nib" href="/shopping/content/blog"> Blog posts: buying guides, comparisons, and how-tos that earn citations. </Card> <Card title="Collection Pages" icon="layer-group" href="/shopping/content/collections"> Curated Shopify collection pages built around your products. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Optimized product data submitted to Google. </Card> </CardGroup> ## When to use each | Use | When you want to… | | ------------------------ | -------------------------------------------------------------------------- | | **Content** | Win prompts where shoppers ask for advice, comparisons, or recommendations | | **Collection Pages** | Give a group of products a citable, AI-ready landing page on your store | | **Product Optimization** | Strengthen the product data that feeds Google's shopping surfaces | ## One shared workflow All three follow the same pattern, so once you've used one, you know them all: <Steps> <Step title="Pick a product"> Each generator starts from a product in your catalog. </Step> <Step title="Run the pipeline"> Siftly drafts the output through a multi-step pipeline grounded in evidence and your brand. </Step> <Step title="Refine by chat"> Edit in plain language, scoped to a section, attribute, or block. </Step> <Step title="Validate and publish"> Approve, clear validation, and publish to Shopify or submit to Google. </Step> </Steps> ## Related <CardGroup> <Card title="Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Ground every generator in your brand. </Card> <Card title="Reddit engagement" icon="reddit" href="/shopping/content/reddit"> Grow presence through authentic community engagement. </Card> </CardGroup> # Product Optimization Source: https://docs.siftly.ai/shopping/content/product-optimization Optimize product titles, descriptions, and attributes for AI shopping and submit them to Google Merchant Center and Manufacturer Center. <Frame> <img alt="Product Optimization: baseline vs. proposed attribute diffs, with GMC and GMfC submission" /> </Frame> ## Overview Product Optimization rewrites your product data (titles, descriptions, and attributes) to be clearer and more complete for AI shopping engines, then submits the results to [Google Merchant Center](/shopping/integrations/google-merchant-center) and [Google Manufacturer Center](/shopping/integrations/google-manufacturer-center). Better structured data is one of the most direct levers for getting onto the shelf. ## Choosing products The candidates list shows your tracked products with a **readiness score** and the number of suggested improvements. Readiness reflects how complete your product data is. Start with high-impact, lower-readiness products. ## How a job runs <Steps> <Step title="Analysis"> Siftly gathers your baseline product data, competitor patterns, and brand context. </Step> <Step title="Writing"> It proposes optimized titles, descriptions, and attributes tuned for AI shopping. </Step> <Step title="Review"> A compliance and claims check catches policy issues, overlong fields, and unsupported claims. </Step> <Step title="Finishing"> The result is normalized, scored for readiness, and prepared for submission. </Step> </Steps> In **guided** mode the job pauses for your review; in **auto** mode it runs straight through to await your approval. ## Reviewing changes The workspace shows your product with **baseline vs. proposed** attribute rows. Accept or reject changes, rewrite individual attributes, or refine by chat. Separate tabs organize the data for **Review**, **Google Merchant Center**, and **Google Manufacturer Center**. ## Submitting When you **Approve** a job, submission unlocks: * **Submit to GMC**: preview the feed snippet with a dry run, then submit. Apply changes to one variant or bulk-apply across several. * **Publish to GMfC**: for products whose brand is approved in Manufacturer Center. <Note> Every submission is versioned. Use the version timeline to review past submissions or roll back. </Note> <Warning> Hard policy violations (prohibited claims, length limits) block submission until resolved. Advisory issues appear as warnings you can choose to proceed past. </Warning> ## Related <CardGroup> <Card title="Google Merchant Center" icon="google" href="/shopping/integrations/google-merchant-center"> Connect your product feed. </Card> <Card title="Google Manufacturer Center" icon="google" href="/shopping/integrations/google-manufacturer-center"> Publish manufacturer attributes. </Card> <Card title="Products & readiness" icon="tags" href="/shopping/analytics/products"> Find products worth optimizing. </Card> <Card title="Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Keep optimized copy on-brand. </Card> </CardGroup> # Reddit engagement Source: https://docs.siftly.ai/shopping/content/reddit Discover relevant Reddit discussions and engage authentically to grow your brand's presence where shoppers and AI both look. <Frame> <img alt="Reddit engagement: discovered discussions and AI-drafted, on-brand replies with approval" /> </Frame> ## Overview Reddit is a frequent source for AI shopping recommendations and a place real shoppers research purchases. Reddit engagement surfaces discussions relevant to your brand and category and helps you take part authentically. ## Discovering opportunities The **Opportunities** view lists fresh Reddit posts that match your brand and topics but that you haven't engaged with yet, with the subreddit, engagement counts, and recency. Filter by topic and open any post to see the thread and a suggested reply. ## Engaging authentically Open a post to draft a reply. Siftly proposes an on-brand comment using a **persona** you've defined, which you review and approve before anything is posted. <Warning> Reddit communities value genuine participation. Always review drafts, add real value, and follow each subreddit's rules. Low-effort or promotional comments can harm your brand. </Warning> ## Staying on top of it The **Engaged** view tracks posts you've already commented on, so you can monitor replies and follow up. <Note> Reddit engagement, including personas and the approval workflow, is available on plans that include it. See [Plans & billing](/shopping/account/plans-billing). </Note> ## Related <CardGroup> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See when social sources shape AI recommendations. </Card> <Card title="Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Define the voice your replies use. </Card> <Card title="Content & optimization" icon="pen-nib" href="/shopping/content/overview"> Explore all the ways to grow presence. </Card> <Card title="Plans & billing" icon="rocket" href="/shopping/account/plans-billing"> Check which plans include Reddit engagement. </Card> </CardGroup> # Introduction Source: https://docs.siftly.ai/shopping/index Welcome to Siftly Shopping. Track and grow how your products appear in AI shopping answers like ChatGPT, Google AI Mode, and Perplexity. <img alt="Siftly Shopping dashboard: Share of Shelf, citations, and product visibility in AI shopping" /> <img alt="Siftly Shopping dashboard: Share of Shelf, citations, and product visibility in AI shopping" /> ## What is Siftly Shopping? Siftly Shopping is a **GEO for commerce** platform. It shows you how your products appear in AI shopping answers, and gives you the tools to win more of the shelf. When a shopper asks an AI assistant "what's the best running shoe for flat feet?" or "a good coffee grinder under \$100", the assistant doesn't return ten blue links. It returns a short, curated set of product recommendations. Your products are either on that shelf or they're invisible. Siftly Shopping measures exactly where you stand and helps you improve it. ## Why GEO for commerce matters Traditional ecommerce SEO optimizes for the search-results grid. **Generative Engine Optimization (GEO) for commerce** optimizes for the AI assistants that increasingly sit between shoppers and your catalog: ChatGPT Shopping, Google AI Mode, Google Shopping, and Perplexity. In an AI answer there is no page two. A handful of products get recommended, and the rest are unseen. Earning a place on that shelf depends on signals that are different enough from classic SEO to deserve their own strategy. **Siftly Shopping answers the questions that matter:** * Are my products showing up when shoppers ask AI for recommendations? * What's my Share of Shelf versus competitors, and is it trending up? * Which sources do AI engines cite, and how do I earn them? * What content, collections, and feed changes will actually improve my visibility? ## Core capabilities <CardGroup> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Measure your Share of Shelf, brand and product visibility, and competitive position across AI shopping platforms, sliced by product and geography. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See which domains and pages AI shopping engines cite when recommending products in your market, and find the sources worth earning. </Card> <Card title="Content & optimization" icon="pen-nib" href="/shopping/content/overview"> Generate grounded blog content and Collection Pages, and optimize product attributes for AI shopping, then publish straight to your store. </Card> <Card title="Integrations" icon="plug" href="/shopping/integrations/overview"> Connect Shopify, Google Merchant Center, Google Manufacturer Center, GA4, and Google Search Console to bring your catalog and analytics together. </Card> </CardGroup> ## Who is Siftly Shopping for? Siftly Shopping is built for teams that sell products and need to stay visible as shopping moves to AI: * **DTC and ecommerce brands** measuring how their catalog shows up in AI recommendations * **Shopify merchants** who want to optimize and publish without leaving their workflow * **Ecommerce and growth marketers** expanding strategy from search to generative shopping * **Brand and merchandising teams** tracking products, pricing, and shelf presence against competitors ## How it works ```mermaid theme={null} flowchart LR A[Connect your catalog] --> B[Analyze AI shelves] B --> C[Track Share of Shelf] C --> D[Optimize content & feeds] D --> B ``` 1. **Connect your catalog**: Link Shopify or Google Merchant Center (or add products manually) so Siftly knows what you sell. 2. **Analyze**: Siftly queries AI shopping engines with the prompts real shoppers ask in your market and records which products get recommended. 3. **Track**: Watch your Share of Shelf, reliability, and competitive position trend over time. 4. **Optimize**: Use content, Collection Pages, and product optimization to close gaps, then measure the lift on the next run. *** Ready to get started? [Set up Siftly Shopping →](/shopping/quickstart) # Cloudflare Source: https://docs.siftly.ai/shopping/integrations/cloudflare Connect Cloudflare AI Crawl Control to see which AI and search crawlers read your store, which pages they hit, and how often. <Frame> <img alt="Siftly Shopping connected to Cloudflare AI Crawl Control: AI and search crawler activity by bot and page" /> </Frame> ## Overview Connecting **Cloudflare AI Crawl Control** shows you which AI and search crawlers are visiting your store, which pages they hit, and how often. That covers ChatGPT (`GPTBot`, `ChatGPT-User`), Claude (`ClaudeBot`), Perplexity (`PerplexityBot`), Google (`Googlebot`, `Google-Extended`), and more. This is the raw signal behind your visibility in AI answers: it tells you whether AI assistants and AI-powered search are actually reading your product and content pages. Once connected, the data appears on your [Traffic](/shopping/analytics/traffic) dashboard. **Difficulty:** ⚠️ Medium. You route your domain through Cloudflare (a DNS change), then paste a read-only token into Siftly. Cloudflare's Free plan is all you need, at no cost. <Note> This integration is **read-only**. Siftly never changes your site, DNS, or crawler settings. It only reads aggregated crawler numbers, through a token you scope to a single domain's analytics. </Note> Cloudflare groups crawler activity into three types: | Activity type | What it is | Example bots | | ------------------------------- | ----------------------------------------------------------- | ---------------------------------------------- | | **AI Citations** (AI Assistant) | Crawlers that fetch a page to answer a user's question live | `ChatGPT-User`, `Claude-User`, `PerplexityBot` | | **AI Indexing** (AI Search) | Crawlers building an AI search index | `OAI-SearchBot`, `Claude-SearchBot` | | **AI Training** | Crawlers collecting data to train models | `GPTBot`, `ClaudeBot`, `CCBot` | *** ## How it works Cloudflare sits in front of your website as a reverse proxy. Every request to your store, including requests from AI crawlers, passes through Cloudflare's edge, where it is recorded in Cloudflare's analytics. Siftly reads those crawler analytics through a read-only Cloudflare API token that you generate. Because of this design, your domain has to be served through Cloudflare for there to be anything to read. If you don't have Cloudflare yet, most of this guide is about getting your domain onto Cloudflare first. The setup has four stages: 1. Create a free Cloudflare account. 2. Get your domain served through Cloudflare. This is the important step, and the method depends on your platform. 3. Create a read-only Analytics token and copy your Zone ID. 4. Paste them into Siftly under **Settings → Integrations → Cloudflare**. *** ## Prerequisites * Your ecommerce domain (for example `store.example.com` or `example.com`). * Access to wherever your domain's DNS is managed today, usually your domain registrar (GoDaddy, Namecheap, and similar) or your store platform's domain settings. * Admin access to your Siftly organization. * About 30–45 minutes. DNS changes can take a little while to propagate. *** ## Which path is yours? Getting your domain onto Cloudflare works differently depending on how your store is hosted. Find your situation, then follow the matching path in Stage 2. | Your setup | Can you change your domain's nameservers? | Path to follow | | -------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------- | | Custom domain on WooCommerce, BigCommerce, a headless store, or your own hosting | Yes, you control DNS at your registrar | **Path A** (standard onboarding) | | Shopify store on a custom domain (standard Liquid theme) | Partly; Shopify manages some records | **Path B** (Orange-to-Orange) | | Not sure | | Start with Path A. If your platform won't let you change nameservers, use Path B or ask Siftly support. | *** ## Stage 1: Create a free Cloudflare account <Steps> <Step title="Sign up"> Go to `dash.cloudflare.com/sign-up` and create an account with your work email, then verify the email. </Step> <Step title="Choose the Free plan"> The Free plan covers this integration in full. A paid plan only adds verified-bot naming and, at the Enterprise tier, per-request logs. Both are optional niceties (see [What to expect](#what-to-expect)). </Step> </Steps> *** ## Stage 2: Get your domain served through Cloudflare ### Path A: Standard onboarding (you control your DNS) Use this if your domain is registered at a normal registrar and you can change its nameservers. This is the common case for WooCommerce, BigCommerce, headless, and self-hosted stores. <Steps> <Step title="Add your site"> In the Cloudflare dashboard, click **Add a site** and enter your domain (for example `example.com`). Choose the **Free** plan when prompted. </Step> <Step title="Confirm the record is proxied"> Cloudflare scans your existing DNS records and shows them. Confirm that the record pointing at your store (usually an **A** or **CNAME** record for your root and `www`) is set to **Proxied**, shown as an orange cloud rather than grey. The orange cloud routes traffic through Cloudflare; a grey cloud means Cloudflare sees nothing. </Step> <Step title="Update your nameservers"> Cloudflare gives you two nameservers (for example `xxx.ns.cloudflare.com`). Log in to your registrar and replace your current nameservers with these two. </Step> <Step title="Wait for Active"> Wait for Cloudflare to confirm the domain is **Active**, usually minutes to a few hours. You'll get an email. Once the domain shows Active with an orange (proxied) record, crawler traffic starts flowing through Cloudflare and being recorded. Continue to Stage 3. </Step> </Steps> ### Path B: Orange-to-Orange for Shopify (Liquid) stores Shopify serves your storefront from its own edge, so you can't simply move nameservers the way Path A does. Instead, you place your own Cloudflare zone in front of Shopify with a proxied CNAME. Cloudflare calls this **Orange-to-Orange (O2O)**. Your Cloudflare zone records the crawler traffic before it reaches Shopify. <Steps> <Step title="Add your domain to Cloudflare"> Add the domain and point its nameservers at Cloudflare, exactly as in Path A. </Step> <Step title="Create a proxied CNAME"> In Cloudflare **DNS**, create a **proxied** (orange-cloud) **CNAME** for your storefront hostname pointing to `shops.myshopify.com`. </Step> <Step title="Set SSL to Full"> In **SSL/TLS → Overview**, set the encryption mode to **Full**. </Step> <Step title="Keep Shopify serving the store"> Keep your existing domain configured in your Shopify admin so Shopify continues to serve the store and issue its certificate. </Step> </Steps> <Warning> **Read these Shopify O2O landmines before you flip DNS:** * **Do not turn on "Always Use HTTPS" in Cloudflare.** It breaks Shopify's automatic SSL certificate renewal (the Let's Encrypt `/.well-known/acme-challenge/` check), which can take your store's HTTPS down. * **Checkout is not covered.** Cloudflare does not run on Shopify's `/checkout` path, so crawler activity there won't appear. This is expected and does not affect your product or content pages. * **Use SSL/TLS = Full**, not "Flexible," so the connection to Shopify stays encrypted. * **If crawler data is empty after setup**, the most common cause is a CNAME that isn't proxied (grey cloud instead of orange). If you aren't comfortable making these DNS changes, ask your developer or Siftly support before proceeding. A misconfigured O2O setup can briefly affect your live store. </Warning> *** ## Stage 3: Create a read-only token and copy your Zone ID Siftly needs two things from Cloudflare: your **Zone ID** (which domain to read) and a **read-only Analytics API token** (permission to read crawler numbers only). ### Copy your Zone ID <Steps> <Step title="Open your domain"> In the Cloudflare dashboard, click your domain. </Step> <Step title="Copy the Zone ID"> On the **Overview** page, look in the right-hand sidebar under **API**. Copy the **Zone ID**, a 32-character string like `0528d34ebf7f5f8a1c2d3e4f5a6b7c8d`. </Step> </Steps> ### Create the API token <Steps> <Step title="Start a custom token"> Go to **My Profile → API Tokens → Create Token**, then **Create Custom Token**. </Step> <Step title="Name it"> Give it a name, for example `siftly-ai-crawl-readonly`. </Step> <Step title="Add one permission"> Under **Permissions**, add exactly one: **Zone → Analytics → Read**. That's the only permission needed. "Logs Read" is not required. </Step> <Step title="Scope it to your domain"> Under **Zone Resources**, choose **Include → Specific zone → your domain**. </Step> <Step title="Create and copy"> Create the token and copy it now. Cloudflare shows it only once. </Step> </Steps> <Note> **Why this is safe:** the token is read-only and scoped to a single zone's analytics. It can't change your site, DNS, security, or crawler settings, and it can't touch any other domain in your account. Siftly stores it encrypted. </Note> *** ## Stage 4: Connect in Siftly <Steps> <Step title="Open Integrations"> In Siftly, open **Settings → Integrations**. </Step> <Step title="Connect Cloudflare"> Find the **Cloudflare** card and click **Connect**. </Step> <Step title="Paste your details"> In the **Connect Cloudflare** dialog, paste: * **Zone ID** (from Stage 3) * **API token** (from Stage 3) * **Zone name** (optional, for example `store.example.com`, used for display only) Then click **Connect Cloudflare**. </Step> </Steps> Siftly validates the token with a small test query. If it succeeds, the integration flips to **Connected**, does a first data pull right away, then refreshes hourly. A confirmation message tells you whether your plan supports verified-bot naming or user-agent detection. Both work fine. *** ## What you'll see after connecting The crawler data lands on your [Traffic](/shopping/analytics/traffic) dashboard: * **Overview tab.** Crawler Activity trend charts split by AI Citations, AI Indexing, and AI Training, plus a per-bot breakdown. A Platforms table lists every AI system that visited, by category, with change-versus-previous-period arrows. * **Pages tab.** Top Crawled Pages ranked by crawler requests, with each bar broken down by bot; Pages by Crawler, where you pick a bot and see which pages it hits; and a Platform-to-Page Journey view alongside a Published Articles table that combines crawler, AI-referral, and Search Console data. * **Logs tab.** A per-request crawler log for the last 24 hours. This tab needs a Cloudflare Enterprise plan. On Free, Pro, and Business plans you'll see the aggregated data on the Overview and Pages tabs instead. *** ## What to expect | Expectation | Detail | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Not real-time** | Cloudflare's analytics lag by a few minutes, and Siftly refreshes hourly. This is a reporting view, not a live feed. | | **History starts at connection** | There is no backfill of past crawler activity. Data accumulates from the moment you connect, so connect early. | | **Hourly aggregates** | On Free, Pro, and Business plans, data is hourly totals per bot and page, not individual request logs. That's normal and enough for trend analysis. | | **Bot detection** | On the Free plan, crawlers are identified by their user-agent string. Cloudflare's paid Bot Management adds verified-bot confirmation. Both are supported; user-agent detection is the standard baseline. | | **Per-request logs** | The Logs tab requires a Cloudflare Enterprise plan. Everything else works on Free. | *** ## Troubleshooting <AccordionGroup> <Accordion title="'Token was rejected' or 'Reconnect required'"> The token is wrong, expired, or lacks **Zone → Analytics → Read**. Re-issue the token (Stage 3) and reconnect. </Accordion> <Accordion title="Connected, but no crawler data"> Your domain probably isn't proxied. Check that the DNS record (or O2O CNAME) shows an orange cloud, and that the domain is **Active** in Cloudflare. Also give real crawlers time to visit. </Accordion> <Accordion title="Wrong domain's data"> The Zone ID belongs to a different domain. Copy the Zone ID from the correct domain's Overview page (Stage 3). </Accordion> <Accordion title="Bot names show as user-agent, not 'verified'"> Expected on plans without Bot Management. No action needed; detection still works. </Accordion> <Accordion title="Logs tab is empty"> Per-request logs need Cloudflare Enterprise. Use the Overview and Pages tabs instead. </Accordion> <Accordion title="Numbers look lower than Cloudflare's own dashboard"> Small differences are expected, because Siftly focuses on a curated set of AI and search bots. Large gaps usually mean the domain was only recently proxied, or history is still building. </Accordion> </AccordionGroup> *** ## FAQ <AccordionGroup> <Accordion title="Do I have to pay Cloudflare?"> No. The Free plan covers this integration. </Accordion> <Accordion title="Will moving to Cloudflare change my store or slow it down?"> Cloudflare acts as a proxy and CDN and typically speeds sites up. The risk to watch is DNS or SSL misconfiguration, so follow the SSL notes above (especially the Shopify O2O warnings) and test your store right after the switch. </Accordion> <Accordion title="Can Siftly change anything on my Cloudflare account?"> No. The token is read-only and scoped to a single zone's analytics. </Accordion> <Accordion title="How do I disconnect?"> Go to **Settings → Integrations → Cloudflare** and disconnect. This removes the stored token; data already pulled remains. </Accordion> </AccordionGroup> *** ## Glossary | Term | Meaning | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | **Zone** | A single domain in Cloudflare (for example `example.com`). | | **Zone ID** | The 32-character identifier for that domain. | | **Proxied (orange cloud)** | Traffic for that DNS record routes through Cloudflare, which this integration requires. A grey cloud means DNS-only, and Cloudflare sees nothing. | | **Orange-to-Orange (O2O)** | Placing your own Cloudflare zone in front of a platform (like Shopify) that already runs its own Cloudflare, using a proxied CNAME. | | **AI Crawl Control** | Cloudflare's view of AI and search crawler traffic, which this integration reads. | <Note> Questions, or a non-standard hosting setup? Contact Siftly support before changing DNS if you're unsure. A bad DNS or SSL change can briefly affect your live store. </Note> *** ## Related <CardGroup> <Card title="Traffic" icon="chart-line" href="/shopping/analytics/traffic"> See crawler activity alongside AI referral and organic traffic. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See which sources AI engines cite when recommending products. </Card> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Compare every integration and what each one powers. </Card> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Connect crawler coverage to shelf presence. </Card> </CardGroup> # Google Analytics 4 Source: https://docs.siftly.ai/shopping/integrations/ga4 Connect Google Analytics 4 (GA4) to measure how much traffic AI assistants send to your store and which pages they reach. <Frame> <img alt="Siftly Shopping connected to Google Analytics 4: AI-assistant referral traffic" /> </Frame> ## Overview Connecting **Google Analytics 4 (GA4)** lets Siftly Shopping show how much traffic AI assistants, like ChatGPT and Perplexity, send to your store, and which pages they land on. It closes the loop between AI visibility and real visits. **Difficulty:** ✅ Easy. Read-only Google OAuth, then pick your GA4 property. <Note> This integration is **read-only**. Siftly never writes to your analytics. It only reads reports. </Note> *** ## Prerequisites * A Google Analytics 4 property with data flowing * A Google user with access to that property *** ## Connecting <Steps> <Step title="Start the connection"> Go to **Settings → Integrations** and click **Connect** next to **Google Analytics 4**. </Step> <Step title="Authorize with Google"> Sign in with the Google account that has access to your GA4 property and approve read-only access. </Step> <Step title="Pick your property"> Choose the GA4 property to connect. Siftly binds to it and starts reading reports. </Step> </Steps> *** ## What it powers Once connected, GA4 data appears on the [Traffic](/shopping/analytics/traffic) page: * Sessions, users, and engagement, with period-over-period change * **AI referral traffic** broken down by assistant (ChatGPT, Perplexity, and others) * Your top pages by AI-assistant traffic *** ## Reconnecting and disconnecting * **Reconnect**: If access expires, the GA4 card shows a reconnect prompt; re-authorize with Google. * **Disconnect**: Go to **Settings → Integrations → Google Analytics 4** and click **Disconnect** to remove stored credentials. *** ## Troubleshooting <AccordionGroup> <Accordion title="No properties appear after authorizing"> The Google account you used may not have access to a GA4 property. Sign in with an account that does, or have an admin grant access, then reconnect. </Accordion> <Accordion title="AI referral traffic looks low or empty"> AI-assistant referrals only appear once shoppers actually arrive from those assistants. Coverage grows as your AI visibility improves and as assistants pass referrer information. </Accordion> </AccordionGroup> *** ## Related <CardGroup> <Card title="Traffic" icon="chart-line" href="/shopping/analytics/traffic"> See AI referral and organic traffic together. </Card> <Card title="Google Search Console" icon="magnifying-glass" href="/shopping/integrations/google-search-console"> Add organic search performance. </Card> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Compare every integration and what each one powers. </Card> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Correlate traffic gains with shelf gains. </Card> </CardGroup> # Google Manufacturer Center Source: https://docs.siftly.ai/shopping/integrations/google-manufacturer-center Connect Google Manufacturer Center (GMfC) to publish authoritative, brand-owned product attributes that enrich how your products appear in Google. <Frame> <img alt="Siftly Shopping connected to Google Manufacturer Center: brand-owned attributes published to Google" /> </Frame> ## Overview **Google Manufacturer Center (GMfC)** lets brand owners publish authoritative product information (materials, certifications, care instructions, features, and richer descriptions) straight to Google. Connecting it lets Siftly Shopping enrich your products with these manufacturer attributes and publish them on your behalf. **Difficulty:** ⚠️ Medium. Connect with Google OAuth, then map your data to GMfC's attribute fields. <Warning> Google Manufacturer Center (**GMfC**) is **not** the same as Google Merchant Center (**GMC**). GMC is your product feed; GMfC is for brand-owned manufacturer attributes. Don't confuse the two. See [Google Merchant Center](/shopping/integrations/google-merchant-center). </Warning> *** ## Prerequisites * A Google Manufacturer Center account * One or more brands **registered and approved** in Manufacturer Center * A Google user with access to that account *** ## Connecting <Steps> <Step title="Start the connection"> Go to **Settings → Integrations** and click **Connect** next to **Google Manufacturer Center**. You'll be redirected to Google to authorize access. </Step> <Step title="Authorize with Google"> Sign in with the Google account that manages Manufacturer Center and approve access. </Step> <Step title="Bind your account"> Choose the Manufacturer Center account to connect. Siftly binds to it and loads your **approved brands**: the brands Google has authorized you to publish attributes for. </Step> </Steps> You can refresh your approved-brands list any time from the GMfC card in **Settings → Integrations**. *** ## Field mapping GMfC has its own set of attribute fields. The **field-mapping editor** controls how Siftly's product data maps to those fields. * Siftly ships with sensible **default mappings** out of the box. * You can **override** any mapping for your organization to match how your catalog is structured. Open the editor at **Settings → Integrations → Google Manufacturer Center → Field mapping**. <Tip> Start with the defaults and only override the fields where your data lives somewhere non-standard. You don't need to map everything to get value. </Tip> *** ## Publishing attributes Manufacturer attributes are produced and submitted through [Product Optimization](/shopping/content/product-optimization). When a product belongs to an approved brand, Siftly writes the mapped attributes to Manufacturer Center for the relevant languages and countries. <Note> A product can only be published to GMfC if its brand is approved in your Manufacturer Center account. Products whose brands aren't approved are skipped until approval comes through. </Note> *** ## Reconnecting and disconnecting * **Reconnect**: If access expires, the GMfC card shows a reconnect prompt; re-authorize with Google. * **Disconnect**: Go to **Settings → Integrations → Google Manufacturer Center** and click **Disconnect**. This removes stored credentials; attributes already published to Google remain. *** ## Troubleshooting <AccordionGroup> <Accordion title="No approved brands appear"> Your brand may not be registered or approved in Manufacturer Center yet. Register it in Google Manufacturer Center; approval can take time. Refresh the approved-brands list once it's granted. </Accordion> <Accordion title="Attributes aren't publishing for a product"> Confirm the product's brand is in your approved-brands list and that the relevant fields are mapped in the field-mapping editor. </Accordion> <Accordion title="The wrong field is being populated"> Open the field-mapping editor and override the default mapping for that field to point at the correct source in your catalog. </Accordion> </AccordionGroup> *** ## Related <CardGroup> <Card title="Google Merchant Center" icon="google" href="/shopping/integrations/google-merchant-center"> Connect your product feed for Google Shopping. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Generate and submit manufacturer attributes. </Card> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Compare every integration and what each one powers. </Card> <Card title="Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Ground attribute generation in your brand's facts and voice. </Card> </CardGroup> # Google Merchant Center Source: https://docs.siftly.ai/shopping/integrations/google-merchant-center Connect Google Merchant Center (GMC) to sync your product feed into Siftly Shopping and push optimized product data back to Google. <Frame> <img alt="Siftly Shopping connected to Google Merchant Center: product feed in, optimized attributes out" /> </Frame> ## Overview **Google Merchant Center (GMC)** is your product feed for Google's shopping surfaces. Connecting it lets Siftly Shopping read your feed for analysis and push **optimized product attributes** back to Google. **Difficulty:** ✅ Easy. Connect with secure Google OAuth, then pick your Merchant Center account. <Note> Google Merchant Center (GMC) is for your product feed. It is different from **Google Manufacturer Center (GMfC)**, which is for brand-owned manufacturer attributes. Many brands connect both. See [Google Manufacturer Center](/shopping/integrations/google-manufacturer-center). </Note> *** ## Prerequisites * A Google Merchant Center account with at least one product feed * A Google user with access to that Merchant Center account *** ## Connecting <Steps> <Step title="Start the connection"> Go to **Settings → Integrations** and click **Connect** next to **Google Merchant Center**. You'll be redirected to Google to authorize access. </Step> <Step title="Authorize with Google"> Sign in with the Google account that manages your Merchant Center and approve the requested access. Google redirects you back to Siftly. </Step> <Step title="Choose your Merchant Center account"> Siftly shows the Merchant Center accounts you can access. Select the one you want to connect. </Step> <Step title="Your products sync"> Siftly imports your product feed in the background and links it to your tracked catalog. </Step> </Steps> *** ## What Siftly imports Once connected, Siftly reads your GMC product feed (titles, descriptions, attributes, and identifiers) and uses it to enrich your tracked products and to power [Product Optimization](/shopping/content/product-optimization). You can re-sync at any time from the GMC card in **Settings → Integrations**. *** ## Pushing optimized data back to Google GMC is also a **publish destination**. When you run [Product Optimization](/shopping/content/product-optimization), Siftly writes your optimized attributes to Google through a supplemental data source: a separate feed that layers your improvements on top of your primary feed without overwriting it. <Tip> Using a supplemental data source means your original feed stays intact. You can review what Siftly proposes before it's submitted, and roll back from the optimization job's version history. </Tip> *** ## Reconnecting and disconnecting * **Reconnect**: If access expires or permissions change, the GMC card shows a reconnect prompt. Click **Reconnect** and re-authorize with Google. * **Disconnect**: Go to **Settings → Integrations → Google Merchant Center** and click **Disconnect**. This removes stored credentials; it does not delete data already in your Merchant Center. *** ## Troubleshooting <AccordionGroup> <Accordion title="No Merchant Center accounts appear after authorizing"> The Google account you used may not have access to a Merchant Center account. Sign in with an account that manages your GMC, or have an admin grant you access, then reconnect. </Accordion> <Accordion title="Products aren't syncing"> Confirm your Merchant Center has an active product feed. Re-sync from the GMC card; large feeds can take a few minutes. </Accordion> <Accordion title="Optimized attributes aren't showing in Google"> Supplemental data sources can take time to process on Google's side. Check the optimization job's status and your Merchant Center's feed processing. </Accordion> </AccordionGroup> *** ## Related <CardGroup> <Card title="Google Manufacturer Center" icon="google" href="/shopping/integrations/google-manufacturer-center"> Publish brand-owned manufacturer attributes. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Optimize product data and submit it to GMC. </Card> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Compare every integration and what each one powers. </Card> <Card title="Products & readiness" icon="tags" href="/shopping/analytics/products"> See how ready each product is to win in AI shopping. </Card> </CardGroup> # Google Search Console Source: https://docs.siftly.ai/shopping/integrations/google-search-console Connect Google Search Console (GSC) to track organic search clicks, impressions, CTR, and average position alongside your AI visibility. <Frame> <img alt="Siftly Shopping connected to Google Search Console: organic search performance" /> </Frame> ## Overview Connecting **Google Search Console (GSC)** brings your organic search performance (clicks, impressions, click-through rate, and average position) alongside your AI visibility, so you can see both channels in one place. **Difficulty:** ✅ Easy. Read-only Google OAuth, then pick your site. <Note> This integration is **read-only**. Siftly only reads your Search Console reports. </Note> *** ## Prerequisites * A verified site in Google Search Console * A Google user with access to that site *** ## Connecting <Steps> <Step title="Start the connection"> Go to **Settings → Integrations** and click **Connect** next to **Google Search Console**. </Step> <Step title="Authorize with Google"> Sign in with the Google account that has access to your Search Console and approve read-only access. </Step> <Step title="Pick your site"> Choose the verified site to connect. You can only connect sites your account already owns or manages in Search Console. </Step> </Steps> *** ## What it powers Once connected, GSC data appears on the [Traffic](/shopping/analytics/traffic) page: * Organic clicks and impressions over time * Click-through rate and average position * Top queries and pages driving organic search *** ## Reconnecting and disconnecting * **Reconnect**: If access expires, the GSC card shows a reconnect prompt; re-authorize with Google. * **Disconnect**: Go to **Settings → Integrations → Google Search Console** and click **Disconnect** to remove stored credentials. *** ## Troubleshooting <AccordionGroup> <Accordion title="No sites appear after authorizing"> Your Google account must have access to a verified Search Console site. Verify the site in Search Console or have an admin grant you access, then reconnect. </Accordion> <Accordion title="Data looks delayed"> Search Console data is typically a couple of days behind. Recent days may be incomplete until Google finalizes them. </Accordion> </AccordionGroup> *** ## Related <CardGroup> <Card title="Traffic" icon="chart-line" href="/shopping/analytics/traffic"> See organic and AI referral traffic together. </Card> <Card title="Google Analytics 4" icon="chart-line" href="/shopping/integrations/ga4"> Add AI-assistant referral traffic. </Card> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Compare every integration and what each one powers. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> See which sources AI engines cite in your market. </Card> </CardGroup> # Integrations overview Source: https://docs.siftly.ai/shopping/integrations/overview Connect Siftly Shopping to Shopify, Google Merchant Center, Google Manufacturer Center, GA4, Google Search Console, and Cloudflare. <Frame> <img alt="Siftly Shopping integrations: Shopify, Google Merchant Center, Manufacturer Center, GA4, Search Console, and Cloudflare" /> </Frame> ## Overview Integrations are how Siftly Shopping gets your data in and pushes your improvements back out. Some bring your **catalog and feeds** into Siftly; others let you **publish** content and product updates; and others add **analytics**, from visitor traffic to AI crawler activity, so you can connect AI visibility to what actually reaches your store. ## Supported integrations <CardGroup> <Card title="Shopify" icon="shopify" href="/shopping/integrations/shopify"> Sync your catalog and publish blog posts, Collection Pages, and product updates. </Card> <Card title="Google Merchant Center" icon="google" href="/shopping/integrations/google-merchant-center"> Sync your product feed and push optimized attributes back to Google. </Card> <Card title="Google Manufacturer Center" icon="google" href="/shopping/integrations/google-manufacturer-center"> Publish authoritative, brand-owned manufacturer attributes. </Card> <Card title="Google Analytics 4" icon="chart-line" href="/shopping/integrations/ga4"> Measure AI-assistant referral traffic to your store. </Card> <Card title="Google Search Console" icon="magnifying-glass" href="/shopping/integrations/google-search-console"> Track organic search clicks, impressions, and position. </Card> <Card title="Cloudflare" icon="cloudflare" href="/shopping/integrations/cloudflare"> See which AI and search crawlers read your store, by bot and page. </Card> </CardGroup> ## At a glance | Integration | Direction | Auth | Powers | | ------------------------------ | -------------- | ----------------- | ------------------------------------------------------------------------- | | **Shopify** | In + out | OAuth / App Store | Catalog sync, publishing | | **Google Merchant Center** | In + out | Google OAuth | Feed sync, [Product Optimization](/shopping/content/product-optimization) | | **Google Manufacturer Center** | Out | Google OAuth | Manufacturer attributes | | **Google Analytics 4** | In (read-only) | Google OAuth | [Traffic](/shopping/analytics/traffic) | | **Google Search Console** | In (read-only) | Google OAuth | [Traffic](/shopping/analytics/traffic) | | **Cloudflare** | In (read-only) | API token | [Traffic](/shopping/analytics/traffic) crawler activity | ## How connecting works <Steps> <Step title="Open Integrations"> Go to **Settings → Integrations**. Each integration has a card showing its connection status. </Step> <Step title="Authorize"> Click **Connect** and complete the secure OAuth flow (or install from the Shopify App Store). You never share a password with Siftly. </Step> <Step title="Pick your account"> For the Google integrations, choose the specific account, property, or site to connect. </Step> <Step title="Sync and use"> Siftly syncs in the background, and the integration begins powering the dashboards and tools above. </Step> </Steps> <Tip> Some traffic-tracking flows reference your **Organization ID**, found under **Settings → Organization**. Match whatever label your dashboard shows. </Tip> ## Related <CardGroup> <Card title="Quickstart" icon="rocket" href="/shopping/quickstart"> Connect your catalog and run your first analysis. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Optimize products and submit them to Google. </Card> </CardGroup> # Shopify Source: https://docs.siftly.ai/shopping/integrations/shopify Connect your Shopify store to sync your catalog and publish blog posts, Collection Pages, and product updates directly from Siftly Shopping. <Frame> <img alt="Siftly Shopping connected to Shopify: catalog sync in, content and product updates out" /> </Frame> ## Overview Shopify is the deepest integration in Siftly Shopping. It does two jobs: it **syncs your catalog in** (products, variants, images, and collections) and it lets you **publish back out** (blog posts, Collection Pages, and optimized product data), without leaving Siftly. **Difficulty:** ✅ Easy. Connect in a few clicks with secure OAuth. No code, no API keys. There are two ways to connect, depending on how you found Siftly: | Connection path | Who it's for | | ----------------------------- | ------------------------------------------------------------- | | **OAuth from Siftly** | You signed up at app.siftly.ai and want to connect your store | | **Shopify App Store install** | You installed Siftly Shopping from the Shopify App Store | *** ## Prerequisites * A Shopify store * A user with permission to install apps and approve access on that store *** ## Connecting from Siftly (OAuth) <Steps> <Step title="Start the connection"> Go to **Settings → Integrations** and click **Connect** next to **Shopify**. Enter your store's `your-store.myshopify.com` domain. </Step> <Step title="Approve access"> You'll be redirected to Shopify to review the permissions Siftly requests. Click **Install** to approve. You never share a password with Siftly. </Step> <Step title="Your catalog syncs"> Shopify redirects you back to Siftly and your catalog begins syncing in the background. You'll see a live count as products come in. </Step> </Steps> *** ## Connecting from the Shopify App Store When you install Siftly Shopping from the App Store, Shopify sends you to Siftly to finish setup. If you aren't signed in yet, Siftly remembers your store and **claims** it once you create or sign in to your organization. <Steps> <Step title="Install from the Shopify App Store"> Find **Siftly Shopping** in the Shopify App Store and click **Install**. </Step> <Step title="Finish setup in Siftly"> Shopify hands you off to Siftly. Sign in or create your organization, and Siftly automatically attaches (claims) your store to it. </Step> <Step title="Your catalog syncs"> Once claimed, your catalog syncs in the background, just like the OAuth path. </Step> </Steps> <Note> If your store isn't attached automatically (for example, you closed the tab mid-signup), open **Settings → Integrations** and finish the connection, or revisit the claim link Shopify provided. </Note> *** ## What Siftly syncs | Data | Notes | | --------------- | ---------------------------------------------------------------------------------------------- | | **Products** | Title, description, type, vendor, tags, and status | | **Variants** | Options, SKUs, and prices per variant | | **Images** | Product and media-library images, available in the content image picker | | **Collections** | Existing collections, used to detect [Collection Page](/shopping/content/collections) coverage | | **Metafields** | Read for context and written when you publish, where applicable | Sync runs in the background after connecting and refreshes as your catalog changes. *** ## Publishing from Siftly Once connected, Siftly can publish back to your store: * **Blog posts** → your Shopify blog. See [Content](/shopping/content/blog). * **Collection Pages** → Shopify collections, published to your Online Store. See [Collection Pages](/shopping/content/collections). * **Optimized product data** → submitted through Google Merchant Center and Manufacturer Center. See [Product Optimization](/shopping/content/product-optimization). Every publish action lets you choose **Draft** (review in Shopify first) or **Published** (go live immediately). *** ## Permissions and reconnecting Siftly requests only the scopes it needs to sync your catalog and publish on your behalf. Occasionally Shopify introduces a new permission requirement; when that happens Siftly shows a **Reconnect required** prompt on the Shopify integration card. <Warning> If you see a missing-scopes or reconnect prompt, publishing is paused until you reconnect. Go to **Settings → Integrations → Shopify** and click **Reconnect** to approve the updated permissions. </Warning> To switch stores, disconnect and reconnect with the new store's domain. *** ## Data and privacy Siftly honors Shopify's mandatory privacy webhooks (customer data request, customer redact, and shop redact). When you uninstall the app from Shopify, Siftly stops syncing your store. To disconnect from Siftly: go to **Settings → Integrations → Shopify** and click **Disconnect**. This removes your stored credentials; it does not affect content already published to your store. *** ## Troubleshooting <AccordionGroup> <Accordion title="My store wasn't attached after installing from the App Store"> Sign in to Siftly and open **Settings → Integrations**. If the store is pending, finish the connection there. If it still doesn't attach, reconnect via OAuth using your `myshopify.com` domain. </Accordion> <Accordion title="'Reconnect required' on the Shopify card"> Shopify added a permission requirement since you connected. Click **Reconnect** and approve the updated scopes. Publishing resumes immediately afterward. </Accordion> <Accordion title="Products aren't appearing"> The initial sync runs in the background and can take a few minutes for large catalogs. If products still don't appear, reconnect the integration to re-trigger a sync. </Accordion> <Accordion title="Publish failed: blog or collection not found"> Make sure your store has at least one blog (for posts) and that the integration has the scopes to write collections. Reconnect if you recently changed store settings. </Accordion> </AccordionGroup> *** ## Related <CardGroup> <Card title="Integrations overview" icon="plug" href="/shopping/integrations/overview"> Compare every integration and what each one powers. </Card> <Card title="Collection Pages" icon="layer-group" href="/shopping/content/collections"> Generate and publish Shopify collection pages. </Card> <Card title="Content" icon="pen-nib" href="/shopping/content/blog"> Generate blog posts and publish them to Shopify. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Optimize product data and submit it to Google. </Card> </CardGroup> # Knowledge Hub Source: https://docs.siftly.ai/shopping/knowledge-hub/overview Build your Brand Kit (Brand DNA, Facts, and Voice) that grounds every piece of content Siftly Shopping generates. <Frame> <img alt="Knowledge Hub: a Brand Kit with Brand DNA, Brand Facts, and Brand Voice" /> </Frame> ## Overview The Knowledge Hub is where Siftly learns your brand. From your website (and any brand guidelines you upload), it builds a structured **Brand Kit** that every generator ([Content](/shopping/content/blog), [Collection Pages](/shopping/content/collections), and [Product Optimization](/shopping/content/product-optimization)) uses to stay on-brand and grounded. Build it once, and everything Siftly writes sounds like you and sticks to the facts. *** ## What's in a Brand Kit <AccordionGroup> <Accordion title="Brand DNA"> Your brand's identity and style: who you are, what you stand for, your tone and writing patterns, editorial preferences, and visual signature. This is the stylistic ground truth for generated content. </Accordion> <Accordion title="Brand Facts"> Verifiable claims about your brand and products, extracted and stored so generators can cite them. Brand Facts keep content specific and defensible instead of generic. </Accordion> <Accordion title="Brand Voice"> The rules content must follow: your editorial stance, phrases to prefer or avoid, limits on brand mentions and calls to action, and any required disclosures. </Accordion> </AccordionGroup> *** ## Generating your Brand Kit <Steps> <Step title="Open the Knowledge Hub"> Go to **Knowledge Hub** and click **Generate**. </Step> <Step title="Add your sources"> Enter your brand's homepage URL. Optionally upload a brand-guidelines file (your "brand bible") as extra ground truth. </Step> <Step title="Generate"> Siftly crawls your site, extracts your DNA, Facts, and Voice, and assembles the kit. This usually takes a minute or two. </Step> </Steps> Each run produces a versioned **kit**. The latest completed kit becomes the one Siftly uses everywhere. *** ## Editing your kit Open a kit to review and refine it. The Brand DNA detail view breaks the kit into editable sections (identity, writing style, editorial patterns, calls to action, visual signature, and sample references) so you can correct anything the extraction got wrong before it shapes your content. *** ## How it powers the rest of Siftly * **Content** uses your DNA and Voice for tone, and your Facts to ground claims. * **Collection Pages** follow your editorial rules when writing descriptions and rationale. * **Product Optimization** keeps optimized copy within your brand's voice constraints. *** ## Keeping it fresh <Note> Regenerate your Brand Kit when your brand, positioning, or website changes significantly. Siftly always uses your most recent completed kit, so a refresh updates every generator at once. </Note> *** ## Related <CardGroup> <Card title="Content" icon="pen-nib" href="/shopping/content/blog"> Generate grounded blog posts. </Card> <Card title="Collection Pages" icon="layer-group" href="/shopping/content/collections"> Build AI-ready Shopify collection pages. </Card> <Card title="Product Optimization" icon="wand-magic-sparkles" href="/shopping/content/product-optimization"> Optimize product data within your brand voice. </Card> <Card title="Quickstart" icon="rocket" href="/shopping/quickstart"> New to Siftly Shopping? Start here. </Card> </CardGroup> # Quickstart Source: https://docs.siftly.ai/shopping/quickstart Connect your catalog and read your first Share of Shelf in about 15 minutes. <Frame> <img alt="Siftly Shopping setup: from connecting your catalog to your first Share of Shelf" /> </Frame> ## Prerequisites Before you begin, make sure you have: * A Siftly Shopping account ([get started](https://app.siftly.ai/sign-up)) * Your store on **Shopify** or **Google Merchant Center** (or a list of products to add manually) * A sense of the markets and use cases your products compete in *** ## Step 1: Create your organization When you first sign in, Siftly walks you through creating an **organization**, your workspace, which holds your brand, products, team, and subscription. Enter your company name and website, then continue. <Tip> If you manage multiple brands or clients, create one organization per brand. Each organization has isolated data, users, and billing. </Tip> *** ## Step 2: Connect your catalog Siftly needs to know what you sell. Choose the source that matches your store: | Source | Best for | What Siftly imports | | -------------------------- | ------------------------------------ | ------------------------------------------- | | **Shopify** | Shopify merchants | Products, variants, images, and collections | | **Google Merchant Center** | Anyone running Google Shopping feeds | Your product feed and performance data | | **Website** | Stores on other platforms | Products you add manually | Connecting **Shopify** or **Google Merchant Center** uses a secure OAuth flow, so you never share a password with Siftly. After you authorize, Siftly syncs your catalog in the background. You'll see a live count as products come in. <Note> You can connect more integrations later from **Settings → Integrations**. See the [integrations overview](/shopping/integrations/overview) for everything Siftly Shopping connects to. </Note> *** ## Step 3: Select your products From your synced catalog, pick the **1–5 products** you want to track first. Siftly de-duplicates variants and shows one row per product, so you choose the items that matter most. You can add or remove tracked products later from the [Products](/shopping/analytics/products) page. *** ## Step 4: Review your prompts Siftly generates a set of **prompts** for your selected products: the kinds of questions real shoppers ask AI assistants in your market, pairing category needs with shopper personas. Review the suggestions, edit any that don't fit, and continue. These prompts are what Siftly runs against AI shopping engines to measure your presence. *** ## Step 5: Launch analysis and read your Share of Shelf With your products and prompts set, Siftly runs its first analysis, querying AI shopping engines and recording which products get recommended. The first run typically completes in a few minutes. When it's done, head to your dashboard and explore: <CardGroup> <Card title="Dashboard" icon="gauge" href="/shopping/analytics/overview"> Your headline metrics (appearances, reliability, and top-3 rank) at a glance. </Card> <Card title="Visibility & Share of Shelf" icon="store" href="/shopping/analytics/visibility"> Your Share of Shelf and competitive position, sliced by product and geography. </Card> <Card title="Citations" icon="quote-left" href="/shopping/analytics/citations"> The sources AI engines cited when recommending products in your market. </Card> <Card title="Conversations" icon="comments" href="/shopping/analytics/conversations"> The exact prompts and AI responses behind your metrics. </Card> </CardGroup> *** ## What's next? <CardGroup> <Card title="Build your Knowledge Hub" icon="book" href="/shopping/knowledge-hub/overview"> Generate your Brand Kit so every piece of content Siftly creates stays on-brand and grounded. </Card> <Card title="Connect analytics" icon="chart-line" href="/shopping/analytics/traffic"> Add GA4 and Google Search Console to see AI-assistant referral traffic and organic performance. </Card> <Card title="Generate content" icon="pen-nib" href="/shopping/content/overview"> Turn your shelf gaps into blog content, Collection Pages, and optimized products. </Card> <Card title="Choose a plan" icon="rocket" href="/shopping/account/plans-billing"> Compare plans and pick the one that fits your catalog and team. </Card> </CardGroup> # Cloudflare Worker Source: https://docs.siftly.ai/traffic-tracking/cloudflare Deploy a Cloudflare Worker that intercepts AI bot traffic at the edge and logs it to Siftly — works in front of any website regardless of tech stack. <Frame> <img alt="AI bot traffic detection — Cloudflare Worker intercepts AI crawler requests at the edge" /> </Frame> ## How It Works A Cloudflare Worker sits in front of your entire website. Every request passes through it before reaching your origin server. When an AI bot is detected by User-Agent, the Worker logs it to the traffic-ingest-service as a non-blocking background task (`ctx.waitUntil`), then passes the request through to your origin unchanged. Your real visitors never notice any difference. ## Setup <Steps> <Step title="Install the Wrangler CLI"> Wrangler is Cloudflare's official CLI for deploying Workers. ```bash theme={null} npm install -g wrangler ``` Then log in to your Cloudflare account: ```bash theme={null} wrangler login ``` </Step> <Step title="Create your Worker project"> Create a new directory for the Worker (or use the `cloudflare-wroker` folder from the downloaded files): ```bash theme={null} mkdir siftly-bot-tracker cd siftly-bot-tracker ``` </Step> <Step title="Create the Worker files"> **`worker.js`** — Copy the code below into this file: ```js worker.js theme={null} const AI_BOT_PATTERNS = [ // OpenAI — citations & training "OAI-SearchBot", "ChatGPT-User", "GPTBot", // Anthropic / Claude — citations & training "Claude-Web", "Claude-User", "ClaudeBot", "anthropic-ai", // Perplexity "PerplexityBot", "Perplexity-User", // Google / Gemini — citations & training "Googlebot", "Google-Extended", "Google-Gemini", // Microsoft / Bing "bingbot", "BingPreview", // Meta "Meta-ExternalAgent", "FacebookBot", // Others "Bytespider", "cohere-ai", "CCBot", // Traditional search "YouBot", "DuckDuckBot", "Baiduspider", ]; // 👇 Replace with your traffic-ingest-service URL const LOG_ENDPOINT = "<TRAFFIC_INGEST_SERVICE_URL>/log/cloudflare"; // 👇 Replace with your Organisation ID from the Siftly dashboard const ORGANIZATION_ID = "<YOUR_ORGANIZATION_ID>"; export default { async fetch(request, env, ctx) { const userAgent = request.headers.get("user-agent") || ""; const isBot = AI_BOT_PATTERNS.some(bot => userAgent.toLowerCase().includes(bot.toLowerCase()) ); if (isBot) { const payload = { timestamp: new Date().toISOString(), bot_ua: userAgent, url: request.url, method: request.method, ip: request.headers.get("cf-connecting-ip"), country: request.cf?.country, city: request.cf?.city, asn: request.cf?.asn, asOrganization: request.cf?.asOrganization, }; // Fire-and-forget — does not block the actual request ctx.waitUntil( fetch(LOG_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${ORGANIZATION_ID}`, }, body: JSON.stringify(payload), }).catch(() => {}) // silently fail if the service is unreachable ); } // Always pass the request through to the origin normally return fetch(request); }, }; ``` **`wrangler.toml`** — Worker configuration: ```toml wrangler.toml theme={null} name = "siftly-bot-tracker" main = "worker.js" compatibility_date = "2025-01-01" routes = [ { pattern = "yourdomain.com/*", zone_name = "yourdomain.com" } ] [vars] LOG_ENDPOINT = "<TRAFFIC_INGEST_SERVICE_URL>/log/cloudflare" # Replace with your Organisation ID from the Siftly dashboard ORGANIZATION_ID = "<YOUR_ORGANIZATION_ID>" # Comma-separated list of bot UA substrings to intercept. # Override here without touching worker.js. AI_BOT_PATTERNS = "OAI-SearchBot,ChatGPT-User,GPTBot,Claude-Web,Claude-User,ClaudeBot,anthropic-ai,PerplexityBot,Perplexity-User,Googlebot,Google-Extended,Google-Gemini,bingbot,BingPreview,Meta-ExternalAgent,FacebookBot,Bytespider,cohere-ai,CCBot,YouBot,DuckDuckBot,Baiduspider" ``` <Note> Replace `yourdomain.com` with your actual domain. The Worker will intercept all traffic matching this pattern. </Note> </Step> <Step title="Fill in your credentials"> In `wrangler.toml` under `[vars]`, replace: | Placeholder | Value | | ------------------------------ | ------------------------------------------------------------- | | `<TRAFFIC_INGEST_SERVICE_URL>` | The URL of the traffic-ingest-service (ask your Siftly admin) | | `<YOUR_ORGANIZATION_ID>` | Your Organisation ID UUID from the Siftly dashboard | Also replace `yourdomain.com` in the `routes` block with your actual domain. <Note> You can customise the `AI_BOT_PATTERNS` variable in `wrangler.toml` to add or remove bots without touching `worker.js`. </Note> </Step> <Step title="Deploy the Worker"> From the Worker directory, run: ```bash theme={null} wrangler deploy ``` Wrangler will upload the Worker to Cloudflare's edge network and activate the route. You should see output like: ``` Uploaded siftly-bot-tracker (1.23 sec) Published siftly-bot-tracker (0.42 sec) https://siftly-bot-tracker.your-account.workers.dev yourdomain.com/* ``` </Step> </Steps> ## Verifying It Works After deploying, simulate an AI bot request to confirm events flow through: ```bash theme={null} curl -A "GPTBot/1.0" https://yourdomain.com ``` Check the **Traffic** section of the Siftly dashboard within a few minutes. You should see an entry for the simulated GPTBot visit. ## Updating the Worker To change the endpoint URL or Organisation ID later: 1. Edit `worker.js` with the new values. 2. Run `wrangler deploy` again. Changes propagate globally within seconds. ## Troubleshooting <AccordionGroup> <Accordion title="Worker deployed but no events in Siftly"> 1. Confirm the route in `wrangler.toml` matches your domain exactly. 2. Visit [dash.cloudflare.com](https://dash.cloudflare.com) → **Workers & Pages** → your worker → **Logs** to see real-time request logs. 3. Check the `LOG_ENDPOINT` URL is correct and the service is reachable. 4. Test with `curl -A "GPTBot/1.0" https://yourdomain.com` from a terminal. </Accordion> <Accordion title="The Worker is interfering with my site"> The Worker calls `return fetch(request)` at the end, which proxies the request to your origin unchanged. If something looks wrong, check that you haven't modified this line. You can also add specific paths to an allowlist or denylist using the `matcher` pattern in `wrangler.toml`. </Accordion> <Accordion title="I need to track multiple domains"> Add multiple route entries to `wrangler.toml`: ```toml theme={null} routes = [ { pattern = "site1.com/*", zone_name = "site1.com" }, { pattern = "site2.com/*", zone_name = "site2.com" } ] ``` Each domain must be in your Cloudflare account. </Accordion> </AccordionGroup> # AI Bot Traffic Tracking Source: https://docs.siftly.ai/traffic-tracking/overview Track AI crawlers and bots visiting your website — see which AI engines are reading your content, how often, and from where. ## How It Works Siftly intercepts AI bot requests at the edge of your infrastructure — before they even reach your origin server — and logs them for analysis. <Frame> <img alt="AI bot traffic detection flow — from crawler request through edge integration to Siftly dashboard" /> </Frame> AI bots are identified by User-Agent strings. The integration is **fire-and-forget** — it never adds latency to real user page loads. ## Prerequisites Before setting up any integration you need your **Organisation ID**. Find it in the Siftly dashboard under **Settings → Organisation**. <Tip> Your Organisation ID looks like a UUID: `550e8400-e29b-41d4-a716-446655440000` </Tip> ## Choose Your Integration <CardGroup> <Card title="WordPress Plugin" icon="wordpress" href="/traffic-tracking/wordpress"> For self-hosted WordPress sites. Upload a ZIP, fill in two fields — done. </Card> <Card title="Vercel / Netlify Middleware" icon="code" href="/traffic-tracking/vercel-netlify"> One file added to any Next.js, SvelteKit, or Astro project. </Card> <Card title="Cloudflare Worker" icon="cloud" href="/traffic-tracking/cloudflare"> Runs at the edge in front of any website regardless of stack. </Card> </CardGroup> ## Detected Bots The following AI crawlers are tracked automatically: | Bot | Company | | ------------- | ------------ | | GPTBot | OpenAI | | ChatGPT-User | OpenAI | | ClaudeBot | Anthropic | | Claude-Web | Anthropic | | anthropic-ai | Anthropic | | Googlebot | Google | | bingbot | Microsoft | | PerplexityBot | Perplexity | | YouBot | You.com | | CCBot | Common Crawl | | Bytespider | ByteDance | | FacebookBot | Meta | | Applebot | Apple | | DuckDuckBot | DuckDuckGo | | Baiduspider | Baidu | # Vercel / Netlify Middleware Source: https://docs.siftly.ai/traffic-tracking/vercel-netlify Add a single middleware file to any Next.js, SvelteKit, Nuxt, or Astro project to track AI bot traffic. <Frame> <img alt="AI bot traffic detection — Vercel/Netlify middleware intercepts AI crawler requests" /> </Frame> ## How It Works Framework middleware intercepts every incoming request **before** your page code runs. When an AI bot is detected, the bot's metadata is sent to the traffic-ingest-service as a fire-and-forget background fetch — zero latency added to real user loads. ## Setup <Steps> <Step title="Create the middleware file"> Add the following file to the **root** of your project (same level as `package.json`): <CodeGroup> ```ts middleware.ts (Next.js) theme={null} import { NextRequest, NextResponse } from 'next/server'; const AI_BOT_PATTERNS = [ // OpenAI — citations & training 'OAI-SearchBot', 'ChatGPT-User', 'GPTBot', // Anthropic / Claude — citations & training 'Claude-Web', 'Claude-User', 'ClaudeBot', 'anthropic-ai', // Perplexity 'PerplexityBot', 'Perplexity-User', // Google / Gemini — citations & training 'Googlebot', 'Google-Extended', 'Google-Gemini', // Microsoft / Bing 'bingbot', 'BingPreview', // Meta 'Meta-ExternalAgent', 'FacebookBot', // Others 'Bytespider', 'cohere-ai', 'CCBot', // Traditional search 'YouBot', 'DuckDuckBot', 'Baiduspider', ]; const LOG_ENDPOINT = '<TRAFFIC_INGEST_SERVICE_URL>/log/vercel'; const ORGANIZATION_ID = '<YOUR_ORGANIZATION_ID>'; export function middleware(request: NextRequest) { const ua = request.headers.get('user-agent') ?? ''; const isBot = AI_BOT_PATTERNS.some((p) => ua.toLowerCase().includes(p.toLowerCase()) ); if (isBot) { const payload = { timestamp: new Date().toISOString(), bot_ua: ua, url: request.url, method: request.method, ip: request.headers.get('x-forwarded-for') ?? request.headers.get('x-real-ip'), country: request.headers.get('x-vercel-ip-country'), city: request.headers.get('x-vercel-ip-city'), }; // Fire-and-forget — never awaited, does not block the response fetch(LOG_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ORGANIZATION_ID}`, }, body: JSON.stringify(payload), }).catch(() => {}); } return NextResponse.next(); } export const config = { // Run on all routes except Next.js internals and static files matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], }; ``` ```js middleware.js (SvelteKit / Nuxt / Astro — server hooks) theme={null} // SvelteKit: place in src/hooks.server.js // Nuxt: place in server/middleware/bot-tracker.js // Astro: place in src/middleware.js const AI_BOT_PATTERNS = [ // OpenAI — citations & training 'OAI-SearchBot', 'ChatGPT-User', 'GPTBot', // Anthropic / Claude — citations & training 'Claude-Web', 'Claude-User', 'ClaudeBot', 'anthropic-ai', // Perplexity 'PerplexityBot', 'Perplexity-User', // Google / Gemini — citations & training 'Googlebot', 'Google-Extended', 'Google-Gemini', // Microsoft / Bing 'bingbot', 'BingPreview', // Meta 'Meta-ExternalAgent', 'FacebookBot', // Others 'Bytespider', 'cohere-ai', 'CCBot', // Traditional search 'YouBot', 'DuckDuckBot', 'Baiduspider', ]; const LOG_ENDPOINT = '<TRAFFIC_INGEST_SERVICE_URL>/log/vercel'; const ORGANIZATION_ID = '<YOUR_ORGANIZATION_ID>'; export async function handle({ event, resolve }) { const ua = event.request.headers.get('user-agent') ?? ''; const isBot = AI_BOT_PATTERNS.some((p) => ua.toLowerCase().includes(p.toLowerCase()) ); if (isBot) { const payload = { timestamp: new Date().toISOString(), bot_ua: ua, url: event.request.url, method: event.request.method, ip: event.request.headers.get('x-forwarded-for'), country: event.request.headers.get('x-vercel-ip-country'), city: event.request.headers.get('x-vercel-ip-city'), }; fetch(LOG_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ORGANIZATION_ID}`, }, body: JSON.stringify(payload), }).catch(() => {}); } return resolve(event); } ``` </CodeGroup> </Step> <Step title="Fill in your credentials"> Replace the two placeholder values in the file: | Placeholder | Value | | ------------------------------ | ------------------------------------------------------------- | | `<TRAFFIC_INGEST_SERVICE_URL>` | The URL of the traffic-ingest-service (ask your Siftly admin) | | `<YOUR_ORGANIZATION_ID>` | Your Organisation ID from the Siftly dashboard | </Step> <Step title="Deploy"> Commit and push (or run `vercel deploy`). The middleware activates automatically on every incoming request. No additional environment variables, build steps, or packages are required. </Step> </Steps> ## Netlify For Netlify, use an [Edge Function](https://docs.netlify.com/edge-functions/overview/) instead of middleware: ```js netlify/edge-functions/bot-tracker.js theme={null} export default async (request, context) => { const AI_BOT_PATTERNS = [ // OpenAI — citations & training 'OAI-SearchBot', 'ChatGPT-User', 'GPTBot', // Anthropic / Claude — citations & training 'Claude-Web', 'Claude-User', 'ClaudeBot', 'anthropic-ai', // Perplexity 'PerplexityBot', 'Perplexity-User', // Google / Gemini — citations & training 'Googlebot', 'Google-Extended', 'Google-Gemini', // Microsoft / Bing 'bingbot', 'BingPreview', // Meta 'Meta-ExternalAgent', 'FacebookBot', // Others 'Bytespider', 'cohere-ai', 'CCBot', // Traditional search 'YouBot', 'DuckDuckBot', 'Baiduspider', ]; const LOG_ENDPOINT = '<TRAFFIC_INGEST_SERVICE_URL>/log/vercel'; const ORGANIZATION_ID = '<YOUR_ORGANIZATION_ID>'; const ua = request.headers.get('user-agent') ?? ''; const isBot = AI_BOT_PATTERNS.some((p) => ua.toLowerCase().includes(p.toLowerCase())); if (isBot) { const payload = { timestamp: new Date().toISOString(), bot_ua: ua, url: request.url, method: request.method, ip: request.headers.get('x-nf-client-connection-ip'), country: context.geo?.country?.code, city: context.geo?.city, }; context.waitUntil( fetch(LOG_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ORGANIZATION_ID}` }, body: JSON.stringify(payload), }).catch(() => {}) ); } return context.next(); }; ``` Add the edge function route in `netlify.toml`: ```toml netlify.toml theme={null} [[edge_functions]] path = "/*" function = "bot-tracker" ``` ## Verifying It Works After deploying, visit your site with a spoofed User-Agent to confirm events appear in Siftly: ```bash theme={null} curl -A "GPTBot/1.0" https://yoursite.com ``` Check the **Traffic** section of the Siftly dashboard within a few minutes. # WordPress Plugin Source: https://docs.siftly.ai/traffic-tracking/wordpress Install the Siftly AI Bot Tracker plugin to log AI crawler visits on your WordPress site. <Frame> <img alt="AI bot traffic detection — WordPress plugin intercepts AI crawler requests" /> </Frame> ## Installation <Steps> <Step title="Download the Plugin"> In the Siftly dashboard, go to **Traffic → Connect** and select **WordPress**. Click the **Download Siftly AI Bot Tracker** button. The downloaded zip already contains your Organisation ID and API endpoint — no manual configuration required. </Step> <Step title="Upload to WordPress"> 1. Log in to your WordPress admin panel. 2. Go to **Plugins → Add New → Upload Plugin**. 3. Click **Choose File**, select the `siftly-ai-bot-tracker.zip` file, and click **Install Now**. 4. After installation completes, click **Activate Plugin**. You will be redirected to the **Settings → Siftly** page automatically. </Step> <Step title="Verify the Connection"> On the **Settings → Siftly** page, confirm that the **API Endpoint URL** and **Organisation ID** are pre-filled, then scroll down and click **Send Test Event**. A green success banner confirms everything is working. <Tip> If you need to change the Organisation ID later (e.g. switching to a different Siftly org), update it on this settings page and click **Save Settings**. </Tip> </Step> </Steps> ## How It Works The plugin: 1. **Captures** every public page visit and checks the User-Agent against the AI bot list. 2. **Queues** bot events in a lightweight local database table. 3. **Sends** queued events to the traffic-ingest-service in batches every 5 minutes via WP-Cron. This means the plugin never slows down your page loads — tracking happens entirely in the background. ## Troubleshooting <AccordionGroup> <Accordion title="Circuit breaker is tripped"> The plugin automatically pauses sending after 5 consecutive failures to avoid hammering a temporarily unavailable endpoint. It resumes after 5 minutes. To reset immediately, go to **Settings → Request Tracker** and click **Reset Circuit Breaker**. </Accordion> <Accordion title="No events appearing in Siftly"> 1. Go to **Settings → Siftly** and confirm the **Organisation ID** and **API Endpoint URL** are filled in. If you downloaded the plugin from the Siftly dashboard, both should be pre-filled. 2. Confirm the **API Endpoint URL** ends with `/log/wordpress`. 3. Click **Send Test Event** to verify connectivity. 4. Check WP-Cron is running — some hosts disable WP-Cron. You may need to trigger it with a real cron job: ```bash theme={null} */5 * * * * curl https://yoursite.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1 ``` </Accordion> <Accordion title="I see events but the Organisation ID is wrong"> Go to **Settings → Siftly**, clear the Organisation ID field, paste the correct UUID from the Siftly dashboard, and click **Save Settings**. </Accordion> </AccordionGroup>