Il Problema della Stampa dal Browser
Se hai mai provato a stampare una ricevuta da un'applicazione web, conosci il dolore: window.print() apre una finestra di dialogo di stampa, rende la pagina come PDF e non ha alcun supporto per i comandi ESC/POS come il taglio automatico o la larghezza della carta personalizzata.
Per le stampanti termiche per ricevute, questo è un problema insormontabile. Hai bisogno di:
- Stampa silenziosa — nessuna finestra di dialogo, nessuna interazione con l'utente
- Comandi ESC/POS — per taglio automatico, testo in grassetto, allineamento, codici a barre
- Codifica affidabile — UTF-8 alla pagina di codice corretta per la tua stampante
- Supporto multipiattaforma — Mac, Windows, Linux
La soluzione è un bridge WebSocket locale — una piccola applicazione in background che gira sul computer dell'utente, accetta lavori di stampa dalla tua applicazione web e invia comandi ESC/POS grezzi alla stampante.
Come Funziona il Bridge WebSocket
La tua Web App → WebSocket (ws://localhost:8765) → Print Agent → Stampante Termica
Il flusso è semplice:
- La tua applicazione web apre una connessione WebSocket a ws://localhost:8765
- Invii un payload JSON che descrive la ricevuta
- Print Agent lo converte in ESC/POS e lo invia alla stampante
- La stampante stampa silenziosamente — nessuna finestra di dialogo, nessuna interazione con il driver
MenuForma Print Agent implementa questo bridge. È gratuito, open source e funziona su Mac, Windows e Linux.
Riferimento API
Connessione
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => {
console.log('Print Agent connesso');
};
ws.onerror = () => {
console.log('Print Agent non in esecuzione');
};
Controlla lo Stato dell'Agente
Invia un ping per verificare che l'agente sia in esecuzione:
ws.send(JSON.stringify({ type: 'ping' }));
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
console.log('Versione Agente:', data.version);
}
};
Stampa una Ricevuta
const receipt = {
type: 'print',
printer: 'auto', // o IP specifico come '192.168.1.100'
data: {
storeName: 'Il Mio Ristorante',
storeAddress: 'Via Principale 123',
orderNumber: '#1042',
tableNumber: 'Tavolo 5',
items: [
{ name: 'Pizza Margherita', qty: 1, price: 14.90 },
{ name: 'Acqua Frizzante', qty: 2, price: 3.50 },
],
subtotal: 21.90,
tax: 1.97,
total: 23.87,
paymentMethod: 'Carta',
footer: 'Grazie per aver cenato con noi!',
}
};
ws.send(JSON.stringify(receipt));
Esempio di Integrazione React
import { useEffect, useRef, useCallback, useState } from 'react';
function usePrintAgent() {
const wsRef = useRef(null);
const [connected, setConnected] = useState(false);
useEffect(() => {
const connect = () => {
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => setConnected(true);
ws.onclose = () => {
setConnected(false);
setTimeout(connect, 3000); // riprova
};
wsRef.current = ws;
};
connect();
return () => wsRef.current?.close();
}, []);
const print = useCallback((receiptData) => { if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) { throw new Error('Print Agent not connected'); } wsRef.current.send(JSON.stringify({ type: 'print', data: receiptData })); }, []);
return { connected, print }; }
---
## Integrazione Shopify
Per i negozi Shopify, puoi attivare la stampa da un webhook d'ordine o da un'estensione del browser:
```javascript
// Nel tuo negozio Shopify o nell'estensione amministrativa
async function printShopifyOrder(order) {
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'print',
data: {
storeName: order.shop_name,
orderNumber: order.name,
items: order.line_items.map(item => ({
name: item.title,
qty: item.quantity,
price: parseFloat(item.price),
})),
total: parseFloat(order.total_price),
paymentMethod: order.payment_gateway,
}
}));
};
}
Configurazione della stampante
Il campo "printer" nel payload di stampa accetta:
| Valore | Descrizione |
|---|---|
| "auto" | Usa la stampante configurata nelle impostazioni di Print Agent |
| "192.168.1.100" | Connettiti direttamente a una stampante di rete tramite IP |
| "USB" | Usa la prima stampante USB rilevata |
Gestione degli errori
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.type === 'print_success') {
console.log('Stampato con successo');
} else if (response.type === 'print_error') {
console.error('Stampa fallita:', response.error);
// Mostra UI di fallback o riprova
}
};
Rilevamento dell'installazione di Print Agent
Prima di mostrare la funzionalità di stampa nella tua UI, verifica se l'agente è in esecuzione:
async function isPrintAgentAvailable() {
return new Promise((resolve) => {
const ws = new WebSocket('ws://localhost:8765');
const timeout = setTimeout(() => {
ws.close();
resolve(false);
}, 1000);
ws.onopen = () => {
clearTimeout(timeout);
ws.close();
resolve(true);
};
ws.onerror = () => {
clearTimeout(timeout);
resolve(false);
};
});
}
// Utilizzo
const agentAvailable = await isPrintAgentAvailable();
if (!agentAvailable) {
// Mostra il prompt di download
window.open('/print-agent', '_blank');
}
Scarica Print Agent
MenuForma Print Agent è gratuito e disponibile per Mac, Windows e Linux. Supporta stampanti termiche USB, di rete e Bluetooth, e implementa l'API WebSocket completa descritta in questa guida.
Per la documentazione completa dell'API e il codice open-source, visita la pagina di Print Agent.
Related Articles
- The UK Hospitality Labor Crisis: Why QR Menus Are the Key to Survival
- 2025 US Restaurant Tech Trends: The Widespread Adoption of Digital Ordering and Cloud Platforms
- The Unstoppable Boom of Online Food Delivery: How US and UK Restaurants Can Capture a Trillion-Dollar Market