Generate professional invoices as HTML pages or React apps with PDF export.
Build invoices as standalone HTML pages (preferred for simplicity) or React web artifacts. They auto-scale to fit the page and export to PDF via the browser's native print dialog. The web page is the single source of truth — the PDF is a print of it.
NixOS note: Puppeteer / headless Chromium fails on this platform due to missing system libraries (
libglib-2.0.so.0). Usewindow.print()(browser print dialog → Save as PDF) instead. The approach below is designed for that reality.
Do NOT start building the invoice until you have enough information to populate real line items and details. An invoice with placeholder data is useless.
Go ahead and start building immediately. You have what you need.
You MUST ask clarifying questions before writing any code. Ask about:
Seller info — Business name, address, email, phone, logo (if any), VAT/tax ID (if applicable)
Client info — Client/company name, address, contact email, VAT number (if B2B in EU)
Line items — Description of each service/product, quantity, rate/price per unit
Payment terms — Net 30, due on receipt, etc. + preferred payment method (bank transfer, Stripe, PayPal, etc.)
Invoice number — Do they have an existing numbering scheme, or should you start one?
Dates — Invoice date, service/delivery date (if different), due date
Tax — What tax rate applies? (Sales tax, VAT, ITBIS, none?) This depends on jurisdiction.
Where is the seller based? — Determines required legal fields, page size (US = Letter, everyone else = A4), and tax handling
Billing contact email — Always ask explicitly. Do NOT invent a placeholder like [email protected] — the user must confirm the real email address.
Production domain — Always ask what domain the app is deployed to. Do NOT use the Replit dev domain or a made-up domain on the invoice itself.
Start with the essentials:
"To create your invoice, I need a few details:
Your business name and address (the seller)
Who you're billing — client name and address
What you're billing for — list each item/service with the quantity and price
Payment terms — when is it due, and how should they pay?
What email should clients contact for billing questions?
What domain is your app deployed to (for the website shown on the invoice)?"
Then follow up for tax details, numbering, branding, etc. based on what they share.
If the user gives vague descriptions like "consulting work," push for specifics: "Can you break that down into specific deliverables? e.g., 'Website redesign — 3 revision rounds' at $5,000. Specific line items look more professional and reduce client pushback."
If you had to guess or infer any details — tax rates, payment terms, invoice numbers, dates — you MUST tell the user what you assumed. After presenting the first draft, explicitly list anything you weren't sure about. For example:
"A few things I assumed — let me know if any need adjusting:
I used invoice number INV-2026-0001 — do you have an existing numbering scheme?
I set the tax rate to 0% since you didn't mention taxes — should I add sales tax or VAT?
I set payment terms to Net 30 with a due date of April 13 — is that right?"
Do NOT silently present fabricated details as fact. Getting invoice details wrong can cause real payment and legal issues.
Use when: The same invoice template will be sent to many different clients (e.g., a subscription SaaS billing its users). Client-specific data (name, email, invoice number, dates, amount) is passed via URL query parameters. One file serves all clients.
client/public/invoice-template.html \# Single file, URL-param driven
The template lives in the main app's public/ folder, served as a static asset
All client-specific fields are read from URLSearchParams at runtime
Seller info, domain, and billing email are hardcoded (they never change)
Client pastes the parameterized link into any browser → prints to PDF
File location: client/public/invoice-template.html→ served at/invoice-template.html
Use when: Building a one-off invoice for a specific client with complex line items, custom branding per client, or when integrated into an app's billing flow.
artifacts/<client>-invoice/
client/src/pages/Invoice.tsx \# Invoice data + component with auto-scale
client/src/index.css \# Print-ready styles (A4 or Letter)
This is the cleanest pattern for subscription/SaaS invoices. Every field that varies per client is a query param; everything that belongs to the seller is hardcoded.
| Param | Description | Default |
|-------|-------------|---------|
| client | Client / company name | "Client Name" (shown in amber as warning) |
| email | Client email address | empty |
| inv| Invoice number |PREFIX-YYYY-0001 |
| date | Invoice date (ISO: YYYY-MM-DD) | today |
| due | Due date (ISO: YYYY-MM-DD) | today + 30 days |
| period | Service period label | next calendar month |
| amount | Line item amount | plan default |
| plan | Plan name label | "Pro" |
| stripe | Stripe payment link URL | placeholder (shown dimmed) |