diff --git a/packages/printer/src/__tests__/print-html.test.ts b/packages/printer/src/__tests__/print-html.test.ts
index ac335eee2..a4ea53d1c 100644
--- a/packages/printer/src/__tests__/print-html.test.ts
+++ b/packages/printer/src/__tests__/print-html.test.ts
@@ -32,17 +32,33 @@ describe('buildPrintableReceiptHtml', () => {
expect(html).toContain('Hello');
});
- it('wraps 80mm thermal output with physical page size and no A4 width rule', () => {
+ it('defers 80mm thermal output to the printer roll paper via size: auto', () => {
const html = buildPrintableReceiptHtml({
bodyHtml: '
Thermal
',
paperWidth: '80mm',
});
- expect(html).toContain('@page { size: 80mm; margin: 0; }');
+ // Must be `size: auto` — NOT `80mm` (a valid but square 80mm×80mm page) and
+ // NOT `80mm auto` (invalid ` auto`, silently ignored → Letter/A4).
+ // Both broken forms render the receipt tiny.
+ expect(html).toContain('@page { size: auto; margin: 0; }');
+ expect(html).not.toContain('@page { size: 80mm; margin: 0; }');
+ expect(html).not.toContain('@page { size: 80mm auto; margin: 0; }');
expect(html).not.toContain('body > * { width: 210mm; }');
expect(html).toContain('Thermal
');
});
+ it('defers 58mm thermal output to the printer roll paper via size: auto', () => {
+ const html = buildPrintableReceiptHtml({
+ bodyHtml: 'Narrow
',
+ paperWidth: '58mm',
+ });
+
+ expect(html).toContain('@page { size: auto; margin: 0; }');
+ expect(html).not.toContain('@page { size: 58mm; margin: 0; }');
+ expect(html).not.toContain('@page { size: 58mm auto; margin: 0; }');
+ });
+
it('keeps print mechanics outside user template content', () => {
const html = buildPrintableReceiptHtml({
bodyHtml: 'User CSS
',
@@ -71,7 +87,7 @@ describe('prepareSystemPrintHtml', () => {
paperWidth: '80mm',
});
- expect(html).toContain('@page { size: 80mm; margin: 0; }');
+ expect(html).toContain('@page { size: auto; margin: 0; }');
expect(html).toContain('');
expect(html).toContain('From iframe
');
});
diff --git a/packages/printer/src/print-html.ts b/packages/printer/src/print-html.ts
index 3f32e97ca..ef50be29f 100644
--- a/packages/printer/src/print-html.ts
+++ b/packages/printer/src/print-html.ts
@@ -18,7 +18,17 @@ export function buildPrintableReceiptHtml({
paperWidth,
}: BuildPrintableReceiptHtmlOptions): string {
const normalizedPaperWidth = normalizeReceiptPaperWidth(paperWidth);
- const pageSize = normalizedPaperWidth === 'a4' ? 'A4' : normalizedPaperWidth;
+ // Thermal receipts defer to the printer's selected roll paper via `size: auto`.
+ //
+ // The CSS `@page size` descriptor grammar is `{1,2} | auto | `
+ // — there is no "fixed width, flowing height" form:
+ // - `80mm auto` is INVALID (length + keyword); browsers ignore it and fall
+ // back to the default paper (Letter/A4), printing the receipt tiny.
+ // - `80mm` is valid but makes BOTH dimensions 80mm — an 80mm×80mm square —
+ // which the print dialog shrinks onto the roll, also printing it tiny.
+ // `auto` lets the browser use the thermal printer's own paper (e.g. 80×297mm) and
+ // shrink-fits the content to the roll width, which is what we actually want.
+ const pageSize = normalizedPaperWidth === 'a4' ? 'A4' : 'auto';
const widthRule = normalizedPaperWidth === 'a4' ? '\nbody > * { width: 210mm; }' : '';
return `