Skip to main content
This page documents all props, state types, and API interfaces used in the QRGenerator component.

QRCodeSVG props

The visible QR code preview uses the QRCodeSVG component from qrcode.react with the following props:
value
string
required
The data to encode in the QR code. This is computed by the useEffect hook based on the active template.
value={qrValue}
size
number
default:"280"
The width and height of the QR code in pixels. Must be a positive integer.
size={size} // Controlled by size state
level
'L' | 'M' | 'Q' | 'H'
default:"'H'"
Error correction level that determines how much of the QR code can be damaged while remaining scannable.
  • 'L': Low (7% recovery)
  • 'M': Medium (15% recovery)
  • 'Q': Quartile (25% recovery)
  • 'H': High (30% recovery)
level={logoUrl ? 'H' : level} // Always 'H' when logo is present
When a logo is uploaded, the level is automatically forced to ‘H’ to ensure scannability despite the center obstruction.
bgColor
string
default:"'#ffffff'"
Background color in hex format. Transparent backgrounds are converted to white for compatibility.
bgColor={bgColor === 'transparent' ? '#ffffff' : bgColor}
fgColor
string
default:"'#0f172a'"
Foreground color (QR code modules) in hex format.
fgColor={fgColor}
includeMargin
boolean
default:"true"
Whether to include a quiet zone (margin) around the QR code. Always set to true for proper scannability.
includeMargin={true}
imageSettings
ImageSettings | undefined
Configuration for embedding a logo image in the center of the QR code. Set to undefined when no logo is uploaded.
imageSettings={logoUrl ? {
  src: logoUrl,
  x: undefined,
  y: undefined,
  height: size * 0.22,
  width: size * 0.22,
  excavate: true,
} : undefined}
See ImageSettings type for detailed field documentation.
Implementation: src/components/QRGenerator.jsx:230-245

QRCodeCanvas props

The hidden Canvas element (used for PNG export) uses identical props to QRCodeSVG, with one key difference:
size
number
default:"560"
The Canvas renders at 2x resolution for high-quality PNG exports.
size={size * 2} // 280 * 2 = 560 for high DPI export
imageSettings.height
number
Logo height is also doubled to maintain proportions at 2x resolution.
height: (size * 2) * 0.22 // 22% of doubled size
imageSettings.width
number
Logo width is also doubled to maintain proportions.
width: (size * 2) * 0.22
Implementation: src/components/QRGenerator.jsx:247-259
All other props (value, level, bgColor, fgColor, includeMargin, imageSettings.src, imageSettings.excavate) remain identical between SVG and Canvas to ensure visual consistency.

ImageSettings type

Configuration object for logo embedding in QR codes:
src
string
required
Data URL or image source for the logo. Generated by FileReader when user uploads an image.
src: logoUrl // e.g., "data:image/png;base64,iVBORw0KG..."
x
number | undefined
X-coordinate for logo placement. When undefined, the logo is automatically centered.
x: undefined // Auto-center horizontally
y
number | undefined
Y-coordinate for logo placement. When undefined, the logo is automatically centered.
y: undefined // Auto-center vertically
height
number
required
Logo height in pixels. Set to 22% of the QR code size.
height: size * 0.22 // e.g., 280 * 0.22 = 61.6px
width
number
required
Logo width in pixels. Set to 22% of the QR code size.
width: size * 0.22
excavate
boolean
default:"true"
When true, removes QR modules behind the logo to prevent scanning interference. Critical for maintaining scannability.
excavate: true // Always true when logo is present

State types

TypeScript-style type definitions for component state variables:

Template state

type ActiveTab = 'url' | 'wifi' | 'vcard' | 'email';

const [activeTab, setActiveTab] = useState<ActiveTab>('url');

Data state types

type UrlData = string;

interface WifiData {
  ssid: string;
  password: string;
  encryption: 'WPA' | 'WEP' | 'nopass';
  hidden: boolean;
}

interface VcardData {
  firstName: string;
  lastName: string;
  phone: string;
  email: string;
  company: string;
}

interface EmailData {
  to: string;
  subject: string;
  body: string;
}
Actual initialization:
const [urlData, setUrlData] = useState('https://www.bbc.com/mundo');
Implementation: src/components/QRGenerator.jsx:9-13

Customization state types

type HexColor = string; // e.g., '#0f172a'

type QRSize = number; // Positive integer, default 280

type ErrorCorrectionLevel = 'L' | 'M' | 'Q' | 'H';

type LogoUrl = string; // Data URL or empty string

const [fgColor, setFgColor] = useState<HexColor>('#0f172a');
const [bgColor, setBgColor] = useState<HexColor>('#ffffff');
const [size, setSize] = useState<QRSize>(280);
const [level, setLevel] = useState<ErrorCorrectionLevel>('H');
const [logoUrl, setLogoUrl] = useState<LogoUrl>('');
Implementation: src/components/QRGenerator.jsx:16-20

Computed state types

type QRValue = string; // Generated QR data

const [qrValue, setQrValue] = useState<QRValue>('');
const qrRef = useRef<HTMLDivElement>(null);
Implementation: src/components/QRGenerator.jsx:22-23

Error correction levels

The QR code specification defines four error correction levels:
L
Low
7% recovery - Suitable for clean environments with no logo
<option value="L">Normal</option>
M
Medium
15% recovery - Default for most QR codes
<option value="M">Buena</option>
Q
Quartile
25% recovery - Higher redundancy for damaged codes
<option value="Q">Alta</option>
H
High
30% recovery - Required when embedding logos
<option value="H">Máxima (Logo)</option>
This level is automatically selected when a logo is uploaded, regardless of the user’s selection.
Implementation: src/components/QRGenerator.jsx:211-216

Handler functions

The component exposes three handler functions for user interactions:

handleDownloadPNG

function handleDownloadPNG(): void
Exports the QR code as a high-resolution PNG image. Process:
  1. Queries the hidden Canvas element from qrRef
  2. Converts Canvas to PNG data URL via toDataURL('image/png')
  3. Changes MIME type to 'image/octet-stream' to force download
  4. Creates temporary anchor element with download attribute
  5. Programmatically clicks anchor to trigger download
  6. Cleans up by removing the anchor element
Output filename: qr-premium.png Implementation:
const handleDownloadPNG = () => {
  const canvas = qrRef.current?.querySelector('canvas');
  if (!canvas) return;

  const pngUrl = canvas
    .toDataURL("image/png")
    .replace("image/png", "image/octet-stream");
  
  let downloadLink = document.createElement("a");
  downloadLink.href = pngUrl;
  downloadLink.download = "qr-premium.png";
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
};
Source: src/components/QRGenerator.jsx:47-58

handleDownloadSVG

function handleDownloadSVG(): void
Exports the QR code as a scalable vector SVG file. Process:
  1. Queries the visible SVG element from qrRef
  2. Serializes SVG DOM to string using XMLSerializer
  3. Creates Blob with MIME type 'image/svg+xml;charset=utf-8'
  4. Generates temporary object URL from Blob
  5. Creates anchor element and triggers download
  6. Cleans up by revoking object URL and removing anchor
Output filename: qr-premium-vector.svg Implementation:
const handleDownloadSVG = () => {
  const svg = qrRef.current?.querySelector('svg');
  if (!svg) return;

  const svgData = new XMLSerializer().serializeToString(svg);
  const blob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
  const url = URL.createObjectURL(blob);

  let downloadLink = document.createElement("a");
  downloadLink.href = url;
  downloadLink.download = "qr-premium-vector.svg";
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
  URL.revokeObjectURL(url);
};
Source: src/components/QRGenerator.jsx:60-75
Unlike PNG export, SVG export properly revokes the object URL to prevent memory leaks. This is necessary because object URLs persist in memory until explicitly revoked or the page is closed.

handleLogoUpload

function handleLogoUpload(e: React.ChangeEvent<HTMLInputElement>): void
Processes logo image uploads and converts them to data URLs. Parameters:
  • e: Change event from file input element
Process:
  1. Extracts first file from input’s FileList
  2. Creates FileReader instance
  3. Registers onload handler that updates logoUrl state
  4. Reads file as data URL (base64-encoded string)
Implementation:
const handleLogoUpload = (e) => {
  const file = e.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = (event) => setLogoUrl(event.target.result);
    reader.readAsDataURL(file);
  }
};
Source: src/components/QRGenerator.jsx:77-84 Usage in JSX:
<input 
  type="file" 
  accept="image/*" 
  onChange={handleLogoUpload} 
  style={{ display: 'none' }} 
/>
Source: src/components/QRGenerator.jsx:199

Template data structures

Detailed schemas for each template’s data format:

WiFi data object

wifiData.ssid
string
default:"''"
Network name (Service Set Identifier)
<input 
  value={wifiData.ssid} 
  onChange={(e) => setWifiData({ ...wifiData, ssid: e.target.value })} 
  placeholder="Mi Red WiFi" 
/>
wifiData.password
string
default:"''"
Network password
<input 
  value={wifiData.password} 
  onChange={(e) => setWifiData({ ...wifiData, password: e.target.value })} 
  placeholder="********" 
/>
wifiData.encryption
'WPA' | 'WEP' | 'nopass'
default:"'WPA'"
Network security type
  • 'WPA': WPA/WPA2 encryption (most common)
  • 'WEP': Legacy WEP encryption
  • 'nopass': Open network (no password)
<select 
  value={wifiData.encryption} 
  onChange={(e) => setWifiData({ ...wifiData, encryption: e.target.value })}
>
  <option value="WPA">WPA/WPA2</option>
  <option value="WEP">WEP</option>
  <option value="nopass">Sin Contraseña</option>
</select>
wifiData.hidden
boolean
default:"false"
Whether the network broadcasts its SSID
hidden: false // Currently not exposed in UI
Generated QR value:
`WIFI:S:${wifiData.ssid};T:${wifiData.encryption};P:${wifiData.password};H:${wifiData.hidden};;`
Source: src/components/QRGenerator.jsx:11,32,117-134

vCard data object

vcardData.firstName
string
default:"''"
Contact’s first name
<input 
  value={vcardData.firstName} 
  onChange={(e) => setVcardData({ ...vcardData, firstName: e.target.value })} 
  placeholder="Juan" 
/>
vcardData.lastName
string
default:"''"
Contact’s last name
<input 
  value={vcardData.lastName} 
  onChange={(e) => setVcardData({ ...vcardData, lastName: e.target.value })} 
  placeholder="Pérez" 
/>
vcardData.phone
string
default:"''"
Contact’s phone number (mobile)
<input 
  value={vcardData.phone} 
  onChange={(e) => setVcardData({ ...vcardData, phone: e.target.value })} 
  placeholder="+1 234 567 8900" 
/>
vcardData.email
string
default:"''"
Contact’s email address
<input 
  value={vcardData.email} 
  onChange={(e) => setVcardData({ ...vcardData, email: e.target.value })} 
  placeholder="[email protected]" 
/>
vcardData.company
string
default:"''"
Contact’s organization/company name
// Not directly exposed in UI, but included in state
company: ''
Generated QR value:
const vcard = `BEGIN:VCARD
VERSION:3.0
N:${vcardData.lastName};${vcardData.firstName};;;
FN:${vcardData.firstName} ${vcardData.lastName}
ORG:${vcardData.company}
TEL;TYPE=CELL:${vcardData.phone}
EMAIL:${vcardData.email}
END:VCARD`;
Source: src/components/QRGenerator.jsx:12,34-36,138-156

Email data object

emailData.to
string
default:"''"
Recipient email address
<input 
  value={emailData.to} 
  onChange={(e) => setEmailData({ ...emailData, to: e.target.value })} 
  placeholder="[email protected]" 
/>
emailData.subject
string
default:"''"
Email subject line (URL-encoded in output)
<input 
  value={emailData.subject} 
  onChange={(e) => setEmailData({ ...emailData, subject: e.target.value })} 
  placeholder="Consulta de servicios" 
/>
emailData.body
string
default:"''"
Email body content (URL-encoded in output)
// Not currently exposed in UI, but included in state
body: ''
Generated QR value:
`mailto:${emailData.to}?subject=${encodeURIComponent(emailData.subject)}&body=${encodeURIComponent(emailData.body)}`
Subject and body parameters are URL-encoded using encodeURIComponent() to properly handle special characters, spaces, and non-ASCII text.
Source: src/components/QRGenerator.jsx:13,39,159-168

Dependencies reference

External packages used by the QRGenerator component:

qrcode.react (v4.2.0)

QRCodeSVG
React.Component
Renders QR codes as SVG elements. Used for the visible preview and vector export.
import { QRCodeSVG } from 'qrcode.react';
QRCodeCanvas
React.Component
Renders QR codes on HTML Canvas. Used exclusively for PNG export at high resolution.
import { QRCodeCanvas } from 'qrcode.react';
npm: npm install qrcode.react Documentation: https://github.com/zpao/qrcode.react

lucide-react (v0.576.0)

Icon components used throughout the UI:
Icons
React.Component[]
import { 
  Download,    // Export buttons
  QrCode,      // Empty state icon
  Settings2,   // Customization section
  Link as LinkIcon, // URL tab
  Wifi,        // WiFi tab
  User,        // vCard tab
  Mail,        // Email tab
  Image as ImageIcon, // Logo upload
  Trash2       // Logo removal
} from 'lucide-react';
npm: npm install lucide-react Documentation: https://lucide.dev/ Source: src/components/QRGenerator.jsx:1-3

Build docs developers (and LLMs) love