> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Expansion `/expand`

```ts
import { expandWikitext, WikitextExpandError } from "react-wikitext/expand";
```

`/expand` expands supported templates and pure wikitext parser functions before parsing. It loads the parser but not React. Expansion is asynchronous.

## Signature

```ts
function expandWikitext(
  source: string,
  options: WikitextExpandOptions,
): Promise<WikitextExpandedDocument>;
```

```ts
interface WikitextExpandOptions {
  parser?: WikitextParser;
  pageName?: string;
  parseOptions?: Omit<WikitextParseOptions, "pageName">;
  resolveTemplate: WikitextTemplateResolver;
  maxDepth?: number;
  maxInvocations?: number;
  maxExpandedLength?: number;
  strict?: boolean;
  signal?: AbortSignal;
}
```

| Option              | Default                                     | Description                                                                     |
| ------------------- | ------------------------------------------- | ------------------------------------------------------------------------------- |
| `parser`            | Default parser                              | Can inject a custom parser                                                      |
| `pageName`          | —                                           | Original page name                                                              |
| `parseOptions`      | —                                           | Shared by original and final parsing; `pageName` comes from the top-level field |
| `resolveTemplate`   | Required                                    | Template source resolver                                                        |
| `maxDepth`          | 40                                          | Nested depth                                                                    |
| `maxInvocations`    | 1,000                                       | Call count                                                                      |
| `maxExpandedLength` | Same as the original source limit (100,000) | Expanded source length                                                          |
| `strict`            | `false`                                     | Whether recoverable failures throw                                              |
| `signal`            | —                                           | Cancellation signal                                                             |

## Resolver

```ts
interface WikitextTemplateRequest {
  title: string;
  pageName?: string;
  callerTitle?: string;
  invocation: WikitextRange;
  signal?: AbortSignal;
}

type WikitextTemplateResolver = (
  request: WikitextTemplateRequest,
) => string | null | undefined | Promise<string | null | undefined>;
```

- `null` / `undefined` means the template is missing; an empty string is a valid template.
- A title is parsed once per expansion; the same `title` must return stable source.
- `callerTitle` is context only and does not participate in the cache key.
- `invocation` points at the top-level call range in `original.source`; nested requests reuse that range.
- The resolver performs remote fetching; the library makes no network requests.

## Result

```ts
interface WikitextExpandedDocument {
  original: WikitextDocument;
  document: WikitextDocument;
  expansion: WikitextExpansionInfo;
}

interface WikitextExpansionInfo {
  status: "complete" | "partial" | "fallback";
  records: readonly WikitextExpansionRecord[];
  diagnostics: readonly WikitextExpansionDiagnostic[];
}

interface WikitextExpansionRecord {
  kind: "template" | "parserFunction" | "argument";
  name: string;
  originalRange: WikitextRange;
  expandedRange: WikitextRange;
  status: "expanded" | "preserved";
}
```

- `original` is the parse snapshot of the original source.
- `document` is the parse snapshot of the expanded source and can be passed directly to `prepareWikitext`.
- `status`:
  - `complete`: all calls expanded.
  - `partial`: some calls were preserved or dependencies were unresolved.
  - `fallback`: the final source failed to parse, so the original snapshot was returned.
- `expansion.diagnostics` coordinates are based on `original.source`; `document.diagnostics` merges final parse diagnostics and mapped expansion diagnostics.

## What is expanded

Supported: template transclusion and parameters, include tags, `#if`, `#ifeq`, `#switch`, `#iferror`, `{{!}}`, `{{=}}`, and implicit newlines.

Preserved with diagnostics by default:

- `#invoke` and Lua.
- Transclusion modifiers such as `subst`.
- Functions that depend on site state or an external runtime, such as `#ifexist` and `#time`.

See the [template expansion guide](/guide/templates.md) for details.

## Budgets and failures

- A single over-long call is preserved with `LENGTH_BUDGET_EXCEEDED`.
- If even the preserved source exceeds `maxExpandedLength`, the call throws `EXPANSION_TOO_LARGE`.
- With `strict: true`, a budget overrun throws `EXPANSION_BUDGET_EXCEEDED`.
- By default, a final parse failure returns the original valid snapshot with `status: "fallback"`.
- Cancellation rejects with `WikitextExpandError` code `ABORTED`; the original reason is stored in `cause`.

`parseOptions.maxSourceLength`, template source length, and `maxExpandedLength` apply separately. Final parsing uses the effective `maxExpandedLength`.

## Errors

```ts
class WikitextExpandError extends WikitextError {
  readonly templateTitle?: string;
  readonly range?: WikitextRange;
  constructor(
    code: WikitextExpandErrorCode,
    message: string,
    options?: { cause?: unknown; templateTitle?: string; range?: WikitextRange },
  );
}
```

Common codes:

| Code                        | Condition                                               |
| --------------------------- | ------------------------------------------------------- |
| `INVALID_EXPAND_OPTIONS`    | Invalid options                                         |
| `INCOMPATIBLE_PARSER`       | Injected parser does not support expansion requirements |
| `TEMPLATE_NOT_FOUND`        | Missing template in strict mode                         |
| `TEMPLATE_RESOLVE_FAILED`   | Resolver failure in strict mode                         |
| `TEMPLATE_PARSE_FAILED`     | Template source parse failure in strict mode            |
| `TEMPLATE_LOOP`             | Loop detected in strict mode                            |
| `UNSUPPORTED_CALL`          | Unsupported call in strict mode                         |
| `UNRESOLVED_DEPENDENCY`     | Unresolved dependency in strict mode                    |
| `EXPANSION_BUDGET_EXCEEDED` | Budget overrun in strict mode                           |
| `EXPANSION_TOO_LARGE`       | Expanded or preserved source exceeds the length limit   |
| `FINAL_PARSE_FAILED`        | Final parse failure in strict mode                      |
| `ABORTED`                   | Cancelled through `signal`                              |

## With the view

```tsx
import { expandWikitext } from "react-wikitext/expand";
import { prepareWikitext } from "react-wikitext/hast";
import { WikitextView } from "react-wikitext/view";

const expanded = await expandWikitext(source, { resolveTemplate });
const prepared = prepareWikitext(expanded.document);
const view = <WikitextView document={prepared} />;
```

The expanded document is already parsed; do not parse it again. Calls preserved after a failed expansion still render as template, function, or argument placeholders.
