Docs/Takumi rendering

Takumi rendering

Use the optional Takumi base when you want to author PDF layouts with HTML and CSS. Vue renders the document to escaped HTML, then Takumi produces the PDF bytes.

Install the base

bash

npx shadcn-vue@latest add @pdfcn-vue/takumi-core @pdfcn-vue/theme-minimal

Configure the @pdfcn-vue namespace as shown in the installation guide. The item installs Takumi, Vue's server renderer, HTML primitives, and the shared theme helpers.

Core component API

Text, Heading, Stack, Section, Divider, PageBreak, KeepTogether, Link, and PdfList keep the Forme core components' props and slots. PdfcnThemeProvider and all nine theme presets work with both bases. Document and View render HTML containers; Image and Svg render images.

Use the Takumi entrypoint throughout a document. Forme's data components, document chrome, fillable fields, and block templates use Forme primitives and remain on the Forme path. For custom Takumi layouts, native HTML tables and CSS can sit alongside the core components.

TakumiDocument.vue

<script setup lang="ts">
  import {
    Document,
    Heading,
    Text,
    Stack,
    Section,
    Divider,
    PageBreak,
    KeepTogether,
    Link,
    PdfList,
    PdfcnThemeProvider,
  } from '@/lib/pdfcn/takumi/index';
  import { minimalTheme } from '@/lib/pdfcn/themes/minimal';

  defineProps<{ recipient?: string }>();
</script>

<template>
  <PdfcnThemeProvider :theme="minimalTheme">
    <Document>
      <Heading>Takumi document</Heading>
      <Stack gap="sm">
        <Text>{{ recipient }}</Text>
        <Section variant="card"><Text>First page content</Text></Section>
        <Divider />
        <Link href="https://example.com">Example link</Link>
        <KeepTogether><Text>Keep this together</Text></KeepTogether>
        <PdfList :items="[{ text: 'First item' }, { text: 'Second item' }]" />
        <PdfList
          :items="[{ text: 'Done', checked: true }]"
          variant="checklist"
        />
      </Stack>
      <PageBreak />
      <Heading :level="2">Second page</Heading>
      <Text>Last page content</Text>
    </Document>
  </PdfcnThemeProvider>
</template>

Render on the server

Import takumi-pdf once to initialize its Node WASM build. renderTakumi accepts a Vue VNode and Takumi's render options, and returns a Uint8Array. serializeTakumi returns HTML if you need to inspect the layout or use your own renderer instance.

ts

import 'takumi-pdf'
import { h } from 'vue'
import { renderTakumi } from '@/lib/pdfcn/takumi/index'
import TakumiDocument from './TakumiDocument.vue'

const bytes = await renderTakumi(h(TakumiDocument, { recipient: 'Vue server render' }), {
  size: 'letter',
  margin: 48,
})

Render in the browser

Initialize the no-init entrypoint with Vite's emitted WASM URL before rendering. Create and revoke blob URLs as described in the rendering guide.

ts

import init from 'takumi-pdf/no-init'
import wasmUrl from 'takumi-pdf/takumi_pdf_wasm_bg.wasm?url'
import { h } from 'vue'
import { renderTakumi } from '@/lib/pdfcn/takumi/index'
import TakumiDocument from './TakumiDocument.vue'

await init({ module_or_path: wasmUrl })
const bytes = await renderTakumi(h(TakumiDocument, { recipient: 'Vue browser render' }))
const blob = new Blob([new Uint8Array(bytes)], { type: 'application/pdf' })

Units and engine differences

Core component dimensions and theme tokens stay in PDF points. The HTML bridge emits pt lengths, expands horizontal and vertical spacing, and preserves unitless font weights and line heights. Styles accept scalar values: numbers use points and CSS strings keep their units. Use separate edge properties for padding, margins, and borders instead of Forme edge objects or arrays. Takumi's render options use CSS pixels at 96 dpi: 48 px is 36 pt. Page geometry comes from render options, rather than a Forme Page component or CSS @page rules.

Register fonts through Takumi's fonts option or PdfRenderer. Forme's font registry does not configure Takumi. Supported CSS, pagination, and PDF features differ between engines; check the Takumi PDF documentation for its current capabilities.

Edit the theme tokens

Try the theme builder