> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siftly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Framer Integration

> Connect Siftly to your Framer site and publish GEO-optimized content directly to your Framer CMS collections.

<Frame>
  <img src="https://mintcdn.com/siftly/IwND2vAxRbhCiRev/images/cms-integrations.svg?fit=max&auto=format&n=IwND2vAxRbhCiRev&q=85&s=2704e9affce00587d23137bf707339c7" alt="Supported CMS platforms including Framer" className="rounded-xl" width="900" height="280" data-path="images/cms-integrations.svg" />
</Frame>

## 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.

<Warning>
  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.
</Warning>

***

## 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.

<Tip>
  If your Framer collection has different field names (e.g., `headline` instead of `title`), select the correct field from the dropdown.
</Tip>

***

## 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.

<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

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

<AccordionGroup>
  <Accordion title="Connection fails with 401 Unauthorized">
    Your API token is invalid or expired. Regenerate the token in Framer's Project Settings and update it in Siftly.
  </Accordion>

  <Accordion title="No collections found">
    Make sure your Framer project has at least one CMS collection created. The collection must exist before connecting.
  </Accordion>

  <Accordion title="Content saves but doesn't appear in Framer">
    Check the Framer CMS panel for the item in **Drafts**. If published with Draft status, it won't be live.
  </Accordion>

  <Accordion title="Field mapping errors">
    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.
  </Accordion>

  <Accordion title="Fields with Use Existing show empty values">
    Ensure you're on the latest version. Source fields are auto-populated server-side — no user input needed.
  </Accordion>
</AccordionGroup>

***

## 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 `<title>` 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 cols={2}>
  <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>
