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.
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 · Users & roles · Blog API.