Framer CMS SEO publishing workflow

The Framer adapter uses the Server API and is therefore marked beta. It connects to one project, finds a writable Collection, maps typed fields, and treats publication as complete only after Framer returns a deployment ID.

Best for: Framer sites with a writable CMS Collection and teams that can test the beta adapter in a controlled Node.js 22+ environment.

Support status: beta
Publisher: framer

How the connection works

Authentication

A Framer API key, complete project URL, and Collection name or ID stored in the server-side publisher environment.

Server-side variables

  • SEO_BLOG_PUBLISH_TOKEN
  • SEO_BLOG_SITE_SLUG
  • FRAMER_API_KEY
  • FRAMER_PROJECT_URL
  • FRAMER_COLLECTION
  • SEO_BLOG_SITE_ORIGIN

Publishing sequence

01

Connect to the project and reject read-only Collections.

02

Map title, body, excerpt, SEO, author, date, and image fields.

03

Write typed values with a stable item identifier.

04

Publish, verify the deployment ID, deploy, and always disconnect.

No-write payload and mapping preview

SEO_BLOG_PUBLISH_TOKEN='<tenant-token>' \
SEO_BLOG_SITE_SLUG='<slug>' \
FRAMER_API_KEY='<framer-api-key>' \
FRAMER_PROJECT_URL='<framer-project-url>' \
FRAMER_COLLECTION='<framer-collection>' \
SEO_BLOG_SITE_ORIGIN='<origin>' \
npx --yes @wotaso/seo-blog-admin-cli publish-cms --cms framer --site-slug '<slug>' --site-origin '<origin>' --dry-run

For a currently due approved post, --dry-run builds the destination payload without writing to the provider. It does not contact the provider or prove credentials, remote schema compatibility, deployment, or a live page; when no post is due, provider inputs are not exercised.

Scheduled runner health heartbeat

SEO_BLOG_PUBLISH_TOKEN='<tenant-token>' \
SEO_BLOG_SITE_SLUG='<slug>' \
FRAMER_API_KEY='<framer-api-key>' \
FRAMER_PROJECT_URL='<framer-project-url>' \
FRAMER_COLLECTION='<framer-collection>' \
SEO_BLOG_SITE_ORIGIN='<origin>' \
SEO_BLOG_SCHEDULED='true' \
npx --yes @wotaso/seo-blog-admin-cli health --config seo-blog.config.json --mode cms --site-slug '<slug>' --site-origin '<origin>'

Run this from the real scheduled runner after seo-blog.config.json contains the selected connector configuration and the listed secrets are loaded. It reports configuration readiness, not a live article. The dashboard expires readiness at the returned deadline, with a 36-hour fallback when no deadline is available.

Fields and data model

  • Stable item ID derives from the internal post ID
  • Slug or stable ID prevents accidental duplicates
  • A missing field match blocks the run

Canonical and route

The Framer site and CMS detail template own the route, canonical tag, and sitemap. The adapter writes content and starts deployment; it does not replace Framer SEO settings.

Known limits

  • Requires Node.js 22+ and the optional Framer package.
  • Server API behavior can change while the adapter is beta.
  • Read-only Collections or a missing deployment ID block publication.

Recovery

  • Identify the Collection and document the field map in dry run.
  • Compare field names and types when no fields match.
  • Never mark a failed deployment published manually; rerun with the stable post ID.

Integration questions

Where are credentials stored?

The Framer credentials stay in CI or another server-side secret environment.

Does SEODrafts own the canonical URL?

No. The destination website owns its route, canonical tag, sitemap, rendering, and analytics.

Can the integration be tested before publishing?

Use the no-write payload preview to inspect local mapping, then separately test credentials and the first destination draft before a live run.

Keep the website your team already owns.

Review the opportunity and draft in SEODrafts, then publish approved work through Framer.

Add my website