Skip to content
Docxcelerate

Essentials

Templates

Compose a document tree with TSX, or with plain function calls — both produce the same document.

Templates come in two forms. They are equivalent; pick by taste and by how much structure the document has.

TSX

/** @jsxImportSource docxcelerate/template */
import { Document, Section, template } from "docxcelerate/template";
import { Greeting, NextSteps } from "./nodes/index.ts";
import type { DocumentData } from "./types.ts";

export const documentTemplate = template<DocumentData>(
  <Document id="tenancy-renewal" title="Tenancy Renewal">
    <Section id="opening" title="Opening">
      <Greeting />
    </Section>
    <Section id="closing" title="Closing">
      <NextSteps />
    </Section>
  </Document>,
);

The pragma on line one is what wires JSX to Docxcelerate rather than to React. Set jsxImportSource in tsconfig.json instead and you can drop it:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "docxcelerate/template"
  }
}

Scaffolded workspaces already have this configured.

Plain functions

import { document, section } from "docxcelerate";

export const documentTemplate = doc<DocumentData>({
  id: "tenancy-renewal",
  title: "Tenancy Renewal",
  nodes: [
    section({ id: "opening", title: "Opening" }, [Greeting]),
    section({ id: "closing", title: "Closing" }, [NextSteps]),
  ],
});

Useful when a document’s structure is computed — building sections from a list, for instance, where JSX would need a map and a fragment anyway.

Reusable components

defineDocumentComponent and defineSectionComponent let you build your own wrappers around the primitives — a house-style letterhead, a standard closing block — and reuse them across documents:

import { defineSectionComponent } from "docxcelerate/template";

export const Closing = defineSectionComponent<DocumentData>({
  id: "closing",
  title: "Closing",
});

Document projects

A document project ties a template to its style and preview data through one entrypoint, document.project.ts:

import { defineDocumentProject } from "docxcelerate/document";
import { documentTemplate } from "./document.tsx";
import { documentStyle } from "./document-style.ts";
import type { DocumentData } from "./types.ts";

export default defineDocumentProject<DocumentData>({
  id: "tenancy-renewal",
  name: "Tenancy Renewal",
  version: "1.0.0",
  template: documentTemplate,
  style: documentStyle,
  previewData: {
    residentName: "Avery Mitchell",
    propertyRef: "Flat 4, Ashcroft House",
  },
});

previewData is what the preview app resolves against. Keep it realistic — short names and placeholder cities hide layout problems that real data exposes.


Edit this page on GitHub ↗