QR Code Integration in Web Projects: React, Node.js, SVG, and Logo
When you need to generate QR codes for personal accounts, e-tickets, or instant payments, the first thought is often to connect an external API. But that adds latency, request limits, and dependency on a third-party service. We implement generation directly in the browser or on the server—with full control over style, size, format, and the ability to add a logo inside the code. Our approach guarantees speed (no extra requests), security, and compatibility with any medium—from screen to print.
Experience from dozens of projects shows that client-side generation using the qrcode library reduces TTFB by 100–200 ms compared to server-side alternatives, and using SVG instead of PNG saves up to 80% in file weight. We select the optimal error correction level to keep the code readable even with up to 30% damage—especially important for QR codes with a logo. Savings on API requests when abandoning external services range from $200 to $500 per month. For example, at 10,000 generations per month, dropping an external API saves about $200.
QR code is an ISO/IEC 18004 standard.
How to Integrate a QR Generator in React?
The main tool is the qrcode library (version 1.5+). It supports Canvas, SVG, and Data URL, works in the browser and Node.js. Installation is minimal:
npm install qrcode
npm install -D @types/qrcode
Generator Component
import QRCode from 'qrcode'
import { useEffect, useRef, useState } from 'react'
interface QRGeneratorProps {
value: string
size?: number
errorCorrection?: 'L' | 'M' | 'Q' | 'H'
color?: { dark: string; light: string }
}
export function QRGenerator({
value,
size = 256,
errorCorrection = 'M',
color = { dark: '#000000', light: '#ffffff' },
}: QRGeneratorProps) {
const canvasRef = useRef<HTMLCanvasElement>(null)
const [dataUrl, setDataUrl] = useState<string>('')
useEffect(() => {
if (!value || !canvasRef.current) return
QRCode.toCanvas(canvasRef.current, value, {
width: size,
margin: 2,
errorCorrectionLevel: errorCorrection,
color,
})
// Simultaneously prepare Data URL for download
QRCode.toDataURL(value, {
width: size * 2, // 2x for print clarity
margin: 2,
errorCorrectionLevel: errorCorrection,
color,
}).then(setDataUrl)
}, [value, size, errorCorrection, color])
function download() {
const a = document.createElement('a')
a.href = dataUrl
a.download = 'qrcode.png'
a.click()
}
return (
<div className="flex flex-col items-center gap-3">
<canvas ref={canvasRef} className="rounded" />
{dataUrl && (
<button onClick={download} className="text-sm text-blue-600 hover:underline">
Download PNG
</button>
)}
</div>
)
}
This component generates a QR code on Canvas and simultaneously creates a Data URL for download in PNG with double resolution. It supports all four error correction levels: L (7%), M (15%), Q (25%), H (30%). For typical tasks, M is sufficient; for a code with a logo, use H.
Why Client-Side Generation Is Faster Than Server-Side?
Comparison: With server-side generation, each request goes through the network, loads server CPU, and requires caching. Client-side generation happens instantly—no data transmission delay. According to our measurements, on an average machine, generating a 256×256 QR code takes less than 10 ms. This is especially critical for dynamic pages where the code is generated on every view (e.g., in a personal account).
| Parameter | Client-Side Generation | Server-Side Generation |
|---|---|---|
| Time to first byte | 0 ms (local) | 50–200 ms (network) |
| Server load | None | High at >1000 req/s |
| CDN caching | Not needed | Desirable |
| Offline capability | Yes | No |
For cases where the QR code needs to be sent in an email or embedded in a PDF, we use server-side generation via Node.js—see section below.
SVG Version for Embedding in a Page
import QRCode from 'qrcode'
import { useState, useEffect } from 'react'
function QRCodeSVG({ value, size = 200 }: { value: string; size?: number }) {
const [svg, setSvg] = useState<string>('')
useEffect(() => {
QRCode.toString(value, { type: 'svg', width: size, margin: 1 })
.then(setSvg)
}, [value, size])
return (
<div
dangerouslySetInnerHTML={{ __html: svg }}
className="inline-block"
/>
)
}
SVG scales without quality loss—suitable for PDFs and print materials. File size is 5–10 times smaller than PNG of the same dimensions.
QR with a Logo in the Center
A QR code with correction level H withstands up to 30% closed area—you can insert a logo:
async function generateQRWithLogo(text: string, logoUrl: string): Promise<string> {
const canvas = document.createElement('canvas')
const size = 400
await QRCode.toCanvas(canvas, text, {
width: size,
margin: 2,
errorCorrectionLevel: 'H', // Must be H when logo is present
color: { dark: '#000000', light: '#ffffff' },
})
const ctx = canvas.getContext('2d')!
const logo = new Image()
logo.crossOrigin = 'anonymous'
await new Promise<void>((resolve) => {
logo.onload = () => resolve()
logo.src = logoUrl
})
const logoSize = size * 0.18 // 18% of QR size
const logoX = (size - logoSize) / 2
const logoY = (size - logoSize) / 2
// White background under logo
ctx.fillStyle = '#ffffff'
ctx.beginPath()
ctx.roundRect(logoX - 4, logoY - 4, logoSize + 8, logoSize + 8, 6)
ctx.fill()
ctx.drawImage(logo, logoX, logoY, logoSize, logoSize)
return canvas.toDataURL('image/png')
}
The logo is overlaid on the generated QR code. Important: error correction level H is mandatory, otherwise the code will stop scanning. Logo size should not exceed 20% of the QR width, or error correction may not help.
Server-Side Generation (Node.js)
When a QR needs to be inserted into a PDF or sent in an email—we generate it server-side:
import QRCode from 'qrcode'
// Express / Next.js API route
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const text = searchParams.get('text')
if (!text) return new Response('Missing text', { status: 400 })
const buffer = await QRCode.toBuffer(text, {
type: 'png',
width: 400,
errorCorrectionLevel: 'M',
})
return new Response(buffer, {
headers: {
'Content-Type': 'image/png',
'Cache-Control': 'public, max-age=3600',
},
})
}
The server endpoint returns a PNG image with caching for one hour—enough for most scenarios (tickets, coupons).
Step-by-Step Integration
- Install the
qrcodelibrary in your project. - Create a React component using Canvas (as shown above).
- Configure error correction levels and colors via props.
- Add a button for downloading PNG.
- For SVG, replace Canvas with the
QRCode.toStringfunction. - For a logo, use level H and image overlay.
- For server-side generation, create an API route returning a PNG buffer.
Error Correction Levels
| Level | Recovery Percentage | Recommendation |
|---|---|---|
| L | 7% | Maximum data density |
| M | 15% | Standard choice |
| Q | 25% | Increased reliability |
| H | 30% | Mandatory for logos |
What's Included in Our Work
We offer turnkey QR generator integration: library selection, custom React component development, SVG and logo integration, server API creation, real-device testing, and source code handover. Average budget savings on developing such functionality is 30% compared to purchasing a ready-made API solution. Cost is calculated individually after briefing.
Timeline: from 0.5 to 2 days depending on complexity (logo, color, multiple formats). We guarantee that generated QR codes pass all scanner tests (ZXing, iPhone, Google Lens) and comply with ISO/IEC 18004 standards.
Why Choose Us?
- 5 years in web application development market.
- Over 50 successfully implemented projects with QR functionality.
- Experience with Core Web Vitals: our solutions do not increase LCP and CLS.
- Post-delivery support—we fix bugs within 24 hours.
If you need a working QR generator quickly and without compromise—contact us. Tell us about your task, and we'll propose the optimal solution. Order implementation today.







