Skip to content

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:

{{ client_name }}
{% if include_appendix %}
{% endif %}
{% for signer in signers %}
{% endfor %}

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 a RichText value 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.

{%p if include_signature_block %}
Signed at {{ city }} on {{ signing_date }}.
{%p endif %}

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:

{{p include_docx_template(template.path) }}

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-endif problems.
  • 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 the RichText value 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:

  1. Start from a clean .docx with the styles, numbering, and boilerplate you want.
  2. Add Jinja tags gradually and keep them visually simple.
  3. Validate often with vibe validate.
  4. Render early to catch numbering, bookmark, and layout issues while the template is still small.
  5. Extract repeated sections into components once the structure stabilizes.

See Also