No-write payload and mapping preview
SEO_BLOG_PUBLISH_TOKEN='<tenant-token>' \
SEO_BLOG_SITE_SLUG='<slug>' \
SANITY_TOKEN='<sanity-token>' \
SANITY_PROJECT_ID='<sanity-project-id>' \
SANITY_DATASET='<sanity-dataset>' \
SANITY_DOCUMENT_TYPE='<sanity-document-type>' \
SEO_BLOG_SITE_ORIGIN='<origin>' \
npx --yes @wotaso/seo-blog-admin-cli publish-cms --cms sanity --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>' \
SANITY_TOKEN='<sanity-token>' \
SANITY_PROJECT_ID='<sanity-project-id>' \
SANITY_DATASET='<sanity-dataset>' \
SANITY_DOCUMENT_TYPE='<sanity-document-type>' \
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
- Both bodyHtml and bodyMarkdown are available to the schema
- Slug is written as a native Sanity slug object
- Document type, API version, and field map are configurable
Canonical and route
Sanity stores content, but the consuming frontend controls the page route, canonical tag, sitemap, structured data, and deployment. SEODrafts derives the final route from the configured website rather than a Studio URL.
Known limits
- Portable Text blocks are not invented from HTML without a tenant mapping or transformation.
- Create-or-replace requires a token that can write the chosen dataset.
- A successful mutation does not confirm that a cached or statically built frontend is live.
Recovery
- Test the exact document type and field map against a non-production dataset first.
- Inspect schema validation errors in Sanity when a field type rejects the mapped value.
- Reuse the deterministic document ID after fixing a failure instead of creating another document.