Saltar al contenido

Para desarrolladores

Imprimí tickets y comandas ESC/POS desde JavaScript

Tu página se conecta con NanoPrint a través de qz-tray.js y le envía tickets ESC/POS armados con el encoder que prefieras. Si tu sistema ya usa qz-tray.js, funciona sin cambios.

Guía de integración Protocolo

Librerías compatibles

Las que recomendamos, probadas con NanoPrint.

qz-tray

Licencia: LGPL-2.1

Se conecta con NanoPrint y envía los trabajos.

Versión 2.2 o posterior. Cada versión de NanoPrint se prueba con qz-tray.js 2.3.0.

web-escpos-printer

Licencia: MIT

Encoder y transportes en un solo paquete.

Usá su transporte de QZ Tray, instalado desde npm.

Ejemplo mínimo

Instalá las dos librerías con npm install qz-tray @point-of-sale/receipt-printer-encoder y enviá un ticket:

JavaScript
import qz from 'qz-tray';
import ReceiptPrinterEncoder from '@point-of-sale/receipt-printer-encoder';

await qz.websocket.connect();
const printer = await qz.printers.getDefault(); // o qz.printers.find('POS-58')

const bytes = new ReceiptPrinterEncoder({ columns: 32 }) // 58 mm; 48 para 80 mm
  .initialize()
  .line('Kiosco Don Pepe')
  .line('Total: $ 1.234,00')
  .qrcode('https://example.com/ticket/123')
  .cut()
  .encode();

const config = qz.configs.create(printer, { jobName: 'Ticket 123' });
await qz.print(config, [
  { type: 'raw', format: 'command', flavor: 'base64', data: toBase64(bytes) },
]);

function toBase64(bytes) {
  let binary = '';
  for (const byte of bytes) binary += String.fromCharCode(byte);
  return btoa(binary);
}

Si la impresora predeterminada del sistema es virtual (por ejemplo, «Microsoft Print to PDF»), getDefault() devuelve null: buscala por nombre o dejá que el usuario la elija.

Nombre y logo de tu sitio

Opcional: NanoPrint muestra en el pedido de permiso el nombre y el logo que envíe tu página, siempre junto a su dirección real. El logo va como data URL PNG, JPEG o WebP de hasta 32 KiB.

JavaScript
// Antes de conectar
qz.security.setCertificatePromise((resolve) => {
  resolve(JSON.stringify({
    nanoprint: { name: 'Kiosco Don Pepe', icon: 'data:image/png;base64,…' },
  }));
});

Si NanoPrint está cerrado

NanoPrint arranca con la computadora, pero el usuario puede haberlo cerrado. Tu página puede volver a abrirlo con el enlace nanoprint://start: el navegador pregunta antes de abrirlo y NanoPrint arranca en la bandeja, sin ventanas.

JavaScript
async function openNanoPrint() {
  window.location.href = 'nanoprint://start';
  // NanoPrint needs a moment to start
  await qz.websocket.connect({ retries: 15, delay: 1 });
}

Ofrecelo como un botón «Abrir NanoPrint» después de una conexión fallida: los navegadores solo abren aplicaciones después de un clic. El enlace solo arranca NanoPrint, no lleva datos, y el sitio igual necesita permiso para imprimir.

Probalo ahora

Con NanoPrint instalado y abierto, esta página se conecta, lista tus impresoras e imprime un ticket de ejemplo. Usa solo qz-tray.js y ReceiptPrinterEncoder.

  • NanoPrint te va a preguntar si este sitio puede imprimir.
  • Chrome puede pedir permiso para acceder a dispositivos de la red local: aceptalo para que la página llegue a NanoPrint.

Ofrecelo a tus usuarios

NanoPrint está pensado para que otros proyectos lo usen.

  • Enlazá a nanoprint.nanofactura.com para la descarga: detecta el sistema de cada usuario y explica la instalación paso a paso.
  • Es gratis para vos y para tus usuarios: sin licencias por puesto, suscripciones ni límites de uso.
  • Tu sistema solo se comunica con NanoPrint, un programa aparte, así que puede tener cualquier licencia, incluso privativa.
  • Si te falta algo o encontrás un problema, contanos en GitHub: las integraciones reales nos ayudan a decidir qué sigue.
Abrir un issue en GitHub

Antes de integrar

  • Páginas https: el usuario activa una sola vez los «sitios seguros» en NanoPrint, que se lo ofrece al instalar.
  • Chrome puede pedir permiso de acceso a la red local antes de conectarse con NanoPrint.
  • Puertos: los mismos que qz-tray.js (wss://localhost:8181 y ws://localhost:8182). Si el usuario elige otros, pasalos en qz.websocket.connect({ port: … }).
  • Límites: 30 trabajos por minuto por sitio, hasta 10 copias por trabajo y mensajes de hasta 2 MiB.
  • Solo impresión directa: archivos, puertos serie, USB, HID e impresión de píxeles, HTML o PDF no están disponibles.
Documentación completa en GitHub