Last Updated: 2026-05-03 Status: Active — Enforced for all content under
public-docs/Scope: Source-of-truth for everything rendered atdocs.vlozi.app
This guide defines the writing standards, file conventions, and quality bar for the user-facing documentation under public-docs/ — the markdown source rendered by apps/public-docs.
It is the public-facing counterpart to Documentation Standards (which governs the internal engineering docs in docs/). The two follow a similar shape but different rules, because the audiences are different:
docs/ (internal) |
public-docs/ (this guide) |
|
|---|---|---|
| Audience | Engineers building Vlozi | Developers integrating Vlozi |
| Tone | Technical, decision-oriented | Task-oriented, copy-paste-ready |
| Content | Vision, ADRs, specs, journeys | Install, quickstart, concepts, reference |
| Diagrams | Required for architecture | Optional, only when load-bearing |
| Privacy | Internal — may discuss tradeoffs, incidents | Public — never reference internal infra, costs, or roadmap |
1. File Organization
1.1 Folder Structure
The directory tree is the navigation. Layout:
public-docs/
├── 01-blog/ ← product (slug: "blog")
│ ├── meta.md ← product metadata, frontmatter only
│ ├── 01-getting-started/ ← chapter (slug: "getting-started")
│ │ ├── meta.md ← chapter metadata
│ │ ├── 01-introduction.md ← page (slug: "introduction")
│ │ ├── 02-install.md
│ │ └── 03-quickstart.md
│ └── 02-authoring/
│ ├── meta.md
│ └── 01-posts.md
└── 02-newsletter/
└── ...1.2 Naming Conventions
| Rule | Example |
|---|---|
| Numeric prefix on every product / chapter / page folder or file | 01-blog/, 02-install.md |
| Prefix is stripped from the URL slug | 01-blog/ → /blog |
| Slug uses kebab-case, lowercase | getting-started, NOT gettingStarted |
| One word per concept | posts.md, NOT blog-posts.md (parent already says "blog") |
meta.md is reserved for metadata files |
Never name a content page meta.md |
1.3 Ordering
The numeric prefix is the only ordering signal. Files sort alphabetically; the prefix forces the order you want.
- Use
01-,02-,03-(zero-padded, two digits) - Reserve gaps when you expect insertions:
01-,05-,10-lets you insert03-foolater without a renumber
IMPORTANT
If you renumber files, update any cross-references that point to them. Slugs include the un-prefixed name, so renumbering does not break URLs — but renaming does.
2. Frontmatter
All .md files use YAML frontmatter between --- fences. Parsed via gray-matter in lib/docs.ts.
2.1 Product meta.md
Lives at public-docs/<NN>-<product>/meta.md. Body is ignored — frontmatter only.
---
name: Blog # required, display name
tagline: Headless blog you manage from the dashboard. # required, one sentence
status: stable # stable | beta | preview
version: 2.1.6 # current SDK / API version
installCommand: npm install @vlozi/blog # primary install command
lastUpdated: 2026-05-03 # ISO date, YYYY-MM-DD
repoUrl: https://github.com/vlozi/blog # optional, public repo
---| Field | Required | Notes |
|---|---|---|
name |
✅ | Display name. Must match the marketing name. |
tagline |
✅ | One sentence. Lower-case start, period at end. |
status |
✅ | One of stable, beta, preview. Drives the status pill. |
version |
recommended | Semver. Drives the "Version" line in the right rail. |
installCommand |
recommended | Renders in the install snippet. |
lastUpdated |
recommended | Bumped when the product's docs are revised. |
repoUrl |
optional | Public repo only. Skip for closed-source modules. |
2.2 Chapter meta.md
Lives at public-docs/<NN>-<product>/<NN>-<chapter>/meta.md.
---
title: Getting started
summary: Install the SDK and ship your first post.
---| Field | Required | Notes |
|---|---|---|
title |
✅ | Display title. Sentence case. |
summary |
recommended | One sentence. Renders on the chapter card. |
2.3 Page .md
Every content page starts with frontmatter, then a # H1, then the body.
---
title: Quickstart
description: Render your first post in five minutes.
---
# Quickstart
Body content...| Field | Required | Notes |
|---|---|---|
title |
✅ | Used in sidebar, breadcrumbs, <title>, prev/next nav. |
description |
recommended | One sentence under the page title. Used in <meta description> for SEO. |
NOTE
The renderer strips the leading # H1 from the body — the page header already shows the title. Keep the H1 in the source for editor readability and Markdown standards compliance.
3. Page Types
We use the Diátaxis framework — every page has exactly one of these jobs. Mixing modes makes pages confusing.
| Type | Question it answers | Example |
|---|---|---|
| Tutorial | "Show me how to do this end-to-end, the first time." | Quickstart |
| How-to | "How do I do this specific thing?" | Theming a post list, scheduling a send |
| Concept | "What is this and why does it work this way?" | Series vs Books, the credit wallet |
| Reference | "What's the exact shape of this API / option / event?" | REST endpoints, webhook payloads |
3.1 Tutorial Pages
Walk a user from zero to a working result. The user follows along.
Required structure:
- One-sentence summary of what they'll have at the end
- Prerequisites — accounts, env vars, packages
- Numbered steps — each with one clear action
- Working code per step (copy-paste-ready)
- What's next — links to How-to or Concept pages
Rules:
- Maximum 5 steps. If you need more, it should probably be split.
- Every step must be verifiable — the user can confirm it worked before moving on.
- Never say "now you can also..." — defer optional paths to the end.
3.2 How-to Pages
Solve one concrete problem for a user who already knows the basics.
Required structure:
- One-line problem statement (the page title is usually it)
- The solution (code or steps)
- Optional: variations / edge cases
- Cross-links to related How-to pages
Rules:
- Stay focused — one How-to = one problem
- Don't re-teach prerequisites; link to the Tutorial or Concept page instead
3.3 Concept Pages
Explain why something works the way it does. No code goal — just understanding.
Required structure:
- The thing being explained, in one sentence
- Why it exists (the problem it solves)
- How it relates to other concepts (with a diagram if it helps)
- Cross-links to How-to / Reference pages that use it
Rules:
- Concept pages can include diagrams; tutorials and how-tos rarely need them
- No exhaustive option lists — those belong in Reference
3.4 Reference Pages
Exhaustive, alphabetized, predictable. The user already knows what they want; they need the exact shape.
Required structure:
- The signature (function / endpoint / config object)
- Parameter / field table (name, type, required, default, description)
- Returns / response shape
- Example — minimal working snippet
- Errors — table of error codes / status codes if applicable
Rules:
- No prose-heavy paragraphs — tables and signatures
- Every field listed, no exceptions, even if "obvious"
- Examples must be runnable as-is
4. Heading Hierarchy
# Page title ← H1, exactly one, stripped on render
## Major section ← H2, sentence case, no numbering
### Subsection ← H3
#### Detail ← H4 (rarely needed; consider splitting the page)Rules:
- Sentence case for all headings:
## Get started, NOT## Get Started - No numbering (
## 1. Installis for internal docs only — the URL-driven nav already orders pages) - Never skip levels (no H2 → H4 jumps)
- Keep H1 source-side; the renderer strips it
- Headings become anchor IDs (via
rehype-slug) — keep them short and stable, since URLs deep-link to them
5. Code Blocks
5.1 Always Specify Language
```ts
const blog = createBlogClient({ apiKey: process.env.VLOZI_API_KEY! });
```Use plaintext if no language fits. Never bare ```.
Common languages: ts, tsx, js, jsx, bash, json, yaml, sql, http, md, dockerfile.
5.2 Show All Package Managers for Install Commands
When documenting install or run commands, show npm + pnpm + yarn + bun as separate blocks:
```bash
# npm
npm install @vlozi/blog
# pnpm
pnpm add @vlozi/blog
# yarn
yarn add @vlozi/blog
# bun
bun add @vlozi/blog
```(A future iteration may render these as a tabbed widget — the source format stays the same.)
5.3 Copy-Paste Readiness
Every code block must be runnable as-is by a developer who copy-pastes it.
- ✅ Include all imports
- ✅ Show env-var placeholders inline (
process.env.VLOZI_API_KEY!) - ❌ No "..." or
// rest of codemid-snippet — split the block instead - ❌ No type annotations that depend on undeclared types
- ❌ No internal Vlozi paths (
@/lib/...) — only public package imports
5.4 Length
- Max 25 lines per block
- Longer = split into stages with one-sentence narration between
- Use highlights sparingly (rehype-pretty-code supports
{1,3-5}notation)
6. Tables
Use tables for any 2D data — fields, options, comparisons, error codes.
| Field | Type | Required | Description |
|:---|:---|:---|:---|
| `apiKey` | string | ✅ | Project API key from the dashboard |
| `baseUrl` | string | — | Override the default API host |Rules:
- Always left-align (
:---) - Use ✅ / — for boolean columns (not ✓ / ✗ / yes / no)
- Backtick all code identifiers in cells:
apiKey, NOT apiKey - Bold-mark the most important column header if scannability matters
7. Callouts
GitHub-flavoured callouts. Use sparingly — too many and they stop being noticed.
> [!NOTE]
> Helpful context that doesn't fit in the prose flow.
> [!TIP]
> Optional optimization or shortcut.
> [!IMPORTANT]
> Something the user must do for the page to apply to them.
> [!WARNING]
> Something that will break if ignored.
> [!CAUTION]
> Something that risks data loss or production impact.Rules:
- Maximum two callouts per page. If you need more, the prose probably needs restructuring.
- Never start a page with a callout — set context first.
- One sentence per callout, ideally.
8. Cross-References
Use absolute path URLs — these are rendered as <Link> and resolve against the docs site root:
See [Quickstart](/blog/getting-started/quickstart) for the full walkthrough.
Continue to the [Authoring chapter](/blog/authoring/posts).Rules:
- ✅ Absolute path:
/blog/getting-started/install - ❌ Relative path:
../getting-started/install.md - ❌ Markdown file extension in URLs:
/blog/getting-started/install.md - Link text = the destination page's title, not "click here" or "this guide"
- Never link to internal
docs/(those are private). Never link togo.vlozi.app/<feature>unless it's a stable, public dashboard route.
8.1 External Links
Use full URLs and prefer the canonical hostname:
- ✅
https://go.vlozi.appfor the dashboard - ✅
https://vlozi.appfor the marketing site - ✅
https://docs.vlozi.appfor absolute self-references (rare — prefer relative)
9. Voice & Style
- Lead with the answer. First sentence should resolve the page's title. Context comes after, not before.
- Second person. Address the reader as you, never we or one. ("You initialize the client" — not "We initialize the client" or "One initializes the client.")
- Active voice. "The SDK fetches posts" — not "Posts are fetched by the SDK".
- Present tense. "Returns a 200" — not "will return a 200".
- Concrete examples. Always show real values:
vlz_live_xxxxxxxxxxxxxxxx, not "your-api-key-here". Use realistic post titles in examples ("How we ship docs"), not "Test post 1". - Cut filler. No "basically", "essentially", "in order to", "it should be noted that", "simply".
- No hype. "The SDK installs in seconds" — not "The SDK installs in blazing fast seconds with our world-class DX".
- Define unfamiliar terms on first use. Especially Vlozi-specific terms ("a credit powers any tool action — see Credits").
- Never reference internal naming. Users don't know what "the brain" or "the orchestrator" are. Use the public name (
@vlozi/chatbot, "the chatbot module").
10. Diagrams (Optional)
Most public docs pages don't need diagrams. When they do — typically on Concept pages — use mermaid with the same color palette as internal docs.
See Documentation Standards § 4 for the mermaid style rules. Apply identically here.
IMPORTANT
Never copy a diagram from docs/ into public-docs/ directly. Internal diagrams expose service names, infra topology, and architectural decisions that must not leak. Redraw with public-safe nodes.
11. What NOT to Document
Things that go in docs/, never in public-docs/:
- Internal service names (
brain-service,orchestrator,gateway) - Infrastructure choices (Cloudflare Workers, Neon, R2 — unless it's a load-bearing concept the user must know about)
- Roadmap, ETAs, post-launch plans
- Pricing internals (margins, costs)
- Past incidents, RCA writeups
- Team-only operational runbooks
- Credentials, internal endpoints, staging URLs
When unsure: ask if a competitor reading this page would learn anything they'd want. If yes, it doesn't go here.
12. Quality Checklist
Before merging a doc:
- Frontmatter present and valid (
titlefor pages,name+tagline+statusfor productmeta.md,titlefor chaptermeta.md) - H1 in source matches frontmatter
title - Page has exactly one of the four Diátaxis types (Tutorial / How-to / Concept / Reference) and follows that type's required structure
- Heading hierarchy is unbroken (no H2 → H4 jumps)
- Every code block has a language tag
- Install commands show npm + pnpm + yarn + bun variants
- All examples are copy-paste runnable (full imports, no
...) - No internal service names, no
docs/links, no roadmap leaks - Cross-references use absolute paths (
/product/chapter/page) - At most two callouts; each is one sentence
- File and folder names use the
NN-kebab-casepattern -
lastUpdatedbumped on the product'smeta.mdif the change is meaningful
13. Authoring Workflow
- Decide the page type (Tutorial / How-to / Concept / Reference) before writing
- Place the file under the right product → chapter folder, with the right numeric prefix
- Write frontmatter first; let the title force you to commit to the page's job
- Outline the H2 sections required for the page type, then fill in
- Run
pnpm devinapps/public-docs/and read the rendered page — formatting issues only show up rendered - Run through the checklist above before opening a PR
14. Related
- Documentation Standards — internal
docs/rules - Public docs source — the live content tree
- Public docs renderer — the Next.js app rendering this content
- Diátaxis framework — external reference for the four-type model