Le problème d'impression du navigateur
Si vous avez déjà essayé d'imprimer un reçu depuis une application web, vous connaissez la douleur : window.print() ouvre une boîte de dialogue d'impression, rend la page sous forme de PDF et n'offre aucun support pour les commandes ESC/POS comme la coupe automatique ou la largeur de papier personnalisée.
Pour les imprimantes thermiques de reçus, c'est un inconvénient majeur. Vous avez besoin de :
- Impression silencieuse — pas de dialogue, pas d'interaction utilisateur
- Commandes ESC/POS — pour la coupe automatique, le texte en gras, l'alignement, les codes-barres
- Encodage fiable — UTF-8 vers la bonne page de codes pour votre imprimante
- Support multiplateforme — Mac, Windows, Linux
La solution est un pont WebSocket local — une petite application en arrière-plan qui s'exécute sur l'ordinateur de l'utilisateur, accepte les tâches d'impression de votre application web et envoie des commandes ESC/POS brutes à l'imprimante.
Comment fonctionne le pont WebSocket
Votre application web → WebSocket (ws://localhost:8765) → Agent d'impression → Imprimante thermique
Le flux est simple :
- Votre application web ouvre une connexion WebSocket à ws://localhost:8765
- Vous envoyez une charge utile JSON décrivant le reçu
- L'Agent d'impression la convertit en ESC/POS et l'envoie à l'imprimante
- L'imprimante imprime silencieusement — pas de dialogue, pas d'interaction avec le pilote
MenuForma Print Agent implémente ce pont. Il est gratuit, open-source et fonctionne sur Mac, Windows et Linux.
Référence de l'API
Connexion
const ws = new WebSocket('ws://localhost:8765');
ws.onopen = () => {
console.log('Agent d'impression connecté');
};
ws.onerror = () => {
console.log('Agent d'impression non démarré');
};
Vérifier le statut de l'agent
Envoyez un ping pour vérifier que l'agent est en cours d'exécution :
ws.send(JSON.stringify({ type: 'ping' }));
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
console.log('Version de l'agent :', data.version);
}
};
Imprimer un reçu
const receipt = {
type: 'print',
printer: 'auto', // ou IP spécifique comme '192.168.1.100'
data: {
storeName: 'My Restaurant',
storeAddress: '123 Main St',
orderNumber: '#1042',
tableNumber: 'Table 5',
items: [
{ name: 'Margherita Pizza', qty: 1, price: 14.90 },
{ name: 'Sparkling Water', qty: 2, price: 3.50 },
],
subtotal: 21.90,
tax: 1.97,
total: 23.87,
paymentMethod: 'Card',
footer: 'Thank you for dining with us!',
}
};
ws.send(JSON.stringify(receipt));
Exemple d'intégration 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); // retry
};
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 }; }
---
## Intégration Shopify
Pour les boutiques Shopify, vous pouvez déclencher l'impression à partir d'un webhook de commande ou d'une extension de navigateur :
```javascript
// Dans votre vitrine Shopify ou votre extension d'administration
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,
}
}));
};
}
Configuration de l'imprimante
Le champ "printer" dans la charge utile d'impression accepte :
| Valeur | Description |
|---|---|
| "auto" | Utilise l'imprimante configurée dans les paramètres de l'agent d'impression |
| "192.168.1.100" | Se connecte directement à une imprimante réseau par IP |
| "USB" | Utilise la première imprimante USB détectée |
Gestion des erreurs
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.type === 'print_success') {
console.log('Printed successfully');
} else if (response.type === 'print_error') {
console.error('Print failed:', response.error);
// Afficher une interface de secours ou réessayer
}
};
Détecter si l'agent d'impression est installé
Avant d'afficher la fonctionnalité d'impression dans votre interface utilisateur, vérifiez si l'agent est en cours d'exécution :
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);
};
});
}
// Utilisation
const agentAvailable = await isPrintAgentAvailable();
if (!agentAvailable) {
// Afficher une invite de téléchargement
window.open('/print-agent', '_blank');
}
Télécharger l'agent d'impression
MenuForma Print Agent est gratuit et disponible pour Mac, Windows et Linux. Il prend en charge les imprimantes thermiques USB, réseau et Bluetooth, et implémente l'API WebSocket complète décrite dans ce guide.
Pour la documentation complète de l'API et le code open source, visitez la page Print Agent.
Related Articles
- Pénurie de personnel en 2025 : comment la technologie sauve les restaurants français
- Wero et le paiement par QR code : la nouvelle révolution pour les restaurateurs en 2026
- Restauration écoresponsable : le digital au service de l'anti-gaspillage en 2025