Blog / journal
When Blog is included in your purchase, staff publish a storefront journal
at /blog/ — long-form articles with their own workflow, SEO, and internal
linking. This is not CMS (homepage bands and policy
pages). If Blog screens aren’t in your admin, they aren’t enabled for this
store — contact support to change what’s included.
Open Content → Blog (admin.your-domain.com/dashboard/blog).
Two presets sit under Users & roles:
| Role | For | Can |
|---|---|---|
| Blog author | Writers | View, create, and edit drafts. Cannot publish. |
| Blog editor | The desk | Author permissions plus publish, archive, reusable blocks, media, and AI drafting tools. |
Manage webhooks is not on the editor preset — owner/manager keep that.
Server-side RBAC enforces the same gates as the menu. An author who PATCHes
an article to published gets 409, not a live URL.
Write an article
Section titled “Write an article”New article asks for a title. The editor then covers:
- Title and slug — changing the slug on a live article creates a redirect
from the old
/blog/{from}URL. Confirm that before you save. - Excerpt — used on the index, RSS, and as the SEO description fallback.
- SEO — title, description, canonical URL, robots. JSON-LD for Article / FAQ / breadcrumb is generated for you; an override replaces the whole graph.
- Featured image — pick from the file manager.
- Body — TipTap. Headings, lists, links, images (stored as a file id), reusable blocks, and CTA embeds. Autosave keeps drafts after a short pause.
- History — restore an autosaved or published snapshot into the editor; publish again to make it live.
Bangla and other locales are separate article rows in the same content group — each with its own slug, status, and publish date. Create a translation from the article editor when you need another locale.
Workflow
Section titled “Workflow”Statuses move in a fixed graph. The rail on the right only offers the next legal step for your role:
draft → in_review → approved → published
Side doors: changes_requested, scheduled, archived. Publishing sets
published_at. Unpublish returns the article to draft and fires an
unpublished webhook if you have one.
Blocks, CTAs, and media
Section titled “Blocks, CTAs, and media”Indented under Blog:
- Blocks — reusable TipTap fragments you embed in an article body.
- CTAs — heading, body, button. Optional scroll depth (
25/50/75) shows that CTA as a storefront overlay at that point in the article instead of the inline stack. - Featured images and in-body images go through the file manager. Unsplash
search is available only when
UNSPLASH_ACCESS_KEYis set on the API — without it the picker returns 404, which is expected.
Webhooks
Section titled “Webhooks”Content → Webhooks (permission blog.manage_webhooks). Create a URL and a
secret. Events: published, unpublished, archived, updated. An empty
event list means all four.
Deliveries run on Celery, not in the request. The body is JSON; the header is
X-Nudova-Signature: sha256=… (HMAC of the raw body). Failed posts retry up
to five times. The secret is write-only — the list never returns it.
Content health
Section titled “Content health”Content → Health shows the last background scan — not a live computation on page load:
- Orphan articles — published pieces with no inbound internal links.
- Decaying articles — published more than 90 days ago with zero recorded views.
- Link suggestions — another published title is mentioned in the body but not linked.
The scan runs on the hourly Celery beat task. An empty dashboard means the scan has not run yet, not that the journal is perfect.
Storefront
Section titled “Storefront”Published articles render at https://your-domain.com/blog/{slug}. Retired
slugs 301 to the live slug. The index accepts category, tag, year, and
search query params.
Also generated when Blog is enabled:
/blog/rss.xml— RSS 2.0 of published articles./sitemap.xml— includes those article URLs.
Tenant config extra can set gtm_container_id (GTM-… only) and
google_site_verification. Empty or malformed values are ignored — the
storefront will not inject a guessed tag.
Article bodies opt into bionic reading (leading letters wrapped after mount) and a readable measure on paragraphs. Emotional scores in the editor (Trust / Urgency / Curiosity / Relief / Authority) are cached on the article and never block save.
Editorial workflow mode
Section titled “Editorial workflow mode”Briefs and Autopilot only exist in full editorial workflow. Open
Content → Blog → Editorial settings (permission blog.publish — the
desk’s setting, not an author’s) and check workflow_mode:
- Simple — the default for most stores. Draft → publish, no briefs, no planning queue.
- Full — adds the Briefs and Autopilot screens below. In simple mode, both screens show a message pointing you back to Editorial settings instead of their normal content, and their API endpoints return 404, not just a hidden menu item.
Briefs — the planning queue
Section titled “Briefs — the planning queue”Content → Blog → Briefs is a flat topic queue, independent of Autopilot — it’s how any store plans what to write next, whether or not Autopilot is installed.
New brief asks for a topic (required), optional notes, and an
optional target publish date. A brief starts planned.
Convert turns a brief into an article: an empty draft titled after the
brief’s topic, with the brief’s notes attached as an editorial comment (not
written into the body) if you left any. It does not call AI — it’s a
manual “start writing this” shortcut. The brief flips to converted and
links to the new article; Convert disappears once that’s happened.
Calendar
Section titled “Calendar”Also full-mode-only: Content → Blog → Calendar overlays two things on one
date grid — planned items (briefs with a target publish date) and
committed items (articles that are scheduled or already published).
It’s read-only; there’s no drag-to-reschedule. Use it to see at a glance
whether your queued briefs and your actual publish dates line up.
Autopilot (optional add-on)
Section titled “Autopilot (optional add-on)”If your purchase includes it, Content → Blog → Autopilot plans and drafts articles from the Briefs queue above on a schedule. See Blog Autopilot for the concept (plan → brief → draft → edit feedback → learning); this section is the screen-by-screen how-to.
Create a content plan
Section titled “Create a content plan”Autopilot → New plan, then fill in:
| Field | What it does |
|---|---|
| Name | Just a label in the plans list. |
| Locale | Which article locale this plan writes (matches Blog’s locale fields). |
| Timezone | The timezone next_run_at is computed in. |
| Cadence | An iCalendar RRULE string — e.g. FREQ=DAILY;INTERVAL=1 for daily, FREQ=WEEKLY;BYDAY=MO,TH for twice a week. |
| Articles per run | How many briefs one scheduled run tries to draft. |
| Autonomy | Draft only — every AI draft lands as draft. Submit for review — the draft is auto-submitted into the approval workflow as in_review instead of sitting as a raw draft. Either way, publishing still needs a human with blog.publish. |
| Active | Off pauses the schedule without deleting the plan. |
| Link to content group | Groups this plan’s articles under one content group for cross-linking. |
| Generate hero image | Only shown when an image-generation provider is configured; disabled (but visible) if the key isn’t ready yet. |
A plan’s header shows its queue status — how many planned briefs are
waiting — and, when that’s zero, a direct link back to Briefs → New so
you’re never stuck wondering why nothing is generating.
Run history
Section titled “Run history”Autopilot → Runs (or a plan’s View runs link) lists every scheduled attempt with a status:
| Status | Meaning |
|---|---|
pending / running |
Scheduled or in progress. |
success |
Drafted the planned number of articles. |
error |
The run failed — see the run’s error detail. |
skipped_no_briefs |
The plan fired, but the Briefs queue was empty. |
skipped_stale |
Skipped because it was overdue past a staleness window. |
skipped_cap |
Skipped because the monthly article or cost cap was already hit. |
A quiet plan is almost always skipped_no_briefs — check Briefs before
assuming something’s broken.
Learning signals
Section titled “Learning signals”Autopilot → Signals shows what the learning loop has distilled from your edits — the patterns it applies to nudge future drafts toward your house style. This view is read-only; the signals themselves come from editing and approving (or rejecting) AI drafts over time, per Blog Autopilot → How it works.
Permissions
Section titled “Permissions”| Permission | Covers |
|---|---|
blog.view |
See Briefs, plans, runs, and signals. |
blog.create |
Create a brief, convert a brief, create a plan. |
blog.edit |
Edit a brief or a plan. |
blog.manage_ai_settings |
Change the monthly caps, review override, and notify list (API only — see above). |
Autopilot also needs the blog.autopilot license entitlement — distinct
from the base Blog domain’s blog.intelligence pack. See
Entitlements → Blog.
MCP authoring (optional)
Section titled “MCP authoring (optional)”Agents with a staff token and blog.use_ai call POST /api/v1/blog/mcp/.
Tools: search, get, draft, suggest metadata, suggest internal links. Every
call is audit-logged. Brand deny-list and required-review live on the tenant
as extra.blog_guardrails:
{ "deny_list": ["banned-phrase"], "required_review": true }required_review defaults to on. Drafts from this channel still cannot
publish until a human approves them.
Related: CMS / content · Marketing · Users & roles · Blog Autopilot.