> ## Documentation Index
> Fetch the complete documentation index at: https://react-docx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rendering

```tsx theme={"dark"}
import { render } from "@cordel/react-docx";

const { outputPath, diagnostics } = await render(<MyDocument />, "./output.docx");
```

Returns a `Promise<RenderResult>` with the output path and any diagnostics collected during rendering.

***

## Basic usage

```tsx theme={"dark"}
import { render, Document, Section, H1, Paragraph } from "@cordel/react-docx";

const MyDocument = () => (
  <Document>
    <Section>
      <H1>Hello</H1>
      <Paragraph>World</Paragraph>
    </Section>
  </Document>
);

const { outputPath, diagnostics } = await render(<MyDocument />, "./hello.docx");
```

***

## renderToBuffer

For serverless or HTTP scenarios where you don't want to write to disk:

```tsx theme={"dark"}
import { renderToBuffer } from "@cordel/react-docx";

const { buffer, diagnostics } = await renderToBuffer(<MyDocument />);
```

Returns a `Promise<RenderToBufferResult>` with a `Uint8Array` buffer and diagnostics.

### HTTP response

```tsx theme={"dark"}
const { buffer } = await renderToBuffer(<Invoice />);

res.setHeader(
  "Content-Type",
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
);
res.send(buffer);
```

### Write to file manually

```tsx theme={"dark"}
import fs from "node:fs";

const { buffer } = await renderToBuffer(<MyDocument />);
fs.writeFileSync("output.docx", buffer);
```

***

## Variables

Pass dynamic data to your document:

```tsx theme={"dark"}
await render(<Invoice />, "./invoice.docx", {
  variables: {
    invoiceNumber: "INV-001",
    customer: "Acme Corp",
    total: 420.00,
  },
});
```

### Variable component

```tsx theme={"dark"}
import { Variable } from "@cordel/react-docx";

const Invoice = () => (
  <Document>
    <Section>
      <H1>
        Invoice #<Variable name="invoiceNumber" />
      </H1>
      <Paragraph>
        Customer: <Variable name="customer" defaultValue="N/A" />
      </Paragraph>
    </Section>
  </Document>
);
```

### useVariables hook

For more control:

```tsx theme={"dark"}
import { useVariables } from "@cordel/react-docx";

const Invoice = () => {
  const vars = useVariables<{
    invoiceNumber: string;
    customer: string;
    total: number;
  }>();

  return (
    <Document>
      <Section>
        <H1>Invoice #{vars.invoiceNumber}</H1>
        <Paragraph>Customer: {vars.customer}</Paragraph>
        <Paragraph>
          <Text className="font-bold">Total: ${vars.total.toFixed(2)}</Text>
        </Paragraph>
      </Section>
    </Document>
  );
};
```

### Formatting

```tsx theme={"dark"}
<Variable
  name="price"
  format={(value) => `$${Number(value).toFixed(2)}`}
/>
```

***

## Render options

| Option           | Type                            | Description                                                          |
| ---------------- | ------------------------------- | -------------------------------------------------------------------- |
| `variables`      | `Record<string, VariableValue>` | Dynamic data passed to `Variable` components and `useVariables`      |
| `strict`         | `boolean`                       | Throw `StrictModeError` if any error-severity diagnostic is emitted  |
| `tailwindParser` | `TailwindParser`                | Custom parser for overriding colors, fonts, or adding class handlers |

```tsx theme={"dark"}
await render(<MyDocument />, "./output.docx", {
  variables: { name: "John" },
  strict: true,
});
```

***

## Diagnostics

Both `render` and `renderToBuffer` return a `diagnostics` array. These are structured warnings and errors collected during rendering — images that failed to load, invalid nesting, unsupported Tailwind classes, etc.

```tsx theme={"dark"}
const { outputPath, diagnostics } = await render(<MyDocument />, "./output.docx");

for (const d of diagnostics) {
  console.log(`[${d.severity}] ${d.code}: ${d.message}`);
}
```

### Diagnostic interface

```typescript theme={"dark"}
interface Diagnostic {
  code: string;                // e.g. "IMAGE_LOAD_FAILED"
  severity: "error" | "warning" | "info";
  message: string;
  element?: string;            // Component name, e.g. "Image"
  suggestion?: string;         // How to fix the issue
  path?: string;               // Tree path, e.g. "Document > Section > Td"
  url?: string;                // Link to documentation
}
```

### Common codes

| Code                          | Severity | Description                                   |
| ----------------------------- | -------- | --------------------------------------------- |
| `IMAGE_LOAD_FAILED`           | error    | Image file not found or URL unreachable       |
| `INVALID_NESTING`             | error    | Component placed in an unsupported parent     |
| `UNSUPPORTED_TAILWIND_CLASS`  | warning  | Tailwind class has no DOCX equivalent         |
| `TAILWIND_CONFIG_LOAD_FAILED` | warning  | Failed to parse tailwind.config file          |
| `VARIABLE_NOT_FOUND`          | info     | Variable not provided and no defaultValue set |

### Custom handler

Override how diagnostics are reported:

```tsx theme={"dark"}
import { setDiagnosticHandler } from "@cordel/react-docx";

setDiagnosticHandler((d) => {
  if (d.severity === "error") {
    console.error(`[${d.code}] ${d.message}`);
  }
});
```

Pass `null` to restore the default console-based handler:

```tsx theme={"dark"}
setDiagnosticHandler(null);
```

### Strict mode

Throws a `StrictModeError` if any diagnostic with `"error"` severity is emitted:

```tsx theme={"dark"}
import { render, StrictModeError } from "@cordel/react-docx";

try {
  await render(<MyDocument />, "./output.docx", { strict: true });
} catch (error) {
  if (error instanceof StrictModeError) {
    console.error("Document has errors:", error.message);
  }
}
```

Works with `renderToBuffer` too:

```tsx theme={"dark"}
const { buffer } = await renderToBuffer(<MyDocument />, { strict: true });
```

***

## Error handling

Three levels of error handling:

**Diagnostics** — non-fatal issues returned in the result. The document still generates.

```tsx theme={"dark"}
const { diagnostics } = await render(<MyDocument />, "./output.docx");
if (diagnostics.length > 0) {
  console.warn(`${diagnostics.length} issue(s) found`);
}
```

**Strict mode** — promote error-severity diagnostics to thrown exceptions.

```tsx theme={"dark"}
await render(<MyDocument />, "./output.docx", { strict: true });
```

**Try/catch** — handle unexpected failures (invalid JSX tree, filesystem errors, etc.).

```tsx theme={"dark"}
try {
  await render(<MyDocument />, "./output.docx");
} catch (error) {
  console.error("Failed:", error);
}
```

***

## Full example

```tsx theme={"dark"}
import {
  render,
  Document,
  Section,
  H1,
  Paragraph,
  Text,
  Table,
  Thead,
  Tbody,
  Tr,
  Th,
  Td,
  useVariables,
} from "@cordel/react-docx";

interface InvoiceData {
  number: string;
  date: string;
  customer: { name: string; email: string };
  items: { name: string; qty: number; price: number }[];
}

const Invoice = () => {
  const vars = useVariables<InvoiceData>();
  const total = vars.items.reduce((sum, item) => sum + item.qty * item.price, 0);

  return (
    <Document>
      <Section>
        <H1 className="text-blue-700">Invoice #{vars.number}</H1>

        <Paragraph className="mt-4">
          <Text className="font-bold">Date: </Text>{vars.date}
        </Paragraph>
        <Paragraph>
          <Text className="font-bold">Customer: </Text>{vars.customer.name}
        </Paragraph>

        <Table className="mt-6 border">
          <Thead>
            <Tr>
              <Th className="border p-2 bg-gray-100">Item</Th>
              <Th className="border p-2 bg-gray-100">Qty</Th>
              <Th className="border p-2 bg-gray-100">Price</Th>
            </Tr>
          </Thead>
          <Tbody>
            {vars.items.map((item, i) => (
              <Tr key={i}>
                <Td className="border p-2">{item.name}</Td>
                <Td className="border p-2">{item.qty}</Td>
                <Td className="border p-2">${item.price}</Td>
              </Tr>
            ))}
          </Tbody>
        </Table>

        <Paragraph className="mt-4 text-right">
          <Text className="text-xl font-bold">Total: ${total}</Text>
        </Paragraph>
      </Section>
    </Document>
  );
};

const { outputPath, diagnostics } = await render(<Invoice />, "./invoice.docx", {
  variables: {
    number: "INV-001",
    date: "2024-01-15",
    customer: { name: "Acme Corp", email: "billing@acme.com" },
    items: [
      { name: "Widget", qty: 10, price: 25 },
      { name: "Gadget", qty: 5, price: 50 },
    ],
  },
});

if (diagnostics.length > 0) {
  console.warn("Warnings:", diagnostics.map((d) => d.message));
}
```
