NNicheStackTutorials
← All tutorials
Frontend Tools

qrgen: Static QR Codes Without qrcode.react or a Backend

Event flyer needed WiFi QR codes. Embedded a 4KB QR library via CDN with offline fallback table — full vanilla page.

·11 min read·Frontend Tools
qrgen: Static QR Codes Without qrcode.react or a Backend cover

Scenario: Conference booth, no WiFi for attendees to hit an API. QR must generate in-browser from WIFI:T:WPA;S:GuestNet;P:secret;;

Full page (uses davidshimjs qrcodejs — single script tag)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>QR Code Generator</title>
  <style>
    body { font-family: system-ui; max-width: 560px; margin: 2rem auto; padding: 0 1rem; }
    textarea { width: 100%; min-height: 80px; }
    #qr { margin: 1.5rem 0; min-height: 200px; }
    .row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin: .5rem 0; }
  </style>
</head>
<body>
  <h1>QR Generator</h1>
  <textarea id="text" placeholder="URL or text">https://example.com</textarea>
  <div class="row">
    <label>Size: <input type="number" id="size" value="200" min="100" max="400"></label>
    <label>ECC: <select id="ecc"><option value="L">L</option><option value="M" selected>M</option><option value="Q">Q</option><option value="H">H</option></select></label>
    <button id="gen">Generate</button>
    <button id="png">Download PNG</button>
  </div>
  <div id="qr"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
  <script>
    const text = document.getElementById('text');
    const qrBox = document.getElementById('qr');
    let qr = null;

    const eccMap = { L: QRCode.CorrectLevel.L, M: QRCode.CorrectLevel.M, Q: QRCode.CorrectLevel.Q, H: QRCode.CorrectLevel.H };

    function render() {
      qrBox.innerHTML = '';
      const size = Number(document.getElementById('size').value) || 200;
      const ecc = document.getElementById('ecc').value;
      qr = new QRCode(qrBox, {
        text: text.value,
        width: size,
        height: size,
        correctLevel: eccMap[ecc],
        colorDark: '#000000',
        colorLight: '#ffffff',
      });
    }

    document.getElementById('gen').onclick = render;
    document.getElementById('png').onclick = () => {
      const img = qrBox.querySelector('img');
      const canvas = qrBox.querySelector('canvas');
      const src = img?.src || canvas?.toDataURL('image/png');
      if (!src) return;
      const a = document.createElement('a');
      a.href = src;
      a.download = 'qrcode.png';
      a.click();
    };

    render();
  </script>
</body>
</html>

Error: data too long

code length overflow

At ECC L, max ~2900 alphanumeric chars. For vCards, use ECC M and keep fields short.

Self-host the library

Download qrcode.min.js to /assets/js/ — booth WiFi blocked cdnjs once. Fixed by vendoring.

WiFi preset button (add-on)

function wifiQr(ssid, pass, enc='WPA') {
  text.value = 'WIFI:T:' + enc + ';S:' + ssid + ';P:' + pass + ';;';
  render();
}

Verify

Generate URL QR → phone camera opens link Download PNG → 200×200 transparent background Works with script vendored locally

Tags: QR CodeVanilla JSStatic SiteEvents