Generate a QR code for a link, a Wi-Fi network, a contact card or a prefilled message, then download it as PNG or SVG. The content is encoded in the pattern itself, with no redirect service in between, so the code keeps working for as long as the destination does. Wi-Fi codes cover WPA, WPA2, WPA3, WEP and open networks, and an email code can carry a prefilled subject and body.
The content as typed. A phone opens a URL in the browser and shows anything else as text it offers to copy or search.
A string such as WIFI:T:WPA;S:name;P:password;; that the iOS and Android cameras both read as an offer to join the network.
A vCard 3.0 block. Scanning it opens a prefilled New Contact screen, so the person does not retype the phone number.
SMSTO: and mailto: links with the message prefilled. The phone opens a draft, and the person still has to press send.
A QR code carries redundant data so it still scans when part of it is dirty, creased or covered. L can recover about 7% of the code and H about 30%. However, higher correction adds modules for the same content, so the code gets denser and needs to be printed larger.
Use H if you put a logo in the middle. Keep the logo under about a fifth of the width and centered, and never cover the three corner squares, which the scanner uses to find and orient the code. This page does not add logos, so place it in your design tool. Then test with a real phone, at the printed size, in poor lighting.
About 2 cm square is the practical minimum for a short URL in print, and that assumes a phone held close. Scale up for a poster.
The white margin around the code is part of the spec. A background color that runs right up to the edge breaks detection.
Print dark modules on a light background. Many scanners fail on light modules over a dark ground.
A 500-character URL produces a dense grid that a phone camera struggles to resolve. Shorten the link to under about 300 characters.
// npm i qrcode
const QRCode = require("qrcode");
// A PNG file
await QRCode.toFile("qr.png", "https://example.com", {
errorCorrectionLevel: "M",
width: 512,
margin: 2, // the quiet zone, in modules
});
// An SVG string
const svg = await QRCode.toString("https://example.com", { type: "svg" });
// A data URI for an img tag
const dataUri = await QRCode.toDataURL("https://example.com");
// Wi-Fi payload format
const wifi = "WIFI:T:WPA;S:Office-5G;P:hunter2;;"; <?php
// composer require endroid/qr-code
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\ErrorCorrectionLevel;
$qr = QrCode::create('https://example.com')
->setSize(512)
->setMargin(20)
->setErrorCorrectionLevel(ErrorCorrectionLevel::High);
$result = (new PngWriter())->write($qr);
$result->saveToFile(__DIR__ . '/qr.png');
// Or straight to the browser
header('Content-Type: ' . $result->getMimeType());
echo $result->getString(); # pip install qrcode[pil]
import qrcode
from qrcode.constants import ERROR_CORRECT_H
qr = qrcode.QRCode(
version=None, # let it pick the smallest that fits
error_correction=ERROR_CORRECT_H,
box_size=10,
border=4, # quiet zone, 4 modules is the spec minimum
)
qr.add_data("https://example.com")
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save("qr.png")
# vCard payload
vcard = "BEGIN:VCARD\nVERSION:3.0\nFN:Alex Morgan\nTEL:+15550142\nEND:VCARD" A QR code is a fixed grid of modules with three large corner squares for orientation, timing patterns for the grid, and Reed-Solomon error correction (redundant data that rebuilds damaged parts) spread across the rest. That correction is why a scuffed sticker still scans and why a logo can cover part of the code. Version 1 is 21x21 modules and holds about 25 alphanumeric characters. Version 40 is 177x177 and holds thousands, but a phone camera at arm's length cannot resolve it.
Codes made here have no tracking and no redirect, so there are no scan analytics either. To count scans of a poster, point the code at a URL with a campaign parameter and read it from your own analytics.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
No. The data is encoded in the pattern itself, so the code points straight at your URL with no redirect service in between. It works for as long as the destination does.
Both. Download PNG gives 256, 512 or 1024 pixels, set by the Size dropdown. Download SVG stays sharp at any size, so use it for posters and print.
It controls how much of the code can be damaged or covered and still scan. L tolerates about 7% and H about 30%. Use H if you plan to put a logo in the middle, and L when a long URL has to fit in a small square.
Up to about 4,000 alphanumeric characters in theory. However, density rises with length, and phone cameras struggle well before the limit. Keep URLs under about 300 characters and shorten anything longer.
Yes. Pick Wi-Fi network or Contact card as the type and fill in the fields. The tool assembles the payload string and shows it under Encoded payload. A Wi-Fi code lets guests join without anyone reading the password out loud.
Pick WPA / WPA2 / WPA3 for almost any router sold in the last fifteen years. The Wi-Fi QR format uses one value, WPA, for all three, and phones negotiate the real protocol when they connect. Choose WEP only for old hardware that still runs it, and Open network for a guest network with no password, which drops the password field from the payload. Tick Hidden network if the router does not broadcast the SSID, which adds the H:true flag so phones connect without a scan.
Yes. Choose Email as the type and fill in To, Subject and Body. The tool builds a mailto: link with the subject and body percent-encoded, so spaces and line breaks survive. Scanning it opens the phone's mail app with a draft ready, and the person still has to press send. Keep the body short, because every character makes the code denser.
A vCard 3.0 block with the Full name, Company, Phone, Email and Website fields you fill in. Empty fields are left out. The tool splits the full name on the last space, so the final word becomes the surname. The phone number is stored as a mobile number, and scanning the code opens a prefilled New Contact screen on iOS and Android.
If you are building the URL first, the URL encoder handles the parameters and the URL parser checks the result. For a short, clean path to encode, use the slug generator.