Takumi

Headers & footers

Repeat bands on every page with page counters.

header and footer accept any node input. They repeat on every page. Bands lay out at full page width and draw in the page margin areas, like Chromium's print templates. Pick a margin at least as tall as the band, or the band overlaps content, exactly as in Chromium.

import {  } from "takumi-pdf";

const  = await (, {
  : (
    < ="flex w-full justify-center text-[10px] text-gray-500">
      Page < ="pageNumber" /> of < ="totalPages" />
    </>
  ),
});

Sizing the margin

Band height depends on layout, so it is hard to guess ahead of time. measure lays out a tree the same way render measures a band: full page width, counter hooks filled with three-digit numbers. Use the height to pick a margin:

import { ,  } from "takumi-pdf";

const  = (
  < ="flex w-full justify-center text-[10px] text-gray-500">
    Page < ="pageNumber" /> of < ="totalPages" />
  </>
);
const {  } = await (, { : "a4" });
const  = await (, {
  ,
  : { : 48, : .(48,  + 20) },
});

Bands sit 20px in from the paper edge, so leave that on top of the measured height.

Passing viewport instead of a page size measures the tree as-is. Counter hooks stay empty.

Page counters

Text and container nodes classed pageNumber or totalPages receive counter text. The counter replaces what the node holds, so an empty <span /> is enough. Chromium's print templates use the same two names.

ClassValue
pageNumberThe current page, counting from 1
totalPagesThe number of pages in the document

A node carrying both classes gets the page number.

Counter styles

Add a CSS @counter-style name next to the hook class. It formats the number. The first supported name wins. Unsupported names are ignored, and a hook without one counts in decimal.

import {  } from "takumi-pdf";

const  = await (, {
  : (
    < ={{ : 12 }}>
      第 < ="pageNumber trad-chinese-informal" /> 頁,共{" "}
      < ="totalPages trad-chinese-informal" /> 頁
    </>
  ),
});

Numbers and numerals

StylePage 7Page 12
decimal (default)712
decimal-leading-zero0712
lower-romanviixii
upper-romanVIIXII
cjk-decimal一二
trad-chinese-informal十二
cjk-ideographic十二

Blink defines cjk-ideographic as an extension of trad-chinese-informal, and this renderer follows it. Both read out numbers up to 9999. Past that they fall back to cjk-decimal, so page 10000 formats as 一零零零零.

Alphabets

These styles count the way a spreadsheet names its columns. The letter after z is aa.

StylePage 12
lower-alpha, lower-latinl
upper-alpha, upper-latinL
lower-greekμ
hiragana
katakana

Other digits

These styles write the decimal number in another script's digits.

StylePage 12StylePage 12
arabic-indic١٢mongolian᠑᠒
bengali১২myanmar၁၂
cambodian១២oriya୧୨
devanagari१२persian۱۲
gujarati૧૨tamil௧௨
gurmukhi੧੨telugu౧౨
kannada೧೨thai๑๒
khmer១២tibetan༡༢
lao໑໒urdu۱۲
malayalam൧൨

khmer and cambodian share their digits, as do persian and urdu.

A registered font has to cover the digits of the style you pick. Latin fonts rarely carry Thai or Tibetan numerals, so pair a script style with a font that has the glyphs.

Band height

Band height is measured once with three-digit counters. Reaching 100 pages does not shift the layout between pages.

Last updated on

On this page