Home

Awesome

QR Code Styling

Version

JavaScript library for generating QR codes with a logo and styling.

Try it here https://qr-code-styling.com

If you have issues / suggestions / notes / questions, please open an issue or contact me. Let's create a cool library together.

Examples

<p float="left"> <img style="display:inline-block" src="https://raw.githubusercontent.com/kozakdenys/qr-code-styling/master/src/assets/facebook_example_new.png" width="240" /> <img style="display:inline-block" src="https://raw.githubusercontent.com/kozakdenys/qr-code-styling/master/src/assets/qr_code_example.png" width="240" /> <img style="display:inline-block" src="https://raw.githubusercontent.com/kozakdenys/qr-code-styling/master/src/assets/telegram_example_new.png" width="240" /> </p>

Extensions

If you would like to use additional stiles, you can connect extensions.

qr-border-plugin

<p float="left"> <img style="display:inline-block" src="https://www.lefe.dev/_static/packages/qr-border-plugin-1.svg" width="240" /> <img style="display:inline-block" src="https://www.lefe.dev/_static/packages/qr-border-plugin-2.svg" width="240" /> </p>

Installation

npm install qr-code-styling

Usage

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>QR Code Styling</title>
    <script type="text/javascript" src="https://unpkg.com/qr-code-styling@1.5.0/lib/qr-code-styling.js"></script>
</head>
<body>
<div id="canvas"></div>
<script type="text/javascript">

    const qrCode = new QRCodeStyling({
        width: 300,
        height: 300,
        type: "svg",
        data: "https://www.facebook.com/",
        image: "https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg",
        dotsOptions: {
            color: "#4267b2",
            type: "rounded"
        },
        backgroundOptions: {
            color: "#e9ebee",
        },
        imageOptions: {
            crossOrigin: "anonymous",
            margin: 20
        }
    });

    qrCode.append(document.getElementById("canvas"));
    qrCode.download({ name: "qr", extension: "svg" });
</script>
</body>
</html>

React example (Codesandbox)

Angular example (Codesandbox)


React example (source)

Angular example (source)

Vue example (source)

Node.js example (source)

Next.js example (source)


API Documentation

QRCodeStyling instance

new QRCodeStyling(options) => QRCodeStyling

ParamTypeDescription
optionsobjectInit object

options structure

PropertyTypeDefault ValueDescription
widthnumber300Size of canvas
heightnumber300Size of canvas
typestring ('canvas' 'svg')canvasThe type of the element that will be rendered
datastringThe date will be encoded to the QR code
imagestringThe image will be copied to the center of the QR code
marginnumber0Margin around canvas
qrOptionsobjectOptions will be passed to qrcode-generator lib
imageOptionsobjectSpecific image options, details see below
dotsOptionsobjectDots styling options
cornersSquareOptionsobjectSquare in the corners styling options
cornersDotOptionsobjectDots in the corners styling options
backgroundOptionsobjectQR background styling options
nodeCanvasnode-canvasOnly specify when running on a node server for canvas type, please refer to node section below
jsDomjsdomOnly specify when running on a node server for svg type, please refer to node section below

options.qrOptions structure

PropertyTypeDefault Value
typeNumbernumber (0 - 40)0
modestring ('Numeric' 'Alphanumeric' 'Byte' 'Kanji')
errorCorrectionLevelstring ('L' 'M' 'Q' 'H')'Q'

options.imageOptions structure

PropertyTypeDefault ValueDescription
hideBackgroundDotsbooleantrueHide all dots covered by the image
imageSizenumber0.4Coefficient of the image size. Not recommended to use ove 0.5. Lower is better
marginnumber0Margin of the image in px
crossOriginstring('anonymous' 'use-credentials')Set "anonymous" if you want to download QR code from other origins.
saveAsBlobbooleantrueSaves image as base64 blob in svg type, see bellow

When QR type is svg, the image may not load in certain applications as it is saved as a url, and some svg applications will not render url images for security reasons. Setting saveAsBlob to true will instead save the image as a blob, allowing it to render correctly in more places, but will also increase the file size.

options.dotsOptions structure

PropertyTypeDefault ValueDescription
colorstring'#000'Color of QR dots
gradientobjectGradient of QR dots
typestring ('rounded' 'dots' 'classy' 'classy-rounded' 'square' 'extra-rounded')'square'Style of QR dots
roundSizebooleantrueWhether to round dots size to integer. true value might create extra margin around qr code. If false, shape-rendering="crispEdges" will be applied to SVG element.

options.backgroundOptions structure

PropertyTypeDefault Value
colorstring ('#fff' 'rgb(255,255,255)' 'transparent')'#fff'
gradientobject

options.cornersSquareOptions structure

PropertyTypeDefault ValueDescription
colorstringColor of Corners Square
gradientobjectGradient of Corners Square
typestring ('dot' 'square' 'extra-rounded')Style of Corners Square

options.cornersDotOptions structure

PropertyTypeDefault ValueDescription
colorstringColor of Corners Dot
gradientobjectGradient of Corners Dot
typestring ('dot' 'square')Style of Corners Dot

Gradient structure

options.dotsOptions.gradient

options.backgroundOptions.gradient

options.cornersSquareOptions.gradient

options.cornersDotOptions.gradient

PropertyTypeDefault ValueDescription
typestring ('linear' 'radial')"linear"Type of gradient spread
rotationnumber0Rotation of gradient in radians (Math.PI === 180 degrees)
colorStopsarray of objectsGradient colors. Example [{ offset: 0, color: 'blue' }, { offset: 1, color: 'red' }]

Gradient colorStops structure

options.dotsOptions.gradient.colorStops[]

options.backgroundOptions.gradient.colorStops[]

options.cornersSquareOptions.gradient.colorStops[]

options.cornersDotOptions.gradient.colorStops[]

PropertyTypeDefault ValueDescription
offsetnumber (0 - 1)Position of color in gradient range
colorstringColor of stop in gradient range

QRCodeStyling methods

QRCodeStyling.append(container) => void

ParamTypeDescription
containerDOM elementThis container will be used for appending of the QR code

QRCodeStyling.getRawData(extension) => Promise<Blob>

ParamTypeDefault ValueDescription
extensionstring ('png' 'jpeg' 'webp' 'svg')'png'Blob type on browser, Buffer type on Node

QRCodeStyling.update(options) => void

ParamTypeDescription
optionsobjectThe same options as for initialization

QRCodeStyling.applyExtension(extension) => void

ParamTypeDescription
extension(svg, options) => voidExtension is a function that takes svg and previously applied options and modifies an svg

applyExtension example

const extension = (svg, options) => {
    const { width, height } = options;
    const size = Math.min(width, height);
    const border = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    const borderAttributes = {
        "fill": "none",
        "x": (width - size + 40) / 2,
        "y": (height - size + 40) / 2,
        "width": size - 40,
        "height": size - 40,
        "stroke": 'black',
        "stroke-width": 40,
        "rx": 100,
    };
    Object.keys(borderAttributes).forEach(attribute => {
      border.setAttribute(attribute, borderAttributes[attribute]);
    });
    svg.appendChild(border);
};

QRCodeStyling.deleteExtension() => void

QRCodeStyling.download(downloadOptions) => Promise<void>

ParamTypeDescription
downloadOptionsobjectOptions with extension and name of file (not required)

Promise returned will resolve into the data URI of the QR code image.

downloadOptions structure

PropertyTypeDefault ValueDescription
namestring'qr'Name of the downloaded file
extensionstring ('png' 'jpeg' 'webp' 'svg')'png'File extension

Building this repo

If you get an error running npm install referring to node-pre-gyp, this is caused by an attempt to compile the canvas dependency. See Compiling instructions in the README. For example on MacOS you need to install dependencies: brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman.

Node Support

You can use this on a node server by passing through the node-canvas or jsdom object depending if your creating a non-svg or svg respectively. You must pass both if using imageOptions.saveAsBlob.

Calling getRawData in node will return a Buffer instead of a Blob.

const { QRCodeStyling } = require("qr-code-styling/lib/qr-code-styling.common.js");
const nodeCanvas = require("canvas");
const { JSDOM } = require("jsdom");
const fs = require("fs");

const options = {
    width: 300,
    height: 300,
    data: "https://www.facebook.com/",
    image: "https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg",
    dotsOptions: {
        color: "#4267b2",
        type: "rounded"
    },
    backgroundOptions: {
        color: "#e9ebee",
    },
    imageOptions: {
        crossOrigin: "anonymous",
        margin: 20
    }
}

// For canvas type
const qrCodeImage = new QRCodeStyling({
    jsdom: JSDOM, // this is required
    nodeCanvas, // this is required,
    ...options,
    imageOptions: {
        saveAsBlob: true,
        crossOrigin: "anonymous",
        margin: 20
    },
});

qrCodeImage.getRawData("png").then((buffer) => {
  fs.writeFileSync("test.png", buffer);
});

// For svg type
const qrCodeSvg = new QRCodeStyling({
    jsdom: JSDOM, // this is required
    type: "svg",
    ...options
});

qrCodeSvg.getRawData("svg").then((buffer) => {
  fs.writeFileSync("test.svg", buffer);
});

// For svg type with the inner-image saved as a blob
// (inner-image will render in more places but file will be larger)
const qrCodeSvgWithBlobImage = new QRCodeStyling({
    jsdom: JSDOM, // this is required
    nodeCanvas, // this is required
    type: "svg",
    ...options,
    imageOptions: {
        saveAsBlob: true,
        crossOrigin: "anonymous",
        margin: 20
    }
});

qrCodeSvgWithBlobImage.getRawData("svg").then((buffer) => {
  fs.writeFileSync("test_blob.svg", buffer);
});

License

MIT License. Copyright (c) 2021 Denys Kozak