Skip to main content
Programmatic API for customizing how Tailwind classes map to DOCX properties. Use this when a tailwind.config file isn’t enough — custom handlers, brand colors at runtime, or replacing built-in behavior.
import { createTailwindParser, render } from "@cordel/react-docx";

const parser = createTailwindParser({
  colors: {
    brand: { 500: "0F4C81", 100: "E8F0FE" },
  },
});

await render(<MyDocument />, "./output.docx", { tailwindParser: parser });

createTailwindParser

Factory function that returns a TailwindParser instance:
import { createTailwindParser } from "@cordel/react-docx";

const parser = createTailwindParser(options);
You can also use the class directly:
import { TailwindParser } from "@cordel/react-docx";

const parser = new TailwindParser(options);

Options

OptionTypeDescription
colorsRecord<string, Record<number, string>>Custom color palette. Merged with built-in colors.
fontSizesRecord<string, number>Custom font sizes (in half-points). Merged with built-ins.
fontFamiliesRecord<string, string>Custom font families. Merged with built-ins.
extraHandlersClassHandler[]Custom handlers prepended to the pipeline. Run before built-ins.
replacedHandlersPartial<Record<HandlerName, ClassHandler>>Replace specific built-in handlers by name.

Custom colors

const parser = createTailwindParser({
  colors: {
    brand: {
      50: "EFF6FF",
      100: "DBEAFE",
      500: "3B82F6",
      700: "1D4ED8",
      900: "1E3A8A",
    },
    accent: {
      500: "F59E0B",
    },
  },
});
Then use in your document:
<Text className="text-brand-500">Brand blue</Text>
<Paragraph className="bg-accent-500">Accent background</Paragraph>
Color values are hex strings without the # prefix.

Custom fonts

const parser = createTailwindParser({
  fontFamilies: {
    "font-heading": "Georgia",
    "font-code": "Fira Code",
  },
});
<Text className="font-heading">Georgia heading</Text>
<Text className="font-code">Monospace code</Text>

Custom handlers

A ClassHandler is a function that processes a Tailwind class and writes the result:
type ClassHandler = (
  cls: string,
  result: TailwindParseResult,
  config: ParseConfig,
) => boolean;
Return true if the class was handled, false to pass it to the next handler.

Adding extra handlers

Extra handlers run before the built-in pipeline:
import { createTailwindParser } from "@cordel/react-docx";

const highlightHandler = (cls, result) => {
  if (cls === "highlight") {
    result.textStyles.backgroundColor = "FFFF00";
    result.textStyles.bold = true;
    return true;
  }
  return false;
};

const parser = createTailwindParser({
  extraHandlers: [highlightHandler],
});
<Text className="highlight">Yellow bold text</Text>

Replacing built-in handlers

Override a specific handler by name. You can delegate to the original via defaultHandlerMap:
import { createTailwindParser, defaultHandlerMap } from "@cordel/react-docx";

const parser = createTailwindParser({
  replacedHandlers: {
    borders: (cls, result, config) => {
      // Custom logic for a specific class
      if (cls === "border-brand") {
        result.tableCellStyles.borders = {
          all: { width: 4, style: "single", color: "0F4C81" },
        };
        return true;
      }
      // Fall back to default for everything else
      return defaultHandlerMap.borders(cls, result, config);
    },
  },
});

Handler names

All built-in handlers that can be replaced:
NameHandles
textFormattingBold, italic, underline, strike, caps
textColortext-{color}-{shade} classes
backgroundColorbg-{color}-{shade} classes
textAlignmenttext-left, text-center, text-right, text-justify
spacingmt-*, mb-*, ml-*, mr-*, indent-*
lineHeightleading-* classes
letterSpacingtracking-* classes
bordersborder-* classes (width, style, color, sides)
tableCellPaddingp-*, px-*, py-*, pt-*, pb-*
tableCellAlignmentalign-top, align-middle, align-bottom
sizingw-*, h-* for images
objectFitobject-cover, object-contain, object-fill
customAspectRatioaspect-* classes
arbitraryColortext-[#hex], bg-[#hex]
arbitraryFontSizetext-[14px], text-[12pt]

TailwindParseResult

The result object that handlers write to:
interface TailwindParseResult {
  textStyles: TextStyles;
  paragraphStyles: ParagraphStyles;
  genericStyles: GenericStyles;
  tableCellStyles: TableCellStyles;
}
Each field maps to a group of DOCX properties. Handlers set individual properties on these objects.

Passing to render

Pass your parser to render or renderToBuffer:
const parser = createTailwindParser({ /* ... */ });

await render(<MyDocument />, "./output.docx", {
  tailwindParser: parser,
});

// or
const { buffer } = await renderToBuffer(<MyDocument />, {
  tailwindParser: parser,
});
When no parser is provided, a default instance is used that loads from your tailwind.config file automatically.