For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /guide/recipes.md.
  • English
  • Recipes

    These snippets use only public APIs and omit the host's own data loading and error handling. Component overrides, resolvers, and plugins are trusted code; review them against the security model before shipping.

    Site theme and dark mode

    Styles are driven by CSS variables. Classes and attributes on the container can participate in selectors:

    .wiki-article {
      --wtr-text: #1f2328;
      --wtr-accent: #0969da;
      --wtr-border: #d0d7de;
      --wtr-placeholder-bg: #f6f8fa;
    }
    
    .wiki-article[data-theme="dark"] {
      --wtr-text: #e6edf3;
      --wtr-accent: #4493f8;
      --wtr-border: #30363d;
      --wtr-placeholder-bg: #161b22;
    }
    import { Wikitext } from "react-wikitext";
    import "react-wikitext/styles.css";
    
    <Wikitext source={source} className="wiki-article" containerProps={{ "data-theme": theme }} />;

    The same source in light and dark themes:

    Theme example

    Body text, emphasis, and a link.

    Template not expanded: Infobox
    • title=Template placeholder

    Theme example

    Body text, emphasis, and a link.

    Template not expanded: Infobox
    • title=Template placeholder
    import { Wikitext } from "react-wikitext";
    import "react-wikitext/styles.css";
    
    const source = `== Theme example ==
    '''Body text''', ''emphasis'', and a [[link]].
    
    {{Infobox|title=Template placeholder}}`;
    
    const css = `
    .recipe-theme {
      --wtr-text: #1f2328;
      --wtr-muted: #57606a;
      --wtr-border: #d0d7de;
      --wtr-accent: #0969da;
      --wtr-accent-soft: #ddf4ff;
      --wtr-placeholder-bg: #f6f8fa;
      padding: 12px;
      border: 1px solid #d0d7de;
      border-radius: 8px;
      background: #ffffff;
    }
    .recipe-theme--dark {
      --wtr-text: #e6edf3;
      --wtr-muted: #8b949e;
      --wtr-border: #30363d;
      --wtr-accent: #58a6ff;
      --wtr-accent-soft: #172a45;
      --wtr-placeholder-bg: #161b22;
      border-color: #30363d;
      background: #0d1117;
    }
    .recipe-theme + .recipe-theme { margin-top: 12px; }
    `;
    
    export default function Demo() {
      return (
        <div>
          <style>{css}</style>
          <div className="recipe-theme">
            <Wikitext source={source} lang="en" />
          </div>
          <div className="recipe-theme recipe-theme--dark">
            <Wikitext source={source} lang="en" />
          </div>
        </div>
      );
    }

    See Styling and components for the variable list.

    Site routes and an image CDN

    Leave routing and media URLs to the host; the library only validates and renders. Define resolvers at module scope so preparation is not repeated:

    import type { WikitextImageResolver, WikitextLinkResolver } from "react-wikitext/hast";
    
    const resolveLink: WikitextLinkResolver = (request) => {
      if (request.kind !== "internal") return undefined;
      const page = request.page ?? request.target;
      const fragment = request.fragment ? `#${request.fragment}` : "";
      return { href: `/wiki/${encodeURIComponent(page)}${fragment}`, target: "_self" };
    };
    
    const resolveImage: WikitextImageResolver = (request) => ({
      src: `https://cdn.example.com/wiki/${encodeURIComponent(request.name)}`,
      alt: request.alt ?? request.name,
      ...(request.width === undefined ? {} : { width: request.width }),
      ...(request.height === undefined ? {} : { height: request.height }),
    });
    <Wikitext source={source} prepareOptions={{ resolveLink, resolveImage }} lang="en" />

    Return-value semantics and policy are in Links and images.

    Template cards

    Do not expand templates, but render the invocation as a site-specific card:

    import { Wikitext } from "react-wikitext";
    import { WikitextFragment, type WikitextTemplateComponentProps } from "react-wikitext/view";
    import "react-wikitext/styles.css";
    
    function TemplateCard({ displayName, node }: WikitextTemplateComponentProps) {
      return (
        <aside style={{ border: "1px solid #d0d7de", borderRadius: 8, padding: 12, margin: "8px 0" }}>
          <strong>{displayName}</strong>
          <WikitextFragment nodes={node.children} mode="block" />
        </aside>
      );
    }
    
    export default function Demo() {
      return (
        <Wikitext
          source={"{{Infobox|title=Example|body=Template arguments appear in the card}}"}
          lang="en"
          semanticComponents={{ template: TemplateCard }}
        />
      );
    }

    WikitextFragment must be used inside the WikitextView context and can only render nodes from the current document.

    Article table of contents

    The library does not have to own the TOC. For a site sidebar, read headings from the render snapshot and pin the anchor strategy:

    import { useMemo } from "react";
    import { createWikiparser } from "react-wikitext/parse";
    import { prepareWikitext } from "react-wikitext/hast";
    import { WikitextView } from "react-wikitext/view";
    import "react-wikitext/styles.css";
    
    const parser = createWikiparser();
    
    export function Article({ source }: { source: string }) {
      const prepared = useMemo(
        () => prepareWikitext(parser.parse(source), { headingIdStrategy: "mediawiki" }),
        [source],
      );
    
      return (
        <div className="article-layout">
          <nav aria-label="Contents">
            <ol>
              {prepared.headings.map((heading) => (
                <li key={heading.nodeId} data-level={heading.level}>
                  {heading.id ? <a href={`#${heading.id}`}>{heading.text}</a> : heading.text}
                </li>
              ))}
            </ol>
          </nav>
          <WikitextView document={prepared} />
        </div>
      );
    }
    • The mediawiki strategy writes bare anchors and assumes a single instance per page.
    • For multiple instances, keep the default instance strategy; inside the view, use useWikitextIds().toHref to get the real link.
    • The in-page TOC is still generated; to keep only the sidebar, hide .wtr-toc with host CSS or use __NOTOC__ in the source.

    Reporting render failures

    The view isolates failures per top-level block; parse and prepare errors belong to the caller:

    import type { WikitextDocument } from "react-wikitext/ast";
    import type { WikitextPrepareOptions } from "react-wikitext/hast";
    import { prepareWikitext, WikitextPrepareError } from "react-wikitext/hast";
    import { WikitextView } from "react-wikitext/view";
    
    function renderPrepared(document: WikitextDocument, prepareOptions: WikitextPrepareOptions) {
      try {
        return <WikitextView document={prepareWikitext(document, prepareOptions)} />;
      } catch (error) {
        if (error instanceof WikitextPrepareError) {
          report(error.code, error.stage, error.cause);
        }
        throw error;
      }
    }
    <Wikitext
      source={source}
      onRenderError={(error, { node }) => {
        report("render", error, { nodeId: node.id, nodeType: node.type });
      }}
    />

    labels.renderFailed controls the block placeholder title; see Errors and diagnostics.