Generate fully scannable, beautifully styled QR codes with custom dot shapes, finder patterns, image overlays, and one-click SVG/PNG download — all integrated with the Mantine design system.
Introduction
The Mantine QR Code component has been completely rebuilt from the ground up. What was previously an LED-style indicator has been transformed into a fully functional QR code generator that produces real, scannable codes from any string input. It renders pure SVG for crisp output at any resolution, follows Mantine's Styles API conventions, and ships with a dedicated download hook for exporting to SVG, PNG, JPEG, or WebP.
✨ New Features
Real QR Code Generation
The component now encodes actual QR code data using the qrcode library. Pass any string — a URL, WiFi credentials, vCard, plain text — and get a scannable QR code rendered as optimized SVG.
import { QRCode } from '@gfazioli/mantine-qr-code';
function Demo() {
return <QRCode value="https://mantine.dev" />;
}
The value prop is the only required prop. Everything else has sensible defaults.
Dot Styles
Control the appearance of data modules with the dotStyle prop. Three built-in styles are available:
<QRCode value="https://mantine.dev" dotStyle="square" /> {/* Default */}
<QRCode value="https://mantine.dev" dotStyle="rounded" />
<QRCode value="https://mantine.dev" dotStyle="dots" />
Each style generates a single combined <path> element for all data modules, keeping the DOM lightweight even for dense QR codes.
Corner Styles
The three finder patterns (the large squares in the corners) can be styled independently with cornerStyle:
<QRCode value="https://mantine.dev" cornerStyle="square" /> {/* Default */}
<QRCode value="https://mantine.dev" cornerStyle="rounded" />
<QRCode value="https://mantine.dev" cornerStyle="dots" />
Mix and match dot and corner styles for unique designs:
<QRCode
value="https://mantine.dev"
dotStyle="dots"
cornerStyle="rounded"
color="violet"
/>
Image Overlay with Excavation
Add a logo or image at the center of the QR code. The component automatically removes ("excavates") the data modules behind the image to keep the code scannable:
<QRCode
value="https://mantine.dev"
size="xl"
image="https://example.com/logo.png"
imageSize={0.2}
imageRadius="md"
imagePadding={1}
imageExcavate={true}
errorCorrectionLevel="H"
/>
Tip: Use
errorCorrectionLevel="H"when overlaying images — it provides 30% error correction, ensuring the code remains scannable even with a portion covered.
Error Correction Levels
Four standard error correction levels are supported via the errorCorrectionLevel prop:
| Level | Recovery | Best for |
|---|---|---|
L |
~7% | Dense data, minimal damage expected |
M |
~15% | General use (default) |
Q |
~25% | Moderate resilience |
H |
~30% | Image overlays, printed codes |
useQRCodeDownload Hook
A dedicated hook makes it easy to export the QR code in multiple formats:
import { QRCode, useQRCodeDownload } from '@gfazioli/mantine-qr-code';
function Demo() {
const { ref, download, getDataUrl } = useQRCodeDownload({
fileName: 'my-qr-code',
scale: 4, // 4x resolution for raster formats
});
return (
<>
<QRCode ref={ref} value="https://mantine.dev" />
<button onClick={() => download({ format: 'svg' })}>Download SVG</button>
<button onClick={() => download({ format: 'png' })}>Download PNG</button>
</>
);
}
Supported formats: svg, png, jpeg, webp. The getDataUrl function returns a data URL — useful for preview thumbnails or embedding.
Theme-Aware Colors
Both foreground and background colors integrate with the Mantine theme:
<QRCode value="https://mantine.dev" color="blue" background="gray.1" />
<QRCode value="https://mantine.dev" color="white" background="dark" />
<QRCode value="https://mantine.dev" color="teal" background="transparent" />
Full Styles API
The component exposes 8 style selectors for granular customization:
| Selector | Element | Description |
|---|---|---|
root |
<div> |
Outer container |
svg |
<svg> |
SVG element |
background |
<rect> |
Background rectangle |
modules |
<path> |
Combined data modules path |
finderPattern |
<g> |
Finder pattern group (×3) |
finderOuter |
<path> |
Outer ring of finder pattern |
finderInner |
<path> |
Inner square of finder pattern |
image |
<image> |
Center image overlay |
CSS Variables
| Variable | Description |
|---|---|
--qr-code-size |
Width and height |
--qr-code-radius |
Container border radius |
--qr-code-color |
Foreground (module) color |
--qr-code-background |
Background color |
Size presets: xs (80px), sm (120px), md (160px), lg (200px), xl (256px).
🔧 Improvements
-
SVG Accessibility: The SVG element includes
role="img"and anaria-labelderived from the encoded value. -
Optimized Rendering: All data modules are combined into a single
<path>element, keeping the DOM minimal regardless of QR code density. -
Memoized Computation: QR matrix generation and SVG path building are wrapped in
useMemo— re-computation only happens when relevant props change. -
SSR Compatible: No browser-only APIs (
window,document) are used during rendering. The download hook uses browser APIs only when explicitly called.
📖 Complete Props Reference
interface QRCodeBaseProps {
value: string; // Required — data to encode
size?: MantineSize | string | number; // Default: 'md'
radius?: MantineRadius | string | number; // Container border radius
color?: MantineColor; // Default: 'dark'
background?: MantineColor | 'transparent'; // Default: 'white'
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H'; // Default: 'M'
quietZone?: number; // Default: 1
dotStyle?: 'square' | 'rounded' | 'dots'; // Default: 'square'
cornerStyle?: 'square' | 'rounded' | 'dots'; // Default: 'square'
image?: string; // Center image URL
imageSize?: number; // 0–1, default: 0.2
imageRadius?: MantineRadius | string | number;
imagePadding?: number; // Default: 1
imageExcavate?: boolean; // Default: true
}
Getting Started
Install the package:
npm install @gfazioli/mantine-qr-code
Import styles at the root of your application:
import '@gfazioli/mantine-qr-code/styles.css';
Use the component:
import { QRCode } from '@gfazioli/mantine-qr-code';
function App() {
return (
<QRCode
value="https://mantine.dev"
size="lg"
dotStyle="rounded"
cornerStyle="rounded"
color="blue"
/>
);
}
Use Cases
{/* URL */}
<QRCode value="https://mantine.dev" />
{/* WiFi credentials */}
<QRCode value="WIFI:T:WPA;S:MyNetwork;P:MyPassword;;" />
{/* vCard contact */}
<QRCode value="BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nTEL:+1234567890\nEND:VCARD" />


Top comments (0)