|
1 | 1 | # @devmehq/react-qr-code |
2 | 2 |
|
3 | | -Simple & Advanced React component to generate [QR codes](http://en.wikipedia.org/wiki/QR_code) |
4 | | - |
| 3 | +🎯 Simple & Advanced React component to generate [QR codes](http://en.wikipedia.org/wiki/QR_code) with custom styling, multiple render formats, and image embedding support. |
5 | 4 |
|
6 | 5 | [](https://npm.im/@devmehq/react-qr-code) |
7 | 6 | [](https://github.com/devmehq/react-qr-code/actions) |
8 | 7 | [](https://www.npmjs.com/package/@devmehq/react-qr-code) |
| 8 | +[](https://bundlephobia.com/package/@devmehq/react-qr-code) |
| 9 | +[](https://github.com/devmehq/react-qr-code/blob/master/LICENSE.md) |
9 | 10 | [](https://unpkg.com/browse/@devmehq/react-qr-code@latest/) |
10 | 11 |
|
11 | 12 | [](https://codesandbox.io/s/react-qr-code-demo-ccho5l?fontsize=14&hidenavigation=1&theme=dark) |
12 | | -## Installation |
13 | 13 |
|
14 | | -```npm |
| 14 | +## ✨ Features |
| 15 | + |
| 16 | +- 🎨 **Customizable**: Colors, sizes, margins, and styles |
| 17 | +- 🖼️ **Multiple Formats**: Render as SVG or Canvas |
| 18 | +- 📱 **Responsive**: Scales perfectly on all devices |
| 19 | +- 🏞️ **Image Embedding**: Add logos or images to QR codes |
| 20 | +- 🛡️ **Error Correction**: Four levels (L, M, Q, H) |
| 21 | +- 📦 **Lightweight**: Zero dependencies, small bundle size |
| 22 | +- 🔧 **TypeScript**: Full TypeScript support |
| 23 | +- ⚡ **Performance**: Optimized rendering with React hooks |
| 24 | + |
| 25 | +## 📦 Installation |
| 26 | + |
| 27 | +```bash |
| 28 | +# Using npm |
15 | 29 | npm install @devmehq/react-qr-code |
| 30 | + |
| 31 | +# Using yarn |
| 32 | +yarn add @devmehq/react-qr-code |
| 33 | + |
| 34 | +# Using pnpm |
| 35 | +pnpm add @devmehq/react-qr-code |
| 36 | +``` |
| 37 | + |
| 38 | +## 🚀 Quick Start |
| 39 | + |
| 40 | +### Basic Usage |
| 41 | + |
| 42 | +```tsx |
| 43 | +import React from 'react' |
| 44 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 45 | + |
| 46 | +function App() { |
| 47 | + return <ReactQrCode value="https://github.com/devmehq/react-qr-code" /> |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +### With Custom Styling |
| 52 | + |
| 53 | +```tsx |
| 54 | +import React from 'react' |
| 55 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 56 | + |
| 57 | +function StyledQRCode() { |
| 58 | + return ( |
| 59 | + <ReactQrCode |
| 60 | + value="https://your-website.com" |
| 61 | + size={300} |
| 62 | + bgColor="#f3f4f6" |
| 63 | + fgColor="#1f2937" |
| 64 | + level="H" |
| 65 | + marginSize={4} |
| 66 | + style={{ borderRadius: '8px' }} |
| 67 | + className="shadow-lg" |
| 68 | + /> |
| 69 | + ) |
| 70 | +} |
| 71 | +``` |
| 72 | + |
| 73 | +### Canvas Rendering |
| 74 | + |
| 75 | +```tsx |
| 76 | +import React from 'react' |
| 77 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 78 | + |
| 79 | +function CanvasQRCode() { |
| 80 | + return ( |
| 81 | + <ReactQrCode |
| 82 | + value="https://your-website.com" |
| 83 | + renderAs="canvas" |
| 84 | + size={256} |
| 85 | + /> |
| 86 | + ) |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +### With Logo/Image |
| 91 | + |
| 92 | +```tsx |
| 93 | +import React from 'react' |
| 94 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 95 | + |
| 96 | +function QRCodeWithLogo() { |
| 97 | + return ( |
| 98 | + <ReactQrCode |
| 99 | + value="https://your-website.com" |
| 100 | + size={256} |
| 101 | + images={[ |
| 102 | + { |
| 103 | + src: '/logo.png', |
| 104 | + height: 50, |
| 105 | + width: 50, |
| 106 | + excavate: true, |
| 107 | + }, |
| 108 | + ]} |
| 109 | + /> |
| 110 | + ) |
| 111 | +} |
| 112 | +``` |
| 113 | + |
| 114 | +## 📖 API Reference |
| 115 | + |
| 116 | +### ReactQrCode Props |
| 117 | + |
| 118 | +| Prop | Type | Default | Description | |
| 119 | +| ------------ | -------------------------- | ------------ | --------------------------------------- | |
| 120 | +| `value` | `string` | **Required** | The value to encode in the QR code | |
| 121 | +| `renderAs` | `'svg' \| 'canvas'` | `'svg'` | Render format (SVG or Canvas) | |
| 122 | +| `size` | `number` | `256` | Size of the QR code in pixels | |
| 123 | +| `bgColor` | `string` | `'#ffffff'` | Background color (CSS color value) | |
| 124 | +| `fgColor` | `string` | `'#000000'` | Foreground color (CSS color value) | |
| 125 | +| `level` | `'L' \| 'M' \| 'Q' \| 'H'` | `'L'` | Error correction level | |
| 126 | +| `marginSize` | `number` | `0` | Margin around the QR code in pixels | |
| 127 | +| `style` | `CSSProperties` | `undefined` | React style object | |
| 128 | +| `className` | `string` | `undefined` | CSS class name | |
| 129 | +| `title` | `string` | `undefined` | Title for SVG accessibility | |
| 130 | +| `id` | `string` | `undefined` | HTML id attribute | |
| 131 | +| `images` | `ReactQrCodeImageProps[]` | `undefined` | Array of images to embed in the QR code | |
| 132 | + |
| 133 | +### ReactQrCodeImageProps |
| 134 | + |
| 135 | +| Property | Type | Default | Description | |
| 136 | +| ---------- | --------- | -------------- | -------------------------------------------- | |
| 137 | +| `src` | `string` | **Required** | Image source URL | |
| 138 | +| `x` | `number` | Auto-centered | X position of the image | |
| 139 | +| `y` | `number` | Auto-centered | Y position of the image | |
| 140 | +| `height` | `number` | 10% of QR size | Height of the image | |
| 141 | +| `width` | `number` | 10% of QR size | Width of the image | |
| 142 | +| `excavate` | `boolean` | `false` | Whether to clear QR modules behind the image | |
| 143 | + |
| 144 | +### Error Correction Levels |
| 145 | + |
| 146 | +| Level | Error Correction | Data Capacity | |
| 147 | +| ----- | ---------------- | ------------- | |
| 148 | +| `L` | ~7% | High | |
| 149 | +| `M` | ~15% | Medium | |
| 150 | +| `Q` | ~25% | Medium-Low | |
| 151 | +| `H` | ~30% | Low | |
| 152 | + |
| 153 | +## 🎨 Styling & Customization |
| 154 | + |
| 155 | +### Responsive Design |
| 156 | + |
| 157 | +```tsx |
| 158 | +import React from 'react' |
| 159 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 160 | + |
| 161 | +function ResponsiveQRCode() { |
| 162 | + return ( |
| 163 | + <div style={{ width: '100%', maxWidth: '400px' }}> |
| 164 | + <ReactQrCode |
| 165 | + value="https://your-website.com" |
| 166 | + size={256} |
| 167 | + style={{ width: '100%', height: 'auto' }} |
| 168 | + /> |
| 169 | + </div> |
| 170 | + ) |
| 171 | +} |
16 | 172 | ``` |
17 | 173 |
|
18 | | -```yarn |
19 | | -yarn install @devmehq/react-qr-code |
| 174 | +### Dark Mode Support |
| 175 | + |
| 176 | +```tsx |
| 177 | +import React from 'react' |
| 178 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 179 | + |
| 180 | +function DarkModeQRCode({ isDarkMode }) { |
| 181 | + return ( |
| 182 | + <ReactQrCode |
| 183 | + value="https://your-website.com" |
| 184 | + bgColor={isDarkMode ? '#1f2937' : '#ffffff'} |
| 185 | + fgColor={isDarkMode ? '#f3f4f6' : '#000000'} |
| 186 | + /> |
| 187 | + ) |
| 188 | +} |
20 | 189 | ``` |
21 | 190 |
|
22 | | -## Usage |
| 191 | +### Custom CSS Classes |
23 | 192 |
|
24 | | -```typescript |
25 | | -import React from 'react'; |
26 | | -import { ReactQrCode } from '@devmehq/react-qr-code'; |
| 193 | +```tsx |
| 194 | +import React from 'react' |
| 195 | +import { ReactQrCode } from '@devmehq/react-qr-code' |
| 196 | +import './styles.css' |
| 197 | + |
| 198 | +function CustomStyledQRCode() { |
| 199 | + return ( |
| 200 | + <ReactQrCode |
| 201 | + value="https://your-website.com" |
| 202 | + className="qr-code-custom" |
| 203 | + size={300} |
| 204 | + /> |
| 205 | + ) |
| 206 | +} |
| 207 | +``` |
27 | 208 |
|
28 | | -<ReactQrCode value="http://facebook.github.io/react/" /> |
| 209 | +```css |
| 210 | +/* styles.css */ |
| 211 | +.qr-code-custom { |
| 212 | + border-radius: 16px; |
| 213 | + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
| 214 | + padding: 16px; |
| 215 | + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| 216 | +} |
29 | 217 | ``` |
30 | 218 |
|
31 | | -```js |
32 | | -var React = require('react'); |
33 | | -var { ReactQrCode } = require('@devmehq/react-qr-code'); |
| 219 | +**Note:** When using `renderAs="canvas"` on high-density displays, the canvas is scaled for pixel-perfect rendering. Custom styles are merged with internal scaling styles. |
34 | 220 |
|
35 | | -<ReactQrCode value="http://facebook.github.io/react/" /> |
| 221 | +## 💡 Use Cases |
| 222 | + |
| 223 | +### WiFi Password Sharing |
| 224 | + |
| 225 | +```tsx |
| 226 | +function WiFiQRCode({ ssid, password, security = 'WPA' }) { |
| 227 | + const wifiString = `WIFI:T:${security};S:${ssid};P:${password};;` |
| 228 | + |
| 229 | + return <ReactQrCode value={wifiString} size={256} level="H" /> |
| 230 | +} |
36 | 231 | ``` |
37 | 232 |
|
38 | | -## Available Props |
| 233 | +### Contact Information (vCard) |
39 | 234 |
|
40 | | -| prop | type | default value | |
41 | | -|--------------|------------------------------|---------------| |
42 | | -| `value` | `string` | | |
43 | | -| `renderAs` | `string` (`'canvas' 'svg'`) | `'canvas'` | |
44 | | -| `size` | `number` | `128` | |
45 | | -| `bgColor` | `string` (CSS color) | `"#FFFFFF"` | |
46 | | -| `fgColor` | `string` (CSS color) | `"#000000"` | |
47 | | -| `level` | `string` (`'L' 'M' 'Q' 'H'`) | `'L'` | |
48 | | -| `marginSize` | `number` | `false` | |
49 | | -| `images` | `array` (see below) | | |
| 235 | +```tsx |
| 236 | +function ContactQRCode({ name, phone, email }) { |
| 237 | + const vCard = `BEGIN:VCARD |
| 238 | +VERSION:3.0 |
| 239 | +FN:${name} |
| 240 | +TEL:${phone} |
| 241 | +EMAIL:${email} |
| 242 | +END:VCARD` |
50 | 243 |
|
51 | | -### `imageSettings` |
| 244 | + return <ReactQrCode value={vCard} size={256} level="M" /> |
| 245 | +} |
| 246 | +``` |
52 | 247 |
|
53 | | -| field | type | default value | |
54 | | -|------------|-----------|-------------------| |
55 | | -| `src` | `string` | | |
56 | | -| `x` | `number` | none, will center | |
57 | | -| `y` | `number` | none, will center | |
58 | | -| `height` | `number` | 10% of `size` | |
59 | | -| `width` | `number` | 10% of `size` | |
60 | | -| `excavate` | `boolean` | `false` | |
| 248 | +### Two-Factor Authentication |
61 | 249 |
|
62 | | -## Custom Styles |
| 250 | +```tsx |
| 251 | +function TwoFactorQRCode({ secret, issuer, accountName }) { |
| 252 | + const otpauth = `otpauth://totp/${issuer}:${accountName}?secret=${secret}&issuer=${issuer}` |
63 | 253 |
|
64 | | -`@devmehq/react-qr-code` will pass through any additional props to the underlying DOM node (`<svg>` or `<canvas>`). This allows the use of inline `style` or custom `className` to customize the rendering. One common use would be to support a responsive layout. |
| 254 | + return ( |
| 255 | + <ReactQrCode |
| 256 | + value={otpauth} |
| 257 | + size={256} |
| 258 | + level="H" |
| 259 | + images={[ |
| 260 | + { |
| 261 | + src: '/logo.png', |
| 262 | + height: 40, |
| 263 | + width: 40, |
| 264 | + excavate: true, |
| 265 | + }, |
| 266 | + ]} |
| 267 | + /> |
| 268 | + ) |
| 269 | +} |
| 270 | +``` |
| 271 | + |
| 272 | +### Payment Links |
65 | 273 |
|
66 | | -**Note:** In order to render QR Codes in `<canvas>` on high density displays, we scale the canvas element to contain an appropriate number of pixels and then use inline styles to scale back down. We will merge any additional styles, with custom `height` and `width` overriding our own values. This allows scaling to percentages *but* if scaling beyond the `size`, you will encounter blurry images. I recommend detecting resizes with something like [react-measure](https://github.com/souporserious/react-measure) to detect and pass the appropriate size when rendering to `<canvas>`. |
| 274 | +```tsx |
| 275 | +function PaymentQRCode({ amount, recipient, currency = 'USD' }) { |
| 276 | + const paymentLink = `https://pay.example.com/?to=${recipient}&amount=${amount}¤cy=${currency}` |
| 277 | + |
| 278 | + return <ReactQrCode value={paymentLink} size={300} level="H" marginSize={4} /> |
| 279 | +} |
| 280 | +``` |
67 | 281 |
|
68 | 282 | <img src="https://github.com/devmehq/react-qr-code/raw/master/examples/qrcode-demo.png" alt="qrcode-demo"> |
69 | 283 |
|
| 284 | +## 🧪 Testing |
| 285 | + |
| 286 | +```bash |
| 287 | +# Run tests |
| 288 | +yarn test |
| 289 | + |
| 290 | +# Run tests in watch mode |
| 291 | +yarn test:watch |
| 292 | + |
| 293 | +# Generate coverage report |
| 294 | +yarn test:coverage |
| 295 | +``` |
| 296 | + |
| 297 | +## 🔧 Development |
| 298 | + |
| 299 | +```bash |
| 300 | +# Install dependencies |
| 301 | +yarn install |
| 302 | + |
| 303 | +# Build the library |
| 304 | +yarn build |
| 305 | + |
| 306 | +# Run linting |
| 307 | +yarn lint-js |
| 308 | + |
| 309 | +# Format code |
| 310 | +yarn prettier |
| 311 | +``` |
| 312 | + |
| 313 | +## 🤝 Contributing |
| 314 | + |
| 315 | +Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests. |
| 316 | + |
| 317 | +1. Fork the repository |
| 318 | +2. Create your feature branch (`git checkout -b feature/amazing-feature`) |
| 319 | +3. Commit your changes (`git commit -m 'Add some amazing feature'`) |
| 320 | +4. Push to the branch (`git push origin feature/amazing-feature`) |
| 321 | +5. Open a Pull Request |
| 322 | + |
| 323 | +## 📝 Roadmap |
| 324 | + |
| 325 | +- [ ] Download QR code as image (PNG/JPEG/SVG) |
| 326 | +- [ ] Share QR code functionality |
| 327 | +- [ ] Server-side rendering (SSR) support |
| 328 | +- [ ] Corner dot customization |
| 329 | +- [ ] Gradient color support |
| 330 | +- [ ] Custom shape modules (dots, rounded, etc.) |
| 331 | +- [ ] Animation support |
| 332 | +- [ ] Batch QR code generation |
| 333 | +- [ ] QR code scanner component |
| 334 | + |
| 335 | +## 📄 License |
| 336 | + |
| 337 | +This project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details. |
| 338 | + |
| 339 | +## 🙏 Acknowledgments |
| 340 | + |
| 341 | +- QR Code is a registered trademark of DENSO WAVE INCORPORATED |
| 342 | +- Built with ❤️ by the [DEV.ME](https://dev.me) team |
| 343 | +- Inspired by the QR code specification and community feedback |
| 344 | + |
| 345 | +## 📧 Support |
| 346 | + |
| 347 | +For support, email support@dev.me or open an issue on [GitHub](https://github.com/devmehq/react-qr-code/issues). |
70 | 348 |
|
71 | | -## TODO |
72 | | -- Add Image Ref |
73 | | -- Add Corner Images and Center Image |
74 | | -- Add Examples to wifi password, 2fa, and other QR codes |
75 | | -- ADD SSR Rendering Support |
76 | | -- Add Download / Share QR Code |
77 | | -- Add Test |
| 349 | +--- |
78 | 350 |
|
79 | | -## LICENSE [MIT](LICENSE.md) |
| 351 | +<div align="center"> |
| 352 | + Made with ❤️ by <a href="https://dev.me">DEV.ME</a> |
| 353 | +</div> |
0 commit comments