QRCode.js Comprehensive Documentation
Introduction
QRCode.js is a professional JavaScript/TypeScript library for creating customized QR codes, offering a blend of simplicity and sophistication. With versatile styling options—dot shapes, colors, gradients, embedded images, borders, and text—it enables you to design unique, visually appealing QR codes that work flawlessly with standard scanners. QRCode.js is part of QR-Platform: All-in-One QR Codes Management Solution.
This documentation provides a comprehensive overview of all available options to help you create the perfect QR code for your needs.
Installation
# Using npm
npm install @qr-platform/qr-code.js
# Using yarn
yarn add @qr-platform/qr-code.js
# Using pnpm
pnpm add @qr-platform/qr-code.js
Basic Usage
import { QRCodeJs } from '@qr-platform/qr-code.js';
// Create a basic QR code
const qrCode = new QRCodeJs({
data: 'https://example.com',
});
// Render the QR code to a container
qrCode.append(document.getElementById('qr-container'));
Core Options
data
- Purpose: The content to be encoded in the QR code
- Type:
string - Required: Yes
- Example:
'https://example.com'
shape
- Purpose: Overall shape of the QR code
- Type:
ShapeTypeenum - Default:
'square' - Possible values:
'square','circle' - Example:
shape: 'circle'
margin
- Purpose: Empty space around the QR code (in pixels)
- Type:
number - Default:
0 - Example:
margin: 20
isResponsive
- Purpose: Allows the QR code SVG to resize dynamically based on its container size. If
false, fixedwidthandheightattributes are set on the SVG. - Type:
boolean - Default:
false - Example:
isResponsive: true
qrOptions
Options that affect the QR code generation algorithm.
typeNumber
- Purpose: Specifies the QR code version (size and capacity)
- Type:
TypeNumber(0-40) - Default:
0(auto-determine based on content) - Example:
qrOptions: { typeNumber: 4 }
mode
- Purpose: Encoding mode for the QR data
- Type:
Modeenum - Default: Auto-detected based on content
- Possible values:
'numeric','alphanumeric','byte','kanji','unicode' - Example:
qrOptions: { mode: 'alphanumeric' }
errorCorrectionLevel
- Purpose: Determines error correction capability
- Type:
ErrorCorrectionLevelenum - Default:
'Q' - Possible values:
'L': Low - 7% error recovery'M': Medium - 15% error recovery'Q': Quality - 25% error recovery'H': High - 30% error recovery
- Example:
qrOptions: { errorCorrectionLevel: 'H' }
Layout Options
Options controlling the positioning and scaling of the QR code within its container.
scale
- Purpose: Scales the QR code size relative to its container or border. Useful for adjusting size within borders.
- Type:
number(0 to 1.5) - Default:
1 - Example:
scale: 0.8 // Make QR code 80% of available space
offset
- Purpose: Applies a vertical offset (positive moves down, negative moves up) to the QR code relative to the center. Useful for fine-tuning position, especially with borders.
- Type:
number - Default:
0 - Example:
offset: -10 // Move QR code 10px up
verticalOffset
- Purpose: Applies a vertical offset (positive moves down, negative moves up) to the QR code, independent of other calculations.
- Type:
number - Default:
0 - Example:
verticalOffset: 5 // Move QR code 5px down
horizontalOffset
- Purpose: Applies a horizontal offset (positive moves right, negative moves left) to the QR code, independent of other calculations.
- Type:
number - Default:
0 - Example:
horizontalOffset: -5 // Move QR code 5px left
Styling Options
Dots (dotsOptions)
Controls the appearance of individual QR code dots.
type
- Purpose: Shape of the dots in the QR code
- Type:
DotTypeenum - Default:
'square' - Possible values:
'dot': Round dots'square': Square dots'rounded': Slightly rounded squares'extraRounded': More rounded squares'classy': Dots with a distinctive classy pattern'classyRounded': Classy dots with rounded corners'verticalLine': Vertical line pattern'horizontalLine': Horizontal line pattern'randomDot': Randomized dot pattern'smallSquare': Smaller square dots'tinySquare': Very small square dots'star': Star-shaped dots'plus': Plus-shaped dots'diamond': Diamond-shaped dots
- Example:
dotsOptions: { type: 'rounded' }
color
- Purpose: Color of the dots
- Type:
string(CSS color, hex, rgb, rgba) - Default:
'#000000' - Example:
dotsOptions: { color: '#FF5733' }
size
- Purpose: Size of the dots in pixels
- Type:
number - Default:
10 - Example:
dotsOptions: { size: 12 }
gradient
- Purpose: Apply a gradient fill to the dots
- Type:
Gradientobject (see Gradients) - Default:
undefined - Example:
dotsOptions: { gradient: { type: 'linear', rotation: Math.PI / 4, colorStops: [{ offset: 0, color: 'blue' }, { offset: 1, color: 'red' }] } }
Corner Squares (cornersSquareOptions)
These options override dotsOptions for the three large corner squares of the QR code.
type
- Purpose: Shape of the corner squares
- Type:
CornerSquareTypeenum - Default: Inherits from
dotsOptions.typeor uses'dot' - Possible values:
'dot': Round corner squares'square': Square corner squares'rounded': Rounded corner squares'classy': Classy corner squares'outpoint': Corner squares with outward points'inpoint': Corner squares with inward points
- Example:
cornersSquareOptions: { type: 'outpoint' }
color
- Purpose: Color of the corner squares
- Type:
string(CSS color, hex, rgb, rgba) - Default: Inherits from
dotsOptions.coloror uses'#000000' - Example:
cornersSquareOptions: { color: '#0000FF' }
gradient
- Purpose: Apply a gradient fill to the corner squares (overrides
dotsOptions.gradient) - Type:
Gradientobject (see Gradients) - Default:
undefined - Example:
cornersSquareOptions: { gradient: { type: 'radial', colorStops: [{ offset: 0, color: 'green' }, { offset: 1, color: 'yellow' }] } }
Corner Dots (cornersDotOptions)
These options override cornersSquareOptions for the smaller dots within the corner squares.
type
- Purpose: Shape of the corner dots
- Type:
CornerDotTypeenum - Default: Inherits from
cornersSquareOptions.typeor uses'dot' - Possible values:
'dot': Round corner dots'square': Square corner dots'heart': Heart-shaped corner dots'rounded': Rounded corner dots'classy': Classy corner dots'outpoint': Corner dots with outward points'inpoint': Corner dots with inward points
- Example:
cornersDotOptions: { type: 'heart' }
color
- Purpose: Color of the corner dots
- Type:
string(CSS color, hex, rgb, rgba) - Default: Inherits from
cornersSquareOptions.coloror uses'#000000' - Example:
cornersDotOptions: { color: '#FF0000' }
gradient
- Purpose: Apply a gradient fill to the corner dots (overrides
cornersSquareOptions.gradient) - Type:
Gradientobject (see Gradients) - Default:
undefined - Example:
cornersDotOptions: { gradient: { type: 'linear', rotation: 0, colorStops: [{ offset: 0, color: 'orange' }, { offset: 1, color: 'purple' }] } }
Background (backgroundOptions)
Controls the QR code background.
- Purpose: Configures the background of the QR code
- Type:
objectorfalseto disable the background - Default:
{ color: '#FFFFFF' }
color
- Purpose: Background color
- Type:
string(CSS color, hex, rgb, rgba) - Default:
'#FFFFFF' - Example:
backgroundOptions: { color: '#F5F5F5' }
round
- Purpose: Rounds the corners of the background (0-1 value or percentage)
- Type:
numberorstring - Default:
0 - Example:
backgroundOptions: { round: 0.5 }
gradient
- Purpose: Apply a gradient fill to the background
- Type:
Gradientobject (see Gradients) - Default:
undefined - Example:
backgroundOptions: { gradient: { type: 'linear', rotation: Math.PI / 2, colorStops: [{ offset: 0, color: '#eee' }, { offset: 1, color: '#ccc' }] } }
Image Embedding
image
- Purpose: URL, Buffer, or Blob of an image to embed in the QR code. This can be set directly in the options, or via
QRCodeJs.setImage()for a global default, orQRCodeJs.useImage()for a builder-specific image. - Type:
string | Buffer | Blob - Example:
image: 'https://example.com/logo.png'
Override Behavior with setImage and useImage
- Both
setImageanduseImagemethods can accept an optional second parameter with{ override: true }to ensure the image takes precedence over any image set elsewhere. - Example with Override:
// Global image that will override any instance-specific images QRCodeJs.setImage('https://example.com/global-logo.png', { override: true }); // Builder pattern with image that will override final options const qr = QRCodeJs.useImage('https://example.com/important-logo.png', { override: true }) .options({ data: 'https://example.com', image: 'https://example.com/this-will-be-ignored.png' // Will be ignored due to override });
imageOptions
Options for the embedded image.
mode
- Purpose: How the image is embedded in the QR code
- Type:
ImageModeenum - Default:
'center' - Possible values:
'center': Image placed in the center, QR code dots reflow around it'overlay': Image placed on top of the QR code'background': Image used as a background with dots drawn over it
- Example:
imageOptions: { mode: 'center' }
imageSize
- Purpose: Relative size of the image (0-1)
- Type:
number - Default:
0.4 - Example:
imageOptions: { imageSize: 0.5 }
margin
- Purpose: Margin around the image in dot units
- Type:
number - Default:
0 - Example:
imageOptions: { margin: 2 }
crossOrigin
- Purpose: CORS setting for the image
- Type:
string - Default:
undefined - Example:
imageOptions: { crossOrigin: 'anonymous' }
fill
- Purpose: Fill color for transparent areas in the image
- Type:
object - Default:
{ color: 'rgba(255,255,255,1)' } - Properties:
color: A solid color fill (string)gradient: A gradient fill (Gradientobject, see Gradients)
- Example (Solid Color):
imageOptions: { fill: { color: 'rgba(255,255,255,0.75)' } } - Example (Gradient Fill):
imageOptions: { fill: { gradient: { type: 'radial', colorStops: [{ offset: 0, color: 'rgba(255,255,255,1)' }, { offset: 1, color: 'rgba(255,255,255,0)' }] } } }
Gradients
Gradients can be applied to multiple elements: dotsOptions, cornersSquareOptions, cornersDotOptions, backgroundOptions, and imageOptions.fill.
Gradient Structure
- Type:
object - Properties:
type: Type of gradient ('linear'or'radial')rotation: Rotation of gradient in radians (for linear gradients)colorStops: Array of color stop objects withoffset(0-1) andcolorproperties
Example
{
dotsOptions: {
gradient: {
type: 'linear',
rotation: Math.PI / 4, // 45 degrees
colorStops: [
{ offset: 0, color: '#8F00FF' }, // Start color
{ offset: 1, color: '#0080FF' } // End color
]
}
}
}
Borders
QRCode.js provides border features:
- Basic border styling like color and thickness is supported
- Full control over all sides of the border
- Advanced border features (inner borders, outer borders, custom text)
- Fine-grained control over border appearance
- Inner and outer borders can be styled independently
- Decorative text and images can be added to each side of the border
borderOptions
Options for adding decorative borders around the QR code. Borders can be configured globally using QRCodeJs.setBorder() / QRCodeJs.setBorderId() or on a per-instance basis using the builder pattern initiated with QRCodeJs.useBorder() / QRCodeJs.useBorderId().
hasBorder
- Purpose: Master switch to enable/disable borders
- Type:
boolean - Example:
borderOptions: { hasBorder: true }
thickness
- Purpose: Thickness of the main border in pixels
- Type:
number - Example:
borderOptions: { thickness: 50 }
color
- Purpose: Color of the main border
- Type:
string(CSS color, hex, rgb, rgba) - Default:
'#000000' - Example:
borderOptions: { color: 'blue' }
radius
- Purpose: Corner rounding of the border
- Type:
string(px or %) - Default:
'0%' - Example:
borderOptions: { radius: '40%' }
noBorderThickness
- Purpose: Thickness to use for a border side if its decoration is disabled (e.g., text is not shown). Useful for maintaining alignment.
- Type:
number - Default:
borderOptions.thickness / 4 - Example:
borderOptions: { noBorderThickness: 5 }
background
- Purpose: Background color specifically for the border area itself.
- Type:
string(CSS color, hex, rgb, rgba) - Default:
undefined - Example:
borderOptions: { background: '#DDDDDD' }
inner
- Purpose: Options for scaling/offsetting the inner content area
- Type:
object - Properties:
radius: Corner rounding of the inner border (string)scale: Scale factor for the inner content (number, 0-1.5)horizontalOffset: Horizontal offset of the inner content (number)verticalOffset: Vertical offset of the inner content (number)
- Example:
borderOptions: { inner: { radius: '10%', scale: 0.8, horizontalOffset: -15, verticalOffset: 10 } }
borderOuter
- Purpose: Options for an additional border outside the main one
- Type:
object - Properties:
color: Color of the outer border (string)thickness: Thickness of the outer border (number)
- Example:
borderOptions: { borderOuter: { color: '#002683', thickness: 10 } }
borderInner
- Purpose: Options for an additional border inside the main one
- Type:
object - Properties:
color: Color of the inner border (string)thickness: Thickness of the inner border (number)
- Example:
borderOptions: { borderInner: { color: 'yellow', thickness: 5 } }
decorations
- Purpose: Add text or images to specific sides of the border
- Type:
object - Properties: Configuration for each side (
top,right,bottom,left) - Example:
borderOptions: { decorations: { top: { disabled: false, enableText: true, offset: 0, curveAdjustment: 0, curveDisabled: false, curveRadius: '50%', type: 'text', value: 'SCAN ME', style: { fontFace: 'Helvetica', fontSize: 28, fontColor: '#ffffff', textTransform: 'uppercase', letterSpacing: 2, fontWeight: 'bold' } } } }
Each decoration object can have these properties:
disabled: Whether this side's decoration is disabledenableText: Whether to enable text on this sideoffset: Positioning offset for the decorationcurveAdjustment: Adjustment for text curvecurveDisabled: Whether to disable curved textcurveRadius: Radius of the text curvetype: Type of decoration ('text'or'image')value: Text content or image URLstyle: Style options for text (font, size, color, etc.)
Example Usage of Borders
const qrCode = new QRCodeJs({
data: 'https://example.com',
borderOptions: {
hasBorder: true,
thickness: 40,
color: '#0033CC',
radius: '10%'
}
});
// Then create QR code with custom border text
const qrCode = new QRCodeJs({
data: 'https://example.com',
borderOptions: {
hasBorder: true,
thickness: 40,
color: '#0033CC',
radius: '10%',
decorations: {
bottom: {
enableText: true,
type: 'text',
value: 'Scan Me',
style: {
fontFace: 'Arial',
fontSize: 24,
fontColor: '#FFFFFF'
}
}
}
}
});
Border Text Methods
QRCode.js provides dedicated methods for managing text on QR code borders, allowing for convenient text configuration across all sides.
Static Methods for Global Text Settings
setText()
- Purpose: Sets global default text for QR code borders that will apply to all subsequently created instances.
- Type:
function(textNameOrOptions: string | TextOptions | null, options?: { override?: boolean }): typeof QRCodeJs - Parameters:
textNameOrOptions: A predefined text template name (e.g., 'Scan Me (Top)'), a customTextOptionsobject, ornullto clearoptions: Optional configuration withoverrideproperty to ensure text takes precedence
- Returns: The QRCodeJs class for chaining
- Example:
// Set global text on top and bottom border sides QRCodeJs.setText({ topValue: 'SCAN ME', bottomValue: 'www.example.com' }); // Use a predefined text template QRCodeJs.setText('Scan Me (Top)'); // With override option to ensure it takes precedence QRCodeJs.setText({ topValue: 'MUST DISPLAY THIS TEXT' }, { override: true }); // Clear global text QRCodeJs.setText(null);
setTextId()
- Purpose: Sets global default text for QR code borders by referencing a predefined template ID.
- Type:
function(textId: string | null, options?: { override?: boolean }): typeof QRCodeJs - Parameters:
textId: ID of a predefined text template (e.g., 'visit-website-bottom') ornullto clearoptions: Optional configuration withoverrideproperty to ensure text takes precedence
- Returns: The QRCodeJs class for chaining
- Example:
// Set global text using a predefined template ID QRCodeJs.setTextId('scan-to-visit-website'); // With override option QRCodeJs.setTextId('lost-found', { override: true }); // Clear global text QRCodeJs.setTextId(null);
Builder Methods for Instance-Specific Text
useText()
- Purpose: Initiates a builder pattern pre-configured with border text from a template name or custom options.
- Type:
function(textNameOrOptions: string | TextOptions, options?: { override?: boolean }): QRCodeBuilder - Parameters:
textNameOrOptions: A predefined text template name or a customTextOptionsobjectoptions: Optional configuration withoverrideproperty to ensure text takes precedence
- Returns: A
QRCodeBuilderinstance for chaining - Example:
// Start builder with custom text options const qrCode = QRCodeJs.useText({ topValue: 'VISIT OUR WEBSITE', bottomValue: 'www.example.com' }).options({ data: 'https://example.com' }); // Start builder with a predefined text template const qrWithTemplate = QRCodeJs.useText('Scan Me (Bottom)') .options({ data: 'https://example.com/scan-me' }); // With override option to ensure text takes precedence over final options const qrWithOverride = QRCodeJs.useText( { leftValue: 'IMPORTANT TEXT' }, { override: true } ).options({ data: 'https://example.com', borderOptions: { decorations: { left: { value: 'This will be ignored', enableText: true } } } });
useTextId()
- Purpose: Initiates a builder pattern pre-configured with border text from a predefined template ID.
- Type:
function(textId: string, options?: { override?: boolean }): QRCodeBuilder - Parameters:
textId: ID of a predefined text template (e.g., 'visit-website-bottom')options: Optional configuration withoverrideproperty to ensure text takes precedence
- Returns: A
QRCodeBuilderinstance for chaining - Example:
// Start builder with a predefined text template by ID const qrCode = QRCodeJs.useTextId('scan-to-visit-website') .options({ data: 'https://example.com' }); // With override option const qrWithOverride = QRCodeJs.useTextId('scan-me', { override: true }) .options({ data: 'https://example.com' });
TextOptions Structure
The TextOptions object allows you to specify text for each side of the QR code border:
interface TextOptions {
topValue?: string | null; // Text for top border (null explicitly disables)
rightValue?: string | null; // Text for right border
bottomValue?: string | null; // Text for bottom border
leftValue?: string | null; // Text for left border
}
- Setting a value to
nullexplicitly disables text on that side - Omitting a property (undefined) leaves any existing text on that side unchanged
- Empty string (
'') will be treated as no text but withenableText: true
Override Behavior
All text methods accept an optional { override: true } parameter to ensure the text values take precedence over any text settings applied at a later stage:
setText()with override will override text from instance optionssetTextId()with override will override text from instance optionsuseText()with override will override text from final.options()calluseTextId()with override will override text from final.options()call
This is particularly useful when you need to ensure specific text appears regardless of other configuration.
Example: Combining Text Methods with Border Options
// Set global default for all QR codes
QRCodeJs.setText({
topValue: 'SCAN ME',
bottomValue: 'www.example.com'
});
// Create QR code with custom border that uses the global text
const qrCode = new QRCodeJs({
data: 'https://example.com',
borderOptions: {
hasBorder: true,
thickness: 40,
color: '#0033CC',
radius: '10%'
// No decoration settings needed - will use the global text
}
});
// Chain builder methods for more complex setup
const qrChained = QRCodeJs.useBorder('Rounded Border (Large)')
.useText({
topValue: 'POWERED BY',
bottomValue: 'QR-PLATFORM'
})
.options({ data: 'https://example.com/chained' });
Clearing Text Settings
To remove text from borders:
// Clear global text settings
QRCodeJs.setText(null);
// Clear text on specific sides
QRCodeJs.setText({
topValue: null, // Explicitly remove top text
bottomValue: null, // Explicitly remove bottom text
});
// Use a predefined "empty" template to clear all sides
QRCodeJs.useText('empty-text-options').options({
data: 'https://example.com'
});
Scan Validation
The QRCode.js library offers functionality to validate that generated QR codes are scannable.
validateScanning()
- Purpose: Verify the generated QR code is scannable
- Returns:
Promise<ScanValidatorResponse>resolving to a validation result object ({ isValid: boolean, decodedText?: string, message?: string }) - Example:
const qrCode = new QRCodeJs({ data: 'https://example.com' }); qrCode.validateScanning() .then(result => { if (result.isValid) { console.log('QR code is valid and scannable!'); console.log('Decoded text:', result.decodedText); } else { console.log('QR code validation failed:', result.message); } });
Node.js Usage
QRCode.js can also be used in Node.js environments.
Installation
Follow the standard installation steps using npm or yarn.
Basic Usage
import { QRCodeJs, Options } from '@qr-platform/qr-code.js/node'; // Import from '@qr-platform/qr-code.js/node'
import fs from 'fs';
const options: Options = {
data: 'https://example.com',
};
const qrCode = new QRCodeJs(options);
qrCode.serialize().then(svgString => {
if (svgString) {
fs.writeFileSync('qrcode.svg', svgString);
console.log('QR Code saved to qrcode.svg');
}
});
Key Differences & Considerations
- Import Path: Use
import { QRCodeJs } from '@qr-platform/qr-code.js/node';. - Peer Dependencies: You must install the required
peerDependenciesfor Node.js functionality.
Install automatically using npx:npx i-peers @qr-platform/qr-code.js
Install manually using npm:npm i @xmldom/xmldom @undecaf/zbar-wasm image-size jose jimp @resvg/resvg-js file-type - No Canvas/Download: Methods relying on browser APIs like
append(),download(), or internal canvas generation are not available or behave differently in the Node.js version.
QRCode.js provides a comprehensive system for generating QR codes with advanced features:
- QR code generation, styling options (colors, shapes, dot types), image embedding and borders
- Advanced border customization
- Custom border text
- Inner and outer borders
- Scan validation tools
- Full control over border sides and styling
Centralized Configuration with Settings (SettingsOptions, setSettings, useSettings)
For a comprehensive way to define or apply a complete QR code configuration in one go, QRCode.js provides:
- A
SettingsOptionsinterface to structure a full configuration. - A static
QRCodeJs.setSettings()method for establishing global defaults using aSettingsOptionsobject. - A
useSettings()method for theQRCodeBuilderto apply aSettingsOptionsobject as a baseline for a specific builder chain.
SettingsOptions Object
The SettingsOptions object allows you to define multiple aspects of a QR code configuration simultaneously:
id?: string: Optional unique identifier for the settings preset.name?: string: Optional descriptive name for the settings preset.description?: string: Optional detailed description of the settings preset.data?: string: The primary data to encode. This will be applied as the maindataoption.image?: string | Buffer | Blob: Image to embed. This will be applied as the mainimageoption.template?: string | RecursivePartial<Options>: Template by name or options object. Maps toQRCodeJs.setTemplate()when used withQRCodeJs.setSettings().templateId?: string: Template by ID. Maps toQRCodeJs.setTemplateId().style?: string | StyleOptions: Style by name orStyleOptionsobject. Maps toQRCodeJs.setStyle().styleId?: string: Style by ID. Maps toQRCodeJs.setStyleId().text?: string | TextOptions: Text configuration by name orTextOptionsobject. Maps toQRCodeJs.setText().textId?: string: Text configuration by ID. Maps toQRCodeJs.setTextId().border?: string | RecursivePartial<BorderOptions>: Border configuration by name or options object. Maps toQRCodeJs.setBorder().borderId?: string: Border configuration by ID. Maps toQRCodeJs.setBorderId().options?: RecursivePartial<Options>: Direct overrides for any mainOptionsproperties. These are deeply merged. Maps toQRCodeJs.setOptions().
Refer to the TypeScript Types and Definitions for the full structure.
Static QRCodeJs.setSettings()
The QRCodeJs.setSettings(settings: SettingsOptions | null) static method sets multiple global defaults at once.
- Behavior: It acts as a macro, internally calling other static setters (like
QRCodeJs.setTemplate(),QRCodeJs.setStyle(),QRCodeJs.setData(),QRCodeJs.setImage(),QRCodeJs.setOptions(), etc.) based on the properties provided in thesettingsobject. - It will override/reset any previously set static configurations for the aspects it covers. For example, if
settingsincludes atemplateId, any previous global template set byQRCodeJs.setTemplate()will be replaced. Similarly, ifsettings.datais provided, it callsQRCodeJs.setData(settings.data), and ifsettings.optionsis provided, it callsQRCodeJs.setOptions(settings.options). - Passing
nullwill clear all static configurations (template, style, text, border, image, data, and options).
Example:
const myGlobalPreset: SettingsOptions = {
name: 'CompanyStandard',
data: 'https://company.com/default-link', // Will call QRCodeJs.setData()
image: 'https://company.com/assets/logo.png', // Will call QRCodeJs.setImage()
templateId: 'company-wide-template', // Assumes this template ID exists, will call QRCodeJs.setTemplateId()
options: { // Will call QRCodeJs.setOptions()
qrOptions: { errorCorrectionLevel: 'H' },
margin: 5
}
};
QRCodeJs.setSettings(myGlobalPreset);
// Subsequent QRCodeJs instances will use these global defaults
const qr1 = new QRCodeJs({ /* data will be 'https://company.com/default-link' */ });
const qr2 = new QRCodeJs({ data: 'https://company.com/specific-page' }); // Overrides data from preset
// To clear all global settings:
// QRCodeJs.setSettings(null);
Builder useSettings()
The QRCodeBuilder.useSettings(settings: SettingsOptions) method applies a SettingsOptions object as a new baseline for a specific builder chain.
- Behavior: Calling
useSettings()on a builder instance will reset any configurations previously applied to that builder instance via methods likeuseTemplate(),useStyle(),useBorder(),useText(),useImage(),useData(), oruseOptions(). The providedsettingsobject then establishes the new comprehensive baseline for that builder. - Subsequent builder methods chained after
useSettings()(e.g.,.useStyle(),.options()) will then modify this new baseline.
Example:
const eventSpecificSettings: SettingsOptions = {
name: 'ConferenceQR',
data: 'https://conference-event.com/details', // Baseline data for this builder
image: 'event-logo.png', // Baseline image
style: { dotsOptions: { type: 'classy', color: '#005FAB' } }, // Baseline style
borderId: 'event-frame' // Baseline border
};
const qrEvent = QRCodeJs.useTemplate('basic') // Initial template (will be reset by useSettings)
.useStyle({ dotsOptions: { color: 'red'} }) // This style will also be reset
.useSettings(eventSpecificSettings) // Resets builder and applies eventSpecificSettings as baseline
.useOptions({ margin: 20 }) // Further customizes the baseline from eventSpecificSettings
.options({ data: 'https://conference-event.com/live-updates' }) // Final data override
.build();
qrEvent.append(document.getElementById('event-qr-container'));
Using Templates, Styles, Borders, Data, Options, and Settings
QRCode.js offers flexible ways to manage configurations, from setting global defaults that apply to all new instances to using a fluent builder pattern for specific instances.
Setting Global Defaults
Static methods on the QRCodeJs class allow you to define default configurations that will be automatically applied to all QRCodeJs instances created after these defaults are set. This is useful for establishing a baseline style or configuration for your application.
QRCodeJs.setTemplate(templateNameOrOptions | null)/QRCodeJs.setTemplateId(id | null): Sets a global default template.QRCodeJs.setStyle(styleNameOrOptions | null)/QRCodeJs.setStyleId(id | null): Sets a global default style.QRCodeJs.setBorder(borderNameOrOptions | null)/QRCodeJs.setBorderId(id | null): Sets a global default border configuration.QRCodeJs.setText(textNameOrOptions | null, overrideOpts?: MethodOverrideOptions)/QRCodeJs.setTextId(id | null, overrideOpts?: MethodOverrideOptions): Sets global default border text. TheoverrideOpts(e.g.,{ override: true }) ensures this text takes precedence over text set by other means (e.g., in instance options).QRCodeJs.setImage(imageUrl | null, overrideOpts?: MethodOverrideOptions): Sets a global default image.overrideOptsensures this image takes precedence over images set by other means.QRCodeJs.setData(data | null, overrideOpts?: MethodOverrideOptions): Sets a global default data string.overrideOptsensures this data takes precedence.QRCodeJs.setOptions(options | null, overrideOpts?: MethodOverrideOptions): Sets global default options that are merged deeply.overrideOptsensures higher precedence for these options over those set by other means for the properties they cover.QRCodeJs.setSettings(settings | null): A powerful static method to set multiple global defaults at once using a comprehensiveSettingsOptionsobject (see Centralized Configuration with Settings). This method acts as a macro, calling the other static setters (likesetTemplate,setStyle,setData,setImage,setOptions, etc.) based on the providedsettingsobject. It will override/reset any previously set static configurations for the aspects it covers.
Any options provided during the instantiation of new QRCodeJs({...}) or through builder methods will override these global defaults for that specific instance, unless an override: true was used with a static setter for that specific property. Call any of these setters with null to clear the respective global default.
Example: Setting various global defaults
// Set a global template and data with override
QRCodeJs.setTemplate('dots');
QRCodeJs.setData('https://example-global.com', { override: true }); // This data will be hard to override
const qr1 = new QRCodeJs({ /* data will be https://example-global.com */ });
const qrWithDifferentData = new QRCodeJs({ data: 'https://another-link.com' }); // data will still be https://example-global.com due to override
// Using setSettings to define multiple global defaults
const globalBrandSettings: SettingsOptions = {
templateId: 'brand-template', // Assumes this ID exists
style: { dotsOptions: { color: '#AA0000' } }, // Dark red dots
image: 'https://brand.com/logo.svg', // Global brand logo
data: 'https://brand-default.com', // Default data for this setting
options: { margin: 10, qrOptions: { errorCorrectionLevel: 'M' } }
};
QRCodeJs.setSettings(globalBrandSettings);
// This will override the previous QRCodeJs.setTemplate('dots').
// However, the data 'https://example-global.com' (set with override:true) will persist.
// All other aspects from globalBrandSettings (style, image, options) will apply.
const qrBrand = new QRCodeJs({ /* data is 'https://example-global.com', other options from globalBrandSettings apply */ });
// Reset all global settings
QRCodeJs.setSettings(null); // This clears all static defaults, including the overridden data.
const qrAfterClear = new QRCodeJs({ data: 'https://new-data.com' }); // Now uses 'https://new-data.com'
Using the Builder Pattern
The static use methods (e.g., QRCodeJs.useTemplate(), QRCodeJs.useStyle(), QRCodeJs.useSettings()) initiate a builder pattern. They return a QRCodeBuilder instance pre-configured with the specified settings. This approach does not set global defaults.
QRCodeJs.useTemplate(templateNameOrOptions)/QRCodeJs.useTemplateId(id): Initiates a builder with a template.QRCodeJs.useStyle(styleNameOrOptions)/QRCodeJs.useStyleId(id): Initiates a builder with a style.QRCodeJs.useBorder(borderNameOrOptions)/QRCodeJs.useBorderId(id): Initiates a builder with border settings.QRCodeJs.useText(textNameOrOptions, overrideOpts?: MethodOverrideOptions)/QRCodeJs.useTextId(id, overrideOpts?: MethodOverrideOptions): Initiates a builder with border text settings.overrideOptsensures precedence over text in final.options().QRCodeJs.useImage(imageUrl, overrideOpts?: MethodOverrideOptions): Initiates a builder with an image.overrideOptsensures precedence over image in final.options().QRCodeJs.useData(data, overrideOpts?: MethodOverrideOptions): Applies a data string to the current builder configuration.overrideOptsensures precedence over data in final.options().QRCodeJs.useOptions(options, overrideOpts?: MethodOverrideOptions): Applies a partial options object to the current builder configuration.overrideOptsensures higher precedence for these options over those in final.options()for the properties they cover.QRCodeJs.useSettings(settings): Applies a comprehensiveSettingsOptionsobject as a new baseline for the builder chain, resetting any configurations previously applied to that builder instance via otherusemethods (see Centralized Configuration with Settings).
You must chain these calls with .options(finalOptions) (which also builds the instance) or .build() to get the final QRCodeJs instance. The .options() method takes the final configuration, including the required data property (unless provided by useData, useSettings, or a global default with override) and any ultimate overrides.
Example: Builder Pattern Usage
// Start with a template, then layer styles and data
const qrBuilder1 = QRCodeJs.useTemplate('rounded')
.useStyle({ dotsOptions: { color: '#007BFF' } }) // Blue override for dots
.useData('Built with template and style')
.options({ margin: 10 }); // Final options and build
// Using useSettings to establish a baseline for the builder
const eventSettings: SettingsOptions = {
data: 'https://myevent.com',
image: 'event-logo.png',
styleId: 'event-style' // Assumes 'event-style' is a defined style
};
const qrEvent = QRCodeJs.useSettings(eventSettings) // Establishes baseline from eventSettings
.useText({ topValue: 'SCAN FOR EVENT DETAILS' }) // Adds text to the baseline
.useOptions({ qrOptions: { errorCorrectionLevel: 'H' } }, { override: true }) // These options take high precedence over final .options()
.options({ data: 'Final Event Data Override', qrOptions: { errorCorrectionLevel: 'M' } });
// Final data overrides eventSettings.data.
// errorCorrectionLevel 'M' from .options() is overridden by 'H' from .useOptions() with override:true.
Configuration Precedence
Understanding the order in which options are applied is key:
- Base Defaults: The library's inherent defaults (
baseQRTemplateOptions). - Static Global Defaults: Set by
QRCodeJs.setTemplate(),QRCodeJs.setStyle(),QRCodeJs.setData(),QRCodeJs.setOptions(),QRCodeJs.setSettings(), etc.QRCodeJs.setSettings()calls individual static setters, so its components follow this rule.- Static setters with
{ override: true }(e.g.,setData('data', { override: true })) will have their specific property take precedence over less specific global defaults or later non-overriding instance options.
- Builder Methods:
- If
QRCodeBuilder.useSettings(settings)is called, it resets previous builder steps for that instance and establishessettingsas the new baseline. - Other builder methods (
useTemplate,useStyle,useData,useOptions, etc.) are applied sequentially. If multiple methods affect the same property, later calls generally override earlier ones within the builder chain (either beforeuseSettingsor after it on the new baseline). - Builder methods with
{ override: true }(e.g.,useData('data', { override: true })) will have their specific property take precedence within the builder's accumulated state before the final.options()call, overriding values from the final.options()for those specific properties.
- If
- Final
.options()call on Builder / Constructor Options: Options passed directly here (e.g.,new QRCodeJs(options)orbuilder.options(options)) override global defaults and accumulated builder configurations, unless a global or builder setting for a specific property was set with{ override: true }.
In summary for a single property (e.g., data or image):
- A value set with
{ override: true }(either static or builder) is very sticky and will generally win. - Otherwise, instance-specific options (from constructor or
.options()) override builder-accumulated options (that were not set with override). - Builder-accumulated options (not set with override) override global static defaults (not set with override).
- Global static defaults (not set with override) override base library defaults.
Complete Examples
Basic QR Code with Custom Dots
const qrCode = new QRCodeJs({
data: 'https://example.com',
dotsOptions: {
type: 'rounded',
color: '#0033CC',
size: 12
}
});
qrCode.append(document.getElementById('qr-container'));
QR Code with Custom Corners and Background
const qrCode = new QRCodeJs({
data: 'https://example.com',
shape: 'square',
qrOptions: {
errorCorrectionLevel: 'H'
},
dotsOptions: {
type: 'classy',
color: '#000000'
},
cornersSquareOptions: {
type: 'outpoint',
color: '#FF0000'
},
cornersDotOptions: {
type: 'dot',
color: '#FF0000'
},
backgroundOptions: {
color: '#FFECDB',
round: 0.2
}
});
QR Code with Embedded Logo
const qrCode = new QRCodeJs({
data: 'https://example.com',
image: 'https://example.com/logo.png',
imageOptions: {
mode: 'center',
imageSize: 0.3,
margin: 1,
crossOrigin: 'anonymous',
fill: {
color: 'rgba(255,255,255,1)'
}
},
dotsOptions: {
type: 'dot',
color: '#4267B2'
}
});
QR Code with Border
const qrCode = new QRCodeJs({
data: 'https://example.com',
dotsOptions: {
type: 'rounded',
color: '#0033CC'
},
borderOptions: {
hasBorder: true,
thickness: 50,
color: '#002683',
radius: '5%'
}
});
const qrCode = new QRCodeJs({
data: 'https://example.com',
dotsOptions: {
type: 'extraRounded',
gradient: {
type: 'radial',
colorStops: [
{ offset: 0, color: '#8F00FF' },
{ offset: 1, color: '#0080FF' }
]
}
},
backgroundOptions: {
color: '#FFFFFF',
round: 0.1
},
borderOptions: {
hasBorder: true,
thickness: 50,
color: '#002683',
radius: '40%',
decorations: {
top: {
enableText: true,
type: 'text',
value: 'SCAN ME',
style: {
fontFace: 'Helvetica',
fontSize: 28,
fontColor: '#ffffff',
letterSpacing: 2,
fontWeight: 'bold'
}
},
bottom: {
enableText: true,
type: 'text',
style: {
fontFace: 'Arial',
fontSize: 20,
fontColor: '#ffffff'
}
}
},
borderOuter: {
color: '#001255',
thickness: 10
},
borderInner: {
color: '#334499',
thickness: 5
}
}
});
QR Code with Gradients
const qrCode = new QRCodeJs({
data: 'Gradient Example',
dotsOptions: {
type: 'rounded',
gradient: {
type: 'linear',
rotation: Math.PI / 4,
colorStops: [
{ offset: 0, color: '#ff5733' },
{ offset: 1, color: '#c70039' }
]
}
},
backgroundOptions: {
gradient: {
type: 'radial',
colorStops: [
{ offset: 0, color: '#ffffff' },
{ offset: 1, color: '#e0e0e0' }
]
}
},
cornersSquareOptions: {
type: 'dot',
gradient: {
type: 'linear',
rotation: 0,
colorStops: [
{ offset: 0, color: '#c70039' },
{ offset: 1, color: '#900c3f' }
]
}
}
});
QR Code with Border Layout Adjustments
const qrCode = new QRCodeJs({
data: 'Layout within Border',
scale: 0.75, // Scale the QR code down to 75% within the border
offset: -15, // Move the QR code up slightly within the border
dotsOptions: {
type: 'square',
color: '#333333'
},
borderOptions: {
hasBorder: true,
thickness: 60,
color: '#CCCCCC',
radius: '10%',
decorations: {
bottom: {
enableText: true,
type: 'text',
value: 'SCALED & OFFSET',
style: {
fontFace: 'Arial',
fontSize: 24,
fontColor: '#555555',
fontWeight: 'normal'
}
}
}
}
});
Circular QR Code with Custom Styling
const qrCode = new QRCodeJs({
data: 'https://example.com',
shape: 'circle',
dotsOptions: {
type: 'rounded',
color: '#6200EA'
},
cornersDotOptions: {
type: 'dot',
color: '#00C853'
},
cornersSquareOptions: {
type: 'rounded',
color: '#00C853'
},
backgroundOptions: {
color: '#FFFFFF'
}
});
API Reference
Constructors
new QRCodeJs(options: QRCodeJsOptions)
Methods
append()
Appends the QR code to a container element.
qrCode.append(
container: HTMLElement,
options?: { clearContainer?: boolean }
): QRCodeJs | undefined
serialize()
Converts the QR code to an SVG string.
qrCode.serialize(inverted?: boolean): Promise<string | undefined>
download()
Downloads the QR code as a file.
qrCode.download(
downloadOptions?: {
name?: string;
extension: 'svg' | 'png' | 'jpeg' | 'webp'
},
canvasOptions?: CanvasOptions
): Promise<void>
update()
Updates the QR code with new options.
qrCode.update(options?: RecursivePartial<Options>): void
validateScanning()
Validates that the QR code is scannable.
qrCode.validateScanning(
validatorId?: string,
debug?: boolean
): Promise<ScanValidatorResponse>
Metadata Methods
These helper methods allow attaching or retrieving metadata on a QR code instance.
qrCode.setId(id?: string): this
qrCode.setName(name?: string): this
qrCode.setDescription(description?: string): this
qrCode.setMetadata(metadata?: Record<string, any>): this
qrCode.getId(): string | undefined
qrCode.getName(): string | undefined
qrCode.getDescription(): string | undefined
qrCode.getMetadata(): Record<string, any> | undefined
qrCode.getSettings(): SettingsOptions & { options: Options }
Static Methods
These methods are called directly on the QRCodeJs class (e.g., QRCodeJs.setTemplate()).
Configuration Defaults & Builder Initiators
The following static methods are available on the QRCodeJs class.
Global Defaults:
setTemplate(templateNameOrOptions | null)/setTemplateId(id | null): Sets a global default template.setStyle(styleNameOrOptions | null)/setStyleId(id | null): Sets a global default style.setBorder(borderNameOrOptions | null)/setBorderId(id | null): Sets a global default border configuration.setText(textNameOrOptions | null, overrideOpts?)/setTextId(id | null, overrideOpts?): Sets global default border text.overrideOpts(e.g.,{ override: true }) ensures precedence.setImage(imageUrl | null, overrideOpts?): Sets a global default image.overrideOptsensures precedence.setData(data | null, overrideOpts?): Sets a global default data string.overrideOptsensures precedence.setOptions(options | null, overrideOpts?): Sets global default options (merged deeply).overrideOptsensures higher precedence.setSettings(settings | null): Sets multiple global defaults from aSettingsOptionsobject. Acts as a macro, calling other static setters. Clears all static defaults ifnullis passed.
All set... methods return typeof QRCodeJs for chaining.
Builder Initiators:
These methods initiate a QRCodeBuilder instance.
useTemplate(templateNameOrOptions)/useTemplateId(id): Starts builder with a template.useStyle(styleNameOrOptions)/useStyleId(id): Starts builder with a style.useBorder(borderNameOrOptions)/useBorderId(id): Starts builder with border settings.useText(textNameOrOptions, overrideOpts?)/useTextId(id, overrideOpts?): Starts builder with border text.overrideOptsensures precedence over text in final.options().useImage(imageUrl, overrideOpts?): Starts builder with an image.overrideOptsensures precedence over image in final.options().useData(data, overrideOpts?): Applies data to the builder.overrideOptsensures precedence over data in final.options().useOptions(options, overrideOpts?): Applies options to the builder.overrideOptsensures precedence over options in final.options().useSettings(settings): Applies aSettingsOptionsobject as a new baseline for the builder, resetting prior builder configurations.
All use... methods return a QRCodeBuilder instance for chaining.
Example Signatures (Illustrative):
// Global Defaults
static setData(data: string | null, overrideOpts?: { override?: boolean }): typeof QRCodeJs;
static setOptions(options: RecursivePartial<Options> | null, overrideOpts?: { override?: boolean }): typeof QRCodeJs;
static setSettings(settings: SettingsOptions | null): typeof QRCodeJs;
// Builder Initiators & Methods
static useData(data: string, overrideOpts?: { override?: boolean }): QRCodeBuilder;
static useOptions(options: RecursivePartial<Options>, overrideOpts?: { override?: boolean }): QRCodeBuilder;
static useSettings(settings: SettingsOptions): QRCodeBuilder;
// (Other set... and use... methods follow similar patterns)
Fluent Builder Pattern (useTemplate, useStyle, useSettings, build, etc.)
QRCode.js offers a fluent builder pattern for a more readable and chainable way to configure and create QR codes, especially when combining templates, styles, and custom options.
Overview
Instead of passing all options to the constructor, you can start with a base template, style, border, or image using QRCodeJs.useTemplate(), QRCodeJs.useStyle(), QRCodeJs.useBorder(), or QRCodeJs.useImage(). These methods return a QRCodeBuilder instance. You can then chain further .useTemplate(), .useStyle(), .useBorder(), .useImage(), and finally .options() or .build() to finalize the configuration.
QRCodeJs.useTemplate(template): Starts a builder with a predefined or custom template.QRCodeJs.useStyle(style): Starts a builder and applies a predefined or custom style.QRCodeJs.useBorder(border): Starts a builder and applies a predefined or custom border configuration.QRCodeJs.useImage(imageUrl): Starts a builder and sets an image..useTemplate(template)(on builder): Applies another template. Options merge..useStyle(style)(on builder): Applies another style. Options merge..useBorder(border)(on builder): Applies a border configuration. Options merge..useImage(imageUrl)(on builder): Sets or overrides the image..options(options)(on builder): Merges final specific options and returns theQRCodeJsinstance..build()(on builder, optional method if options(options) is NOT called): Creates theQRCodeJsinstance with the accumulated configuration.
How Builder Methods Work Together
You can chain useTemplate, useStyle, useBorder, and useImage calls. The options are merged progressively. If multiple methods define the same option (e.g., dotsOptions.color from a template and a style, or image from useImage and a template), the option from the last applied method in the chain for that specific property will generally take precedence. The final .options() call provides the ultimate override.
Examples
1. Start with a Template, Add Options:
const qrFromTemplate = QRCodeJs.useTemplate('rounded') // Start with 'rounded' template
.options({ // Merge specific options
data: 'Data for rounded QR',
margin: 10
})
.build(); // Build the final instance
qrFromTemplate.append(document.getElementById('qr-container-1'));
2. Start with a Style, Add Options:
const myStyle = {
dotsOptions: { type: 'dots', color: '#FF6347' }, // Tomato dots
backgroundOptions: { color: '#F0F8FF' } // AliceBlue background
};
const qrFromStyle = QRCodeJs.useStyle(myStyle) // Start with custom style
.options({ // Merge specific options
data: 'Data for styled QR',
qrOptions: { errorCorrectionLevel: 'H' }
})
.build();
qrFromStyle.append(document.getElementById('qr-container-2'));
3. Chain Template and Style:
const qrCombined = QRCodeJs.useTemplate('dots') // Start with 'dots' template (black dots)
.useStyle({ dotsOptions: { color: '#4682B4' } }) // Apply style, overriding dot color to SteelBlue
.useImage('https://example.com/logo.png') // Add an image
.options({ data: 'Template + Style + Image' })
.build();
qrCombined.append(document.getElementById('qr-container-3'));
4. Build without final options:
// Assume 'data' is part of the template or style
const qrBuildDirectly = QRCodeJs.useTemplate({
data: 'Data in template',
dotsOptions: { type: 'square' }
})
.build(); // Build directly if all options are set
qrBuildDirectly.append(document.getElementById('qr-container-4'));
TypeScript Types
Main Options Interface
interface Options {
// Core Data & QR Algorithm
data: string; // Required: Content to encode
qrOptions: {
typeNumber: number; // Default 0 (auto)
mode?: Mode; // Default: auto-detected
errorCorrectionLevel: ErrorCorrectionLevel; // Default 'Q'
};
// Overall Shape & Layout
shape: ShapeType; // Default 'square'
margin?: number; // Default 0: Space around QR code (pixels)
isResponsive?: boolean; // Default false: Allow SVG resizing
scale?: number; // Default 1: Scale QR code within container/border (0-1.5)
offset?: number; // Default 0: Vertical offset relative to center
verticalOffset?: number; // Default 0: Absolute vertical offset
horizontalOffset?: number; // Default 0: Absolute horizontal offset
// Dot Styling
dotsOptions: {
type: DotType; // Default 'square'
color: string; // Default '#000000'
gradient?: Gradient;
size: number; // Default 10 (pixels)
};
// Corner Square Styling (Overrides dotsOptions)
cornersSquareOptions?: {
type?: CornerSquareType; // Default: inherits dotsOptions.type or 'dot'
color?: string; // Default: inherits dotsOptions.color or '#000000'
gradient?: Gradient;
};
// Corner Dot Styling (Overrides cornersSquareOptions)
cornersDotOptions?: {
type?: CornerDotType; // Default: inherits cornersSquareOptions.type or 'dot'
color?: string; // Default: inherits cornersSquareOptions.color or '#000000'
gradient?: Gradient;
};
// Background Styling
backgroundOptions?: {
color?: string; // Default '#FFFFFF'
gradient?: Gradient;
round?: number | string; // Default 0: Corner rounding (0-1 or %)
} | false; // Set to false to disable background
// Image Embedding
image?: string | Buffer | Blob; // Image source (URL, Buffer, Blob)
imageOptions: {
mode?: ImageMode; // Default 'center'
imageSize: number; // Default 0.4: Relative image size (0-1)
margin: number; // Default 0: Margin around image (dot units)
crossOrigin?: string; // Default undefined: CORS setting
fill?: {
color: string; // Default 'rgba(255,255,255,1)'
gradient?: Gradient;
};
};
borderOptions?: {
hasBorder: boolean; // Master switch to enable/disable borders
thickness: number; // Thickness of the main border in pixels
color: string; // Color of the main border
radius: string; // Corner rounding of the border (e.g., '10%', '20px')
noBorderThickness: number; // Thickness for border sides with disabled decorations
background?: string; // Background color for the border area
inner?: {
radius: string;
scale: number;
horizontalOffset: number;
verticalOffset: number;
};
borderOuter?: {
color: string;
thickness: number;
};
borderInner?: {
color: string;
thickness: number;
};
decorations?: {
top?: DecorationOptions;
right?: DecorationOptions;
bottom?: DecorationOptions;
left?: DecorationOptions;
};
};
}
// Supporting Interfaces
interface Gradient {
type: 'linear' | 'radial';
rotation?: number;
colorStops: Array<{ offset: number; color: string }>;
}
interface DecorationOptions {
disabled: boolean;
enableText: boolean;
offset: number;
curveAdjustment: number;
curveDisabled: boolean;
curveRadius: string;
type: 'text' | 'image';
value: string;
style?: {
fontFace: string;
fontSize: number;
fontColor: string;
letterSpacing: number;
fontWeight: 'normal' | 'bold';
};
}
// Enums
enum ShapeType {
square = 'square',
circle = 'circle'
}
enum Mode {
numeric = 'numeric',
alphanumeric = 'alphanumeric',
byte = 'byte',
kanji = 'kanji',
unicode = 'unicode'
}
enum ErrorCorrectionLevel {
L = 'L', // 7% error recovery
M = 'M', // 15% error recovery
Q = 'Q', // 25% error recovery
H = 'H' // 30% error recovery
}
enum DotType {
dot = 'dot',
square = 'square',
rounded = 'rounded',
extraRounded = 'extra-rounded',
classy = 'classy',
classyRounded = 'classy-rounded',
verticalLine = 'vertical-line',
horizontalLine = 'horizontal-line',
randomDot = 'random-dot',
smallSquare = 'small-square',
tinySquare = 'tiny-square',
star = 'star',
plus = 'plus',
diamond = 'diamond'
}
enum CornerSquareType {
dot = 'dot',
square = 'square',
rounded = 'rounded',
classy = 'classy',
outpoint = 'outpoint',
inpoint = 'inpoint'
}
enum CornerDotType {
dot = 'dot',
square = 'square',
heart = 'heart',
rounded = 'rounded',
classy = 'classy',
outpoint = 'outpoint',
inpoint = 'inpoint'
}
enum ImageMode {
center = 'center',
overlay = 'overlay',
background = 'background'
}
Metadata Management
QRCode.js provides comprehensive metadata management capabilities for organizing, tracking, and categorizing QR code instances. This section covers the various metadata features available through both instance methods and the builder pattern.
Overview
Metadata in QRCode.js allows you to:
- Assign unique identifiers to QR code instances
- Provide human-readable names and descriptions
- Attach custom data for tracking and analytics
- Retrieve comprehensive settings information
- Support enterprise-level QR code management workflows
Instance Metadata Methods
Once a QR code instance is created, you can manage its metadata using chainable methods:
Setting Metadata
const qrCode = new QRCodeJs({
data: 'https://company.com/products/laptop-pro'
});
// Chain metadata methods for clean configuration
qrCode
.setId('product-laptop-pro-2024')
.setName('Laptop Pro QR Code')
.setDescription('QR code for Laptop Pro product page with specifications and pricing')
.setMetadata({
productId: 'laptop-pro-001',
category: 'electronics',
subcategory: 'laptops',
brand: 'TechCorp',
price: 1299.99,
inStock: true,
campaign: 'back-to-school-2024',
trackingEnabled: true,
analytics: {
expectedScans: 1000,
conversionTarget: 50
}
});
Retrieving Metadata
// Access individual metadata components
const qrId = qrCode.getId(); // 'product-laptop-pro-2024'
const qrName = qrCode.getName(); // 'Laptop Pro QR Code'
const qrDescription = qrCode.getDescription(); // 'QR code for Laptop Pro...'
const customMetadata = qrCode.getMetadata(); // { productId: 'laptop-pro-001', ... }
// Get comprehensive settings and configuration
const settings = qrCode.getSettings();
console.log('Complete QR Configuration:', settings);
Builder Pattern Metadata
The builder pattern provides elegant metadata assignment during QR code construction:
const enterpriseQR = QRCodeJs.useTemplate('corporate')
.useId('campaign-summer-2024-001')
.useName('Summer Campaign Landing Page')
.useDescription('Primary QR code for summer marketing campaign directing to landing page')
.useMetadata({
campaignId: 'summer-2024',
campaignType: 'seasonal',
targetAudience: ['millennials', 'gen-z'],
channels: ['social-media', 'print', 'email'],
budget: 25000,
duration: {
start: '2024-06-01',
end: '2024-08-31'
},
kpis: {
primary: 'conversion-rate',
secondary: ['engagement', 'reach']
},
geography: {
regions: ['north-america', 'europe'],
languages: ['en', 'es', 'fr', 'de']
}
})
.options({
data: 'https://company.com/summer-campaign-2024',
image: 'https://company.com/assets/summer-logo.png'
});
Enterprise Metadata Patterns
Content Management System Integration
class CMSQRManager {
static createContentQR(content) {
const metadata = {
contentId: content.id,
contentType: content.type,
title: content.title,
author: content.author,
publishDate: content.publishDate,
lastModified: content.lastModified,
tags: content.tags,
language: content.language,
seoScore: content.seoScore,
readingTime: content.estimatedReadingTime
};
return QRCodeJs.useTemplate('cms-standard')
.useId(`cms-${content.type}-${content.id}`)
.useName(`${content.title} - ${content.type}`)
.useDescription(`QR code for ${content.type}: ${content.title}`)
.useMetadata(metadata)
.options({
data: `https://cms.company.com/content/${content.id}`,
qrOptions: { errorCorrectionLevel: 'M' }
});
}
}
// Usage
const articleQR = CMSQRManager.createContentQR({
id: 'art-2024-0315',
type: 'article',
title: 'Future of Sustainable Technology',
author: 'Dr. Jane Smith',
publishDate: '2024-03-15',
lastModified: '2024-03-20',
tags: ['technology', 'sustainability', 'innovation'],
language: 'en',
seoScore: 94,
estimatedReadingTime: '8 minutes'
});
Multi-Channel Campaign Management
class CampaignQRGenerator {
constructor(campaignConfig) {
this.config = campaignConfig;
}
createChannelQR(channel, specific = {}) {
const baseMetadata = {
campaignId: this.config.id,
campaignName: this.config.name,
channel: channel.name,
channelType: channel.type,
medium: channel.medium,
budget: channel.budget,
expectedReach: channel.expectedReach,
createdAt: new Date().toISOString(),
...this.config.globalMetadata
};
return QRCodeJs.useTemplate(this.config.template)
.useId(`${this.config.id}-${channel.name}-${Date.now()}`)
.useName(`${this.config.name} - ${channel.displayName}`)
.useDescription(`${this.config.name} campaign QR for ${channel.displayName}`)
.useMetadata({ ...baseMetadata, ...specific })
.options({
data: `${this.config.baseUrl}?utm_source=${channel.name}&utm_medium=${channel.medium}&utm_campaign=${this.config.id}`,
...channel.qrOptions
});
}
}
// Usage
const campaignGen = new CampaignQRGenerator({
id: 'holiday-2024',
name: 'Holiday Sale Campaign',
template: 'festive',
baseUrl: 'https://store.company.com/holiday-sale',
globalMetadata: {
brand: 'TechCorp',
season: 'holiday',
year: 2024,
department: 'marketing'
}
});
const socialQR = campaignGen.createChannelQR(
{
name: 'instagram',
displayName: 'Instagram',
type: 'social',
medium: 'social-media',
budget: 5000,
expectedReach: 50000,
qrOptions: { margin: 20 }
},
{
platform: 'instagram',
contentType: 'story',
demographics: 'young-adults'
}
);
Analytics and Tracking Integration
class AnalyticsQRWrapper {
static enhanceWithAnalytics(qrInstance, analyticsConfig) {
const enhancedMetadata = {
...qrInstance.getMetadata(),
analytics: {
trackingId: analyticsConfig.trackingId,
platform: analyticsConfig.platform,
goals: analyticsConfig.goals,
customDimensions: analyticsConfig.customDimensions,
autoTrack: analyticsConfig.autoTrack,
enableHeatmap: analyticsConfig.enableHeatmap,
retentionPeriod: analyticsConfig.retentionPeriod
},
privacy: {
gdprCompliant: true,
anonymized: analyticsConfig.anonymized,
consentRequired: analyticsConfig.consentRequired
}
};
qrInstance.setMetadata(enhancedMetadata);
return qrInstance;
}
static createAnalyticsReport(qrInstance) {
const metadata = qrInstance.getMetadata();
const settings = qrInstance.getSettings();
return {
qrInfo: {
id: qrInstance.getId(),
name: qrInstance.getName(),
description: qrInstance.getDescription()
},
configuration: settings,
metadata: metadata,
analyticsReadiness: this.validateAnalyticsSetup(metadata),
reportGeneratedAt: new Date().toISOString()
};
}
static validateAnalyticsSetup(metadata) {
const analytics = metadata?.analytics;
return {
hasTrackingId: !!analytics?.trackingId,
hasGoals: !!(analytics?.goals && analytics.goals.length > 0),
gdprCompliant: metadata?.privacy?.gdprCompliant === true,
autoTrackEnabled: analytics?.autoTrack === true
};
}
}
// Usage
const productQR = QRCodeJs.useTemplate('product')
.useId('product-smartphone-x1')
.useName('Smartphone X1 Product Page')
.useMetadata({
productId: 'smartphone-x1',
category: 'mobile',
price: 699.99
})
.options({
data: 'https://store.company.com/smartphone-x1'
});
const enhancedQR = AnalyticsQRWrapper.enhanceWithAnalytics(productQR, {
trackingId: 'GA-123456789',
platform: 'google-analytics',
goals: ['purchase', 'add-to-cart', 'view-specifications'],
customDimensions: {
productCategory: 'mobile',
priceRange: '600-800',
season: 'q1-2024'
},
autoTrack: true,
enableHeatmap: true,
retentionPeriod: '2-years',
anonymized: true,
consentRequired: false
});
const analyticsReport = AnalyticsQRWrapper.createAnalyticsReport(enhancedQR);
console.log('QR Analytics Report:', analyticsReport);
Metadata Best Practices
1. Consistent Schema Design
// Define a standardized metadata schema
const MetadataSchema = {
// Core identification
id: 'string (required)',
name: 'string (required)',
description: 'string (required)',
// Lifecycle tracking
createdAt: 'ISO 8601 timestamp',
updatedAt: 'ISO 8601 timestamp',
createdBy: 'string (user identifier)',
lastModifiedBy: 'string (user identifier)',
version: 'string (semantic versioning)',
// Business context
businessUnit: 'string',
department: 'string',
project: 'string',
campaign: 'string',
// Technical details
environment: 'development | staging | production',
region: 'string',
locale: 'string (ISO 639-1)',
// Analytics and tracking
analytics: {
enabled: 'boolean',
platform: 'string',
goals: 'string[]',
customDimensions: 'Record<string, any>'
},
// Compliance and governance
dataRetention: 'string (duration)',
privacyLevel: 'public | internal | confidential | restricted',
complianceFlags: 'string[]'
};
2. Validation and Type Safety
class MetadataValidator {
static validateRequiredFields(metadata) {
const required = ['id', 'name', 'description'];
const missing = required.filter(field => !metadata[field]);
if (missing.length > 0) {
throw new Error(`Missing required metadata fields: ${missing.join(', ')}`);
}
}
static sanitizeMetadata(metadata) {
return {
...metadata,
// Ensure timestamps are ISO strings
createdAt: metadata.createdAt || new Date().toISOString(),
updatedAt: new Date().toISOString(),
// Sanitize strings
name: metadata.name?.trim(),
description: metadata.description?.trim(),
// Ensure arrays are arrays
tags: Array.isArray(metadata.tags) ? metadata.tags : [],
// Validate email format for creator fields
createdBy: this.validateEmail(metadata.createdBy)
};
}
static validateEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return email && emailRegex.test(email) ? email : null;
}
}
// Usage with validation
function createValidatedQR(data, metadata) {
try {
MetadataValidator.validateRequiredFields(metadata);
const sanitizedMetadata = MetadataValidator.sanitizeMetadata(metadata);
return QRCodeJs.useTemplate('validated')
.useId(sanitizedMetadata.id)
.useName(sanitizedMetadata.name)
.useDescription(sanitizedMetadata.description)
.useMetadata(sanitizedMetadata)
.options({ data });
} catch (error) {
console.error('QR creation failed:', error.message);
throw error;
}
}
3. Metadata Versioning and Migration
class MetadataVersionManager {
static CURRENT_VERSION = '2.1.0';
static migrateMetadata(metadata) {
const version = metadata.schemaVersion || '1.0.0';
let migrated = { ...metadata };
if (this.isVersionLess(version, '2.0.0')) {
migrated = this.migrateTo2_0_0(migrated);
}
if (this.isVersionLess(version, '2.1.0')) {
migrated = this.migrateTo2_1_0(migrated);
}
migrated.schemaVersion = this.CURRENT_VERSION;
migrated.lastMigration = new Date().toISOString();
return migrated;
}
static migrateTo2_0_0(metadata) {
return {
...metadata,
// Migrate old tracking field to new analytics structure
analytics: {
enabled: metadata.tracking?.enabled || false,
platform: metadata.tracking?.platform || 'unknown',
goals: metadata.tracking?.events || []
},
// Remove deprecated fields
tracking: undefined
};
}
static migrateTo2_1_0(metadata) {
return {
...metadata,
// Add new compliance fields with defaults
compliance: {
dataRetention: metadata.compliance?.dataRetention || '1-year',
privacyLevel: metadata.compliance?.privacyLevel || 'internal'
}
};
}
static isVersionLess(version1, version2) {
const v1Parts = version1.split('.').map(Number);
const v2Parts = version2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const v1Part = v1Parts[i] || 0;
const v2Part = v2Parts[i] || 0;
if (v1Part < v2Part) return true;
if (v1Part > v2Part) return false;
}
return false;
}
}
Integration Examples
Database Integration
class QRDatabaseManager {
static async saveQRMetadata(qrInstance) {
const metadata = {
id: qrInstance.getId(),
name: qrInstance.getName(),
description: qrInstance.getDescription(),
customMetadata: qrInstance.getMetadata(),
settings: qrInstance.getSettings(),
createdAt: new Date(),
updatedAt: new Date()
};
// Save to database (pseudo-code)
return await database.qrCodes.create(metadata);
}
static async loadQRMetadata(qrId) {
const record = await database.qrCodes.findById(qrId);
if (!record) return null;
// Recreate QR instance with stored metadata
const qrInstance = new QRCodeJs(record.settings.options || { data: record.data });
qrInstance
.setId(record.id)
.setName(record.name)
.setDescription(record.description)
.setMetadata(record.customMetadata);
return qrInstance;
}
}
This comprehensive metadata management system enables enterprise-level QR code organization, tracking, and governance while maintaining flexibility for various use cases and integration requirements.
License and Support
QRCode.js by QR-Platform is free for personal projects, open-source projects, or general non-commercial use. For commercial use, a license is required.
See the full license at LICENSE.md for more information. For commercial licenses, including full source code and support, contact [email protected].
Using QRCode.js in Commercial Applications
This page explains how you can use the QRCode.js library in your commercial projects, based on our official license terms. Our goal is to make it clear what's possible and what's required when you're building applications intended to generate revenue or that are not open-source.
Basic Examples
Basic examples to get started with QRCode.js