# Tools

Which tools the viewer offers. Set a tool to `false` and it is gone: not on the toolbar, not in the selection bar, and `viewer.activateTool()` refuses it with `INVALID_ARGUMENT`. Absent means on — within the mode: `true` cannot add a tool the mode does not offer (see [SDKMode](https://kernstra.com/docs/web-sdk/config/mode)). Select, Pan and Search are there in every mode unless set to `false`. Five tools — `sign`, `editText`, `stamp`, `image` and `erase` — also take an object for their own settings; `true` is the same as `{}`.

Each tool also needs its license feature: the drawing, mark-up, Sign, Image, Stamp, Link, Note, Text box and Erase tools need `annotations`, Edit Text needs `edit-text`, Add Text needs `add-text`, Manage Pages needs `edit-pages` and Security needs `export`. Select, Pan and Search need no feature. Without any feature a valid license still opens and renders documents, navigates, zooms, searches from the toolbar and undoes; nothing that changes the document is in that list.

- Interface: `ToolsConfig`
- Config path: `config.tools`

## Example

```ts
new PDFViewer(container, doc, {
  tools: {
    stamp: { builtIn: true, custom: [{ label: 'Logo', url: '/stamps/logo.png' }] },
    sign: { draw: true, type: false, upload: false },
    image: { maxBytes: 2 * 1024 * 1024, types: ['image/png', 'image/jpeg'] },
    erase: { minSize: 4, maxSize: 32, defaultSize: 12 },
    link: false,
    security: false,
  },
});
```

## Options (45)

### `selectText`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/selecttext

Select pointer mode and the selection's markup bar. Present in every mode unless set to `false`. Needs no license feature. It is the resting tool by default (see [`defaultTool`](https://kernstra.com/docs/web-sdk/config/mode/defaulttool)); `selectText: false` with a Select rest leaves no tool active.

```ts
tools: { selectText: false }
```

### `pan`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/pan

Pan pointer mode: drag to scroll, a click selects an annotation; links are not followed in Pan. Present in every mode unless set to `false`. Needs no license feature.

### `search`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/search

Text search. Present in every mode unless set to `false`. Needs no license feature from the toolbar; the selection bar's **Search for this** also needs a license that lets the words leave the viewer (the `extract` feature, or a production license's clean output).

### `highlight`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/highlight

Area highlight tool. Needs the `annotations` license feature.

### `textHighlight`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/texthighlight

Text selection highlight tool. Needs the `annotations` license feature. The selection bar's Highlight, Comment, Underline, Squiggly underline, Strikethrough and Black out follow it (Comment also needs the Comments panel, editable).

### `note`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/note

Sticky note tool. Needs the `annotations` license feature. The selection bar's **Add a note** follows it.

### `freeText`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/freetext

Text box: a free-text comment on the page. Needs the `annotations` license feature (new text written into the page as page content is `addText`, which is `add-text`).

### `draw`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/draw

Freehand drawing tool. Needs the `annotations` license feature.

### `rectangle`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/rectangle

Rectangle drawing tool. Needs the `annotations` license feature.

### `ellipse`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/ellipse

Ellipse drawing tool. Needs the `annotations` license feature.

### `line`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/line

Line drawing tool. Needs the `annotations` license feature.

### `arrow`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/arrow

Arrow drawing tool. Needs the `annotations` license feature.

### `polygon`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/polygon

Polygon drawing tool: click the corners, close on the first. Needs the `annotations` license feature.

### `polyline`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/polyline

Polyline drawing tool: click the corners, finish on the last. Needs the `annotations` license feature.

### `check`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/check

Marks menu: a tick placed with one click, in the Marks bar's ink and size (pen-dark and 20 pt to start). Needs the `annotations` license feature. `check`, `cross` and `dot` are tools of their own, so a host offers the three, two or none; the Marks menu goes with its last member.

### `cross`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/cross

Marks menu: a cross placed with one click. Needs the `annotations` license feature.

### `dot`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/dot

Marks menu: a dot placed with one click. Needs the `annotations` license feature.

### `erase`

- Type: `boolean | EraseConfig`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/erase

Universal eraser tool; it can remove the page's own content. Needs the `annotations` license feature. Takes an `EraseConfig` object (or `true`, the same as `{}`) for the brush sizes, in points. A `minSize`, `maxSize` or `defaultSize` that is not a positive number keeps its default. A `maxSize` below `minSize` is raised to it, and a `defaultSize` outside them is brought inside; each correction is reported with a console warning.

```ts
tools: { erase: { minSize: 4, maxSize: 32, defaultSize: 12 } }
```

#### `erase.minSize`

- Type: `number`
- Default: `6`
- Page: https://kernstra.com/docs/web-sdk/config/tools/erase-minsize

Smallest brush, in points.

#### `erase.maxSize`

- Type: `number`
- Default: `64`
- Page: https://kernstra.com/docs/web-sdk/config/tools/erase-maxsize

Largest brush, in points. One below `minSize` is raised to it.

#### `erase.defaultSize`

- Type: `number`
- Default: `24`
- Page: https://kernstra.com/docs/web-sdk/config/tools/erase-defaultsize

Brush a session starts with, in points. One outside `minSize`–`maxSize` is brought inside.

### `editText`

- Type: `boolean | EditTextConfig`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/edittext

Edit Text tool (inline PDF text editing): retyping and restyling the document's own text. Needs the `edit-text` license feature (opening or retyping a block from code, through `viewer.tools.editText`, also needs `extract`). Takes an `EditTextConfig` object; passing `true` is the same as `{}`. See [EditTextToolApi](https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext) for the programmatic side.

```ts
// One block per paragraph is the default and the recommended grouping: nothing to set.
tools: { editText: true }
```

#### `editText.blockDetection`

- Type: `'rows' | 'paragraphs'`
- Default: `'paragraphs'`
- Page: https://kernstra.com/docs/web-sdk/config/tools/edittext-blockdetection

How text is grouped into editable blocks. **Keep the default, `'paragraphs'`**: it is what Edit Text is built around. It makes one block per paragraph: the consecutive lines of one column that share leading and face are selected, moved and edited together, while columns, bullets, headings, table rows and lone numbers stay apart; a tagged document's own paragraph elements settle the grouping where it has them. Typing inside a paragraph reflows it within its box: words flow onto the next line and back, Enter starts a new line, every word keeps its own font, size and color, and a changed line keeps the paragraph's alignment, justified spacing included.

`'rows'` is an alternative, not an improvement: it makes one block per visual row, split where a gap reads as a column boundary, so each line of a paragraph is its own block and is selected, moved and edited on its own.

- `'paragraphs'`: Default, and recommended. One block per paragraph; typing reflows the paragraph within its box.
- `'rows'`: One block per visual row, split where a gap reads as a column boundary; a paragraph's lines are edited one at a time.

### `addText`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/addtext

Add Text tool: new text written into the page as page content. Needs the `add-text` license feature (the Text box tool, a comment on top of the page, is `freeText` under `annotations`).

### `sign`

- Type: `boolean | SignatureConfig`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign

Signature tool. Needs the `annotations` license feature (signing a form's signature field needs `forms`). Sign is also offered in `'form-fill'` mode, for your own button. The same dialog opens from the Sign tool and from a form's signature fields, so `tools.sign` shapes both. `true` is the same as `{}`: every tab, the built-in faces. With one tab left the dialog shows no tab strip. With every tab off there is no way to make a signature: the Sign tool is hidden and signature fields are read-only. `tools.sign: false` only hides the tool — form signature fields still open the full dialog.

A signature made in a form's signature field is saved as that field's appearance, cropped to its ink so it fills the field: every reader shows it in the field and prints it, the export's [`flatten`](https://kernstra.com/docs/web-sdk/config/export/flatten) locks it into the page with the other fields, and the field stays a signature field. It is an electronic signature, not a digital one — nothing is written as the field's signature value, so the file claims no digital signature, and a digital ID applied later in another application replaces the picture. The SDK never draws over a field that holds a digital signature, nor into a read-only or hidden one. A field that already shows a signature (saved by the SDK or another application) shows it as the page draws it, without the "Sign here" prompt, and can be signed again; one that holds a digital signature cannot (`FormFieldInfo.signature`). To replace the dialog entirely, see [`callbacks.onSignatureRequest`](https://kernstra.com/docs/web-sdk/config/callbacks/onsignaturerequest).

```ts
import { SIGNATURE_FONTS } from '@kernstra/pdf-web-sdk';

tools: {
  sign: {
    upload: false,
    fonts: [...SIGNATURE_FONTS, { family: "'Acme Script', cursive", label: 'Acme' }],
  },
}
```

#### `sign.draw`

- Type: `boolean`
- Default: `true`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-draw

Offer the Draw tab.

#### `sign.type`

- Type: `boolean`
- Default: `true`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-type

Offer the Type tab.

#### `sign.upload`

- Type: `boolean`
- Default: `true`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-upload

Offer the Upload tab.

#### `sign.fonts`

- Type: `readonly SignatureFont[]`
- Default: `SIGNATURE_FONTS`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-fonts

Faces the Type tab offers. Each `SignatureFont` is `{ family, label }`: `family` a CSS font-family value — load the face yourself (`@font-face`) — and `label` the name shown beside the preview. `fonts` replaces the Type tab's faces, in order; an empty list keeps the default. The built-in faces' names ("Standard", "Script", …) follow the viewer's language when you pass the `SIGNATURE_FONTS` objects themselves — spread the constant; a face you describe yourself shows the `label` you gave it.

#### `sign.inks`

- Type: `ColorList`
- Default: `black, navy, blue, red`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-inks

Inks a signature can be written in, first ink selected. A `ColorList` is a list of hex strings or `{ color, label }` color options (see [Annotations](https://kernstra.com/docs/web-sdk/config/annotations)).

#### `sign.savedSignatures`

- Type: `readonly SavedSignature[]`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-savedsignatures

Signatures to offer for reuse, restored. The dialog keeps up to three signatures the user chose to save; they last for the session unless you keep them — store what the [`savedSignaturesChanged`](https://kernstra.com/docs/web-sdk/api/events#ev-savedsignatureschanged) event gives you and pass it back here. The list is shared by every viewer on the page. See [What you can replace](https://kernstra.com/docs/web-sdk/guides/replace).

#### `sign.webFonts`

- Type: `boolean`
- Default: `false`
- Page: https://kernstra.com/docs/web-sdk/config/tools/sign-webfonts

Fetch the Type tab's script faces from Google Fonts. Beside its plain Standard face, the Type tab offers four script faces (Dancing Script, Great Vibes, Pacifico, Sacramento). By default they are **not** fetched: each renders in a handwriting face the operating system ships (Snell Roundhand, Apple Chancery, Marker Felt and Savoye on a Mac; Segoe Script, Lucida Handwriting, Segoe Print and Lucida Calligraphy on Windows, or Office's Edwardian Script and Monotype Corsiva where they are installed), and the dialog makes no network request, which keeps the SDK's no-Google-Fonts guarantee intact. Set it where a request to Google is acceptable to you and your users, and add `https://fonts.googleapis.com` to `style-src` and `https://fonts.gstatic.com` to `font-src`. Either way the dialog never waits on the font host; faces that have not arrived by the time a signature is placed fall back to the system face for that signature.

It is read from `tools.sign` as an object: with `tools.sign: false` the faces stay off for a form's signature fields too. To hide the tool and keep them, leave `tools.sign` on and drop the tool from [`toolbar.groups`](https://kernstra.com/docs/web-sdk/config/toolbar/groups).

```ts
tools: { sign: { webFonts: true } }
```

### `image`

- Type: `boolean | ImageConfig`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/image

Image insertion tool; it writes into the page itself. Needs the `annotations` license feature. Takes an `ImageConfig` object (or `true`, the same as `{}`). `types` narrows what the Image tool accepts — the picker's file filter, its fine print ("PNG or JPEG · up to 2 MB") and the check on a chosen or supplied file all follow it.

```ts
tools: { image: { maxBytes: 2 * 1024 * 1024, types: ['image/png', 'image/jpeg'] } }
```

#### `image.maxBytes`

- Type: `number`
- Default: `10 MB`
- Page: https://kernstra.com/docs/web-sdk/config/tools/image-maxbytes

The largest file accepted, in bytes. Whatever its size, an image whose header claims over 64 million pixels, or a side over 16384 px, is refused before it is decoded. A value that is not a positive number keeps the default.

#### `image.types`

- Type: `readonly string[]`
- Default: `PNG, JPEG, GIF, WebP, BMP`
- Page: https://kernstra.com/docs/web-sdk/config/tools/image-types

MIME types accepted. A type outside the default five (SVG, for one) is refused whatever the list says. Types match without regard to case; a list with nothing valid left keeps the default five.

### `stamp`

- Type: `boolean | StampConfig`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp

Stamp tool. Needs the `annotations` license feature. Takes a `StampConfig` object (or `true`, the same as `{}`). With `builtIn` and `builder` off and neither `custom` nor a valid preset there is nothing to place, and the Stamp tool is hidden.

A picture stamp is kept as a PNG `data:` URL, and one lifted from a page is part of that document — so whatever stores the list holds a copy of it. A region is lifted with at most two megapixels (a seal-sized one at 432 dpi): a lift of a whole scanned page can take a few megabytes, past what `localStorage` holds in some browsers. Size the store for it, and keep the list for the session only where documents are confidential. A kept stamp larger than a PDF page (14,400 points a side) or a wording longer than 32 characters is skipped when restored.

```ts
// Your own wording stamps instead of the English set
tools: {
  stamp: {
    builtIn: false,
    presets: [
      { label: 'GENEHMIGT', color: '#2E7D32' },
      { label: 'EINGANG', color: '#C62828', dated: true, border: 'ribbon' },
    ],
  },
}
```

#### `stamp.builtIn`

- Type: `boolean`
- Default: `true`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp-builtin

Show the tick, cross and dot, the standard set and RECEIVED with today's date. With `builtIn: false`, `presets` are listed alone.

#### `stamp.builder`

- Type: `boolean`
- Default: `true`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp-builder

"New stamp" and the stamps made with it. `builder: false` takes "New stamp" and the stamps made with it off the picker.

#### `stamp.custom`

- Type: `{ label: string; url: string }[]`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp-custom

Your own stamp images, listed under **Yours** next to the stamps the user makes, at their own proportions and at most 200 pt wide. A `data:` URL whose header claims a raster too large to decode (over 64 million pixels, or a side over 16384 px) is left out with a console warning. A stamp image `url` on another origin needs that origin in `connect-src` or `img-src`.

```ts
tools: { stamp: { builtIn: true, custom: [{ label: 'Logo', url: '/stamps/logo.png' }] } }
```

#### `stamp.presets`

- Type: `readonly StampPreset[]`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp-presets

Your own wording stamps, listed with the standard set — the words are written into the document exactly as you give them, so give them in your users' language — after the standard set (a `dated` one under "With today's date"), or alone with `builtIn: false`. They cannot be removed from the picker. A `StampPreset` is `{ label, color?, dated?, border? }`: `label` the wording (e.g. `'PAID'`, `'BEZAHLT'`), `color` a hex ink (default: the first of `inks`), `dated` adds the placing date under the wording (default `false`), `border` is `'boxed'` (default), `'ribbon'` or `'plain'`. A `label` is trimmed; one left empty is skipped with a console warning, as is one whose `color` is not a hex color (only a preset with no `color` at all takes the first ink). `#rgb` is expanded to `#RRGGBB`.

#### `stamp.inks`

- Type: `ColorList`
- Default: `red, blue, green, black`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp-inks

The inks "New stamp" offers. A `ColorList` is a list of hex strings or color options (see [Annotations](https://kernstra.com/docs/web-sdk/config/annotations)).

#### `stamp.userStamps`

- Type: `readonly SavedStamp[]`
- Page: https://kernstra.com/docs/web-sdk/config/tools/stamp-userstamps

Stamps the user made before, to restore. Stamps made with "New stamp" last for the session; to keep them, store what the [`userStampsChanged`](https://kernstra.com/docs/web-sdk/api/events#ev-userstampschanged) event gives you and pass it back here. At most eight are kept, shared by every viewer on the page. See [What you can replace](https://kernstra.com/docs/web-sdk/guides/replace).

### `link`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/link

Link annotation tool (URL + internal page). Needs the `annotations` license feature. The links already written into the document are configured under [Links](https://kernstra.com/docs/web-sdk/config/links).

### `managePages`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/managepages

Page management panel. Needs the license's `edit-pages` feature. It opens only when the document can be saved for its Cancel to go back to; otherwise the viewer reports `INVALID_STATE` and it stays closed. Page editing from the thumbnails (rotate, move, duplicate, delete) follows `managePages` the same way, so it too needs `edit-pages`. **Extract pages** inside Manage Pages also needs `export`.

### `security`

- Type: `boolean`
- Default: `on, within the mode`
- Page: https://kernstra.com/docs/web-sdk/config/tools/security

Passwords and permissions. Needs the license's `export` feature: protection is part of the saved file. Without `export` there is no owner-password prompt: unlock a restricted document with `doc.security.unlockOwnerPermissions()`, which needs no feature.

## Notes

**The selection bar** that appears over selected text follows the same map: Highlight, Comment, Underline, Squiggly underline, Strikethrough and Black out need `textHighlight` (Comment also needs the Comments panel, editable), Add a note needs `note`, Search for this needs `search`; Copy and Search for this also need a license that lets the words leave the viewer (see [the resting tool](https://kernstra.com/docs/web-sdk/config/mode/defaulttool)). In `'view-only'` and `'form-fill'`, which offer no authoring tools, it offers Copy and Search for this.

A group whose every tool is disabled through `tools` renders no tab and no cluster on the toolbar — `tools: { sign: false, image: false, stamp: false, link: false }` makes the Insert tab disappear entirely. Use [`toolbar.groups`](https://kernstra.com/docs/web-sdk/config/toolbar/groups) to drop a group from the toolbar while leaving its tools available to `viewer.activateTool()`.

Image, Sign and Black out write into the page itself; Erase can remove the page's own content.


Web page: https://kernstra.com/docs/web-sdk/config/tools
