React hooks for seamless integration with QZ Tray — the browser-to-desktop print connector.
- QZ Tray desktop application running on the user's machine (download)
- React 18 or 19
- A backend endpoint to sign QZ Tray requests (required for production use)
npm install react-qztray
# or
pnpm add react-qztray1. Wrap your app with QzTrayProvider
import { QzTrayProvider } from 'react-qztray';
export const Root = () => (
<QzTrayProvider
certificate="-----BEGIN CERTIFICATE-----\nYOUR_CERT_HERE\n-----END CERTIFICATE-----"
signatureAlgorithm="SHA512"
signaturePromise={(toSign) => (resolve) => {
fetch('/api/sign', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ toSign }),
})
.then((res) => res.text())
.then(resolve);
}}
>
<App />
</QzTrayProvider>
);2. Connect and print
import { useQzTray, useQzPrint } from 'react-qztray';
const PrintButton = () => {
const { isConnected, connect } = useQzTray();
const { print, isPrinting } = useQzPrint();
const handlePrint = async () => {
if (!isConnected) await connect();
print({
printer: 'ZDesigner',
config: { size: { width: 100, height: 150 }, units: 'mm' },
data: [{ type: 'pixel', format: 'html', flavor: 'plain', data: '<h1>Hello!</h1>' }],
});
};
return (
<button onClick={handlePrint} disabled={isPrinting}>
{isPrinting ? 'Printing...' : 'Print'}
</button>
);
};Provides QZ Tray context to all child hooks. Place it at the root of your app.
| Prop | Type | Required | Description |
|---|---|---|---|
certificate |
string | (() => Promise<string>) |
✓ | Public PEM certificate from QZ Tray's signing tool. Accepts a string or an async function that fetches it. |
signaturePromise |
PromiseFactory |
✓ | Factory function that signs the request. Should call your backend. |
signatureAlgorithm |
"SHA1" | "SHA256" | "SHA512" |
Signing algorithm. Defaults to "SHA512". |
|
wsOptions |
ConnectOptions |
WebSocket connection options (host, port, keepAlive, retries, delay). | |
autoConnect |
boolean |
Connect to QZ Tray automatically on mount. Defaults to false. |
|
onConnect |
() => void |
Called when the connection is established. | |
onDisconnect |
() => void |
Called when the connection is closed. | |
onError |
(error: unknown) => void |
Called on connection error. |
Access connection state and controls. Must be used inside QzTrayProvider.
const { isConnected, isConnecting, error, connect, disconnect } = useQzTray();| Return | Type | Description |
|---|---|---|
isConnected |
boolean |
Whether QZ Tray is currently connected. |
isConnecting |
boolean |
Whether a connection attempt is in progress. |
error |
unknown |
Last connection error, or null. |
connect |
() => Promise<void> |
Open the WebSocket connection. |
disconnect |
() => Promise<void> |
Close the WebSocket connection. |
Send print jobs to any printer visible to QZ Tray. Must be used inside QzTrayProvider.
const { print, isPrinting, error } = useQzPrint();| Return | Type | Description |
|---|---|---|
print |
(options: IPrintOptions) => Promise<void> |
Send a print job. Connects automatically if not connected. |
isPrinting |
boolean |
Whether a print job is in progress. |
error |
unknown |
Last print error, or null. |
IPrintOptions
| Option | Type | Required | Description |
|---|---|---|---|
printer |
string |
✓ | Printer name as it appears in the OS. |
data |
PrintData[] |
✓ | Array of print data objects. |
config |
PrinterOptions |
Paper size, units, density, orientation, etc. | |
autoDisconnect |
boolean |
Disconnect after the job completes. Defaults to true. |
See the examples/ directory for complete usage examples:
01-basic-setup.tsx— Provider setup with inline and async certificate02-connection.tsx— Connection status UI andautoConnect03-print-html.tsx— Print HTML content as a pixel job04-print-pdf.tsx— Print PDF from URL or base6405-print-raw.tsx— Raw ZPL and ESC/POS commands06-multiple-jobs.tsx— Chain multiple jobs without disconnecting
A Vite dev app is included for local testing.
pnpm install
pnpm playgroundOpen http://localhost:5173, paste your certificate and signature endpoint, and send test print jobs directly from the browser.
Contributions are more than welcome! Whether it's a bug report, feature request, or a pull request — all input is appreciated.
- Fork the repo and create your branch from
main - Install dependencies with
pnpm install - Make your changes and add tests where applicable
- Run
pnpm lint,pnpm typecheck, andpnpm testbefore submitting - Open a pull request
If you're unsure about something, feel free to open an issue first to discuss it.
MIT © Juliusz Kowalewski