DOCX Authoring Guide¶
VIBE supports both Markdown and Word templates. If you prefer to draft in Microsoft Word, this guide covers the practical differences that matter when authoring .docx templates.
When to Choose DOCX¶
DOCX templates are a good fit when:
- Your starting point is an existing Word document with established styles or branding
- You need Word-native features such as tracked numbering, tables, headers, footers, or bookmarks
- The final deliverable is primarily a Word document rather than web preview text
Markdown templates are often easier to diff and refactor, but DOCX is the better authoring format when visual fidelity in Word is the priority.
Where Jinja Syntax Goes¶
Use the same Jinja syntax in DOCX that you would use in Markdown:
In practice, place tags where ordinary text would normally go:
- In a normal paragraph
- Inside a table cell
- Inside a list item
- Inside a heading
Keep each tag contiguous in Word. A tag like {{ client_name }} should be typed as one continuous piece of text, not partially bolded or manually split across differently formatted fragments.
docxtpl Structural Tags¶
VIBE renders .docx templates with docxtpl, so Word templates support a few extra tags beyond plain Jinja. These matter whenever the logic needs to control an entire Word structure rather than just inline text.
{%p ... %}controls a paragraph{%tr ... %}controls a table row{%tc ... %}controls a table cell/column region{%r ... %}controls a single Word run{{r value }}inserts aRichTextvalue into the current run{{p value }}inserts paragraph-level content such as a rich paragraph or subdocument
Use these tags when ordinary Jinja would otherwise need to cross paragraph, row, cell, or run boundaries.
The paragraphs containing {%p if ... %} and {%p endif %} are removed by docxtpl. Only the content in between remains when the condition is true.
For inserted DOCX subdocuments or paragraph-level content, the placeholder must also stand alone in its own paragraph:
Rules of Thumb¶
- Put
{%p ... %},{%tr ... %},{%tc ... %},{%r ... %}, and{{p ... }}on their own paragraph, row, cell, or run. - Do not write both the opening and closing prefixed tags in the same paragraph or row. Use separate Word paragraphs/rows for the start and end tags.
- Keep spaces inside the delimiters: write
{%p if condition %}, not{%pif condition%}. - Style the real content paragraphs, rows, and cells, not the placeholder paragraph or row that contains the control tag, because that wrapper is removed during rendering.
- In bulleted or numbered lists, put
{%p if ... %}and{%p endif %}on their own list paragraphs. This avoids list numbering and missing-endifproblems. - If Word splits a tag across multiple runs because of formatting changes, delete the whole tag and retype it as plain contiguous text.
{{r ... }} and Rich Text¶
Use {{r ... }} when the value is a docxtpl.RichText object or another helper returns rich inline content. This is different from a normal {{ variable }} insertion:
{{ variable }}keeps the current run styling from the template{{r value }}lets the value carry its own inline formatting
This also applies to built-in filters that produce rich DOCX output. For example, in Word templates use {{r client_name | or('Client Name') }} and {{p project_description | markdown }}.
Be careful with run styling:
{{r ... }}resets the current character styling unless theRichTextvalue specifies it- paragraph style still comes from the surrounding paragraph
- do not use two
{{r ... }}insertions in the same run - Jinja filters do not apply cleanly to
RichText, so transform the value before passing it into the template
Formatting and Structure¶
VIBE renders the template content and keeps the surrounding DOCX structure intact, so Word formatting usually comes from the document itself:
- Paragraph styles, fonts, spacing, and margins stay in the
.docx - Headings should use Word's built-in heading styles if you want numbering and cross-references to behave correctly
- Tables, headers, footers, and page layout belong in Word, not in the template logic
For cross-references in DOCX, use Word's native cross-reference tools rather than typing section numbers manually. See Cross-References and Section Numbering.
Components in DOCX¶
Components work in DOCX templates too:
- A DOCX host can insert Markdown or DOCX components
- A Markdown host can also insert DOCX components
- The same
{{ insert(...) }}call is used in both formats
For the component model itself, see Reuse with Components. For data structures reused between components, see Reusable Data with definitions.
Common Gotchas¶
Tags split by formatting¶
If Word splits a tag into multiple styled fragments, the template can become fragile. If a variable or control tag behaves strangely, delete the whole tag and retype it as plain contiguous text.
Manual numbering¶
Do not type section numbers by hand if they may shift. Use Word heading numbering and Word cross-references instead. VIBE updates those references after rendering.
Logic-heavy templates¶
DOCX is best when the presentation is important. If the template logic becomes hard to reason about, move calculations into computable variables and shared content into components.
Preview mismatch¶
The browser preview is useful, but the DOCX output is the source of truth for Word formatting. Check the actual .docx output when debugging spacing, numbering, or layout issues.
Debugging DOCX Templates¶
Start with the same checks you would use for Markdown templates:
- Validate the template with
vibe validate - Confirm question visibility and answers with the interview preview
- Reduce the problem to the smallest failing section you can
For DOCX-specific debugging, the vibe-dev docx commands are the most useful:
vibe-dev docx read path/to/output.docx
vibe-dev docx component-render my-template
vibe-dev docx insert-debug my-template
vibe-dev docx download-debug my-template
The command reference is in vibe-dev - VIBE Developer Toolkit.
Workflow Suggestions¶
For a Word-first workflow:
- Start from a clean
.docxwith the styles, numbering, and boilerplate you want. - Add Jinja tags gradually and keep them visually simple.
- Validate often with
vibe validate. - Render early to catch numbering, bookmark, and layout issues while the template is still small.
- Extract repeated sections into components once the structure stabilizes.