# Template JSON

> Paper, label size and the element list. Every length is in millimetres.

Source: https://82label.app/en/docs/template/

A template is one JSON object. The designer, the library and the print agent all use this format and nothing else. Positions and sizes are in **millimetres** from the label's top left corner; only font sizes are in **points**. Elements are drawn in order (later ones on top).

```js
const template = {
  v: 1,
  name: 'Shipping label',
  paper: { kind: 'roll', dpi: 203 },
  label: { width: 60, height: 40 },
  elements: [
    { type: 'rect', x: 1, y: 1, w: 58, h: 38, stroke: 0.3, radius: 2 },
    { type: 'text', x: 4, y: 3, w: 36, h: 6, text: '{{orderNo}}', size: 9, bold: true },
    { type: 'text', x: 4, y: 10, w: 36, h: 12, text: '{{items}}', size: 8, fit: 'wrap' },
    { type: 'line', x1: 4, y1: 24, x2: 56, y2: 24, width: 0.3 },
    { type: 'text', x: 4, y: 26, w: 36, h: 10, text: '{{customer}}', size: 11, bold: true, valign: 'middle', fit: 'shrink' },
    { type: 'qr', x: 41, y: 4, size: 16, value: '{{orderUrl}}' },
  ],
  fields: [
    { name: 'orderNo', label: 'Order number', example: 'A-20261022-0012' },
    { name: 'items', label: 'Items', example: 'Wireless earbuds Pro and 2 more' },
    { name: 'customer', label: 'Customer', example: 'Haneul Kim' },
    { name: 'orderUrl', label: 'URL', example: 'https://shop.example.com/o/12' },
  ],
};

Label82.print(template);
```

## Top-level keys

| Key | Meaning |
| --- | --- |
| `v` | Format version: `1`. |
| `name` | Template name (shown in your template list). |
| `paper` | `{ kind: 'roll' }` or `{ kind: 'sheet', … }`. See [roll labels](https://82label.app/en/docs/roll/) and [Formtec sheets](https://82label.app/en/docs/sheets/). |
| `label` | One label (one slot on a sheet): `width`, `height`, corner `radius`. |
| `elements` | The elements, table below. |
| `fields` | Optional list of `{ name, label, example }` for the designer preview and example values. |

## Elements

| type | Required | Optional |
| --- | --- | --- |
| `text` | `x y w h text size` | `bold`, `align` (left, center, right), `valign` (top, middle, bottom), `fit` (shrink, wrap, clip), `font`, `rotate` (0, 90, 180, 270). `size` is in points. |
| `barcode` | `value` | `x y w h` (left out: centred, 80% wide), `format` (default code128), `showText`, `codeSet`, `rotate` |
| `qr` | `value` | `x y size` (left out: a centred square), `ecc` (L, M, Q, H; default M) |
| `image` | `x y w h src` | `src` is a data: URL, an https URL or a `{{field}}`. `fit` (contain, cover) |
| `line` | `x1 y1 x2 y2 width` | Line `width` in mm |
| `rect` | `x y w h` | `stroke` (border width in mm, default 0.3, 0 for none), `fill` (none, black), `radius` |

## Black and white only

Most label printers are thermal (black only), so there are no colors. For white text on black, use an image instead of text over a `fill: 'black'` box.

## Pre-printed frames (layer: 'frame')

Mark parts that are already printed on the stock, such as box lines and captions like "To", with `layer: 'frame'`. They are drawn on screen and on blank paper; on pre-printed stock, `print(t, rows, { frames: false })` leaves them out and prints only the values.

> JSON Schema of the format: [/schema/template.json](https://82label.app/schema/template.json). When saving, the server (82label.app) checks only `v`, the paper kind, the label size and the element count (at most 2,000).
