# Printing (browser, agent, silent)

> The three modes of print(), the result, picking a printer, and browser dialog settings.

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

One call prints: `print(template, rows, options)`. `template` is a template object or a template id (`'lbl_…'`).

```js
const r = await Label82.print(template, rows, {
  mode: 'auto',        // 'auto' | 'agent' | 'browser'
  printer: 'TSC TE210', // agent printer name (default printer if left out)
  copies: 1,           // labels per row
  startAt: 1,          // sheets: first slot
  frames: true,        // false: skip layer 'frame' elements
});
```

## Three modes

| mode | Behaviour |
| --- | --- |
| `auto` (default) | If the print agent runs on the PC and is linked to a subscribed account, print through it with no dialog (silent). Otherwise the browser print dialog. |
| `agent` | Agent only. Throws `AgentError` when it is missing or not linked (never falls back). |
| `browser` | Always the browser dialog; the agent is not looked for. |

## Silent printing

Through the agent there is no dialog. The library renders the labels as PNGs at the printer's dpi, sends them to the agent on the PC (`http://127.0.0.1:18282`), and the agent prints them through the Windows driver at the paper size (no margins, 100%).

- The first request from a site makes the agent ask "Allow this site to print?". Meanwhile `print()` prints nothing and returns `status: 'pending_permission'`; after allowing, the next click prints at once.
- If the agent runs but is not linked to a subscription, the browser prints and the result carries `notice: 'agent_license_required'`.
- Without an agent the library decides within 0.4 seconds and falls back to the browser.

## The result

```js
{
  via: 'agent' | 'browser',
  printed: 2,                 // labels sent (copies included)
  status: 'done' | 'pending_permission' | 'cancelled',
  errors: [],                 // bad barcode values, overflowing text… (printing goes on)
  notice: 'agent_license_required', // only when set
}
```

```js
const r = await Label82.print(template, rows);
if (r.status === 'pending_permission') showToast('Allow this site in the print agent window.');
else if (r.notice === 'agent_license_required') showToast('Link the print agent to your account to print directly.');
if (r.errors.length) console.warn(r.errors);
```

## Printers

```js
const list = await Label82.printers(); // null without the agent
// [{ name: 'TSC TE210', isDefault: true, dpi: 203 }, { name: 'Canon G3010', isDefault: false }]
const status = await Label82.agentStatus(); // { version, allowed, licensed } or null
```

## Browser dialog settings

- Scale: **100%** (actual size). Turn off "fit to page".
- Margins: **none**. 82label sets `@page { size: Wmm Hmm; margin: 0 }`.
- Turn off headers and footers (date, URL). Chrome drops them when there are no margins.
- On a roll label printer, pick the label size as the printer's paper size.

> Browser printing cannot tell whether the user cancelled the dialog, so `status` is `'done'`. Use the agent when you need an exact print log.
