DEV Community

Mubeen Khan
Mubeen Khan

Posted on

WiFi QR codes are just one line of text (here is the format)

WiFi QR codes are just one line of text (here is the format)

You have seen them on cafe tables and Airbnb welcome books: point your phone camera at the square, and you join the WiFi without typing a 24-character password. There is no magic in it. A WiFi QR code is a plain text string in a tiny, well-supported format, and once you know the format you can generate one in about ten lines of JavaScript.

The format

The payload looks like this:

WIFI:T:WPA;S:CoffeeShop_Guest;P:flatwhite42;; 
Enter fullscreen mode Exit fullscreen mode

Four fields, each terminated by a semicolon, and the whole thing ends with a double semicolon:

  • T: the security type. WPA covers WPA/WPA2 (nearly every modern router), WEP is for old equipment, and nopass means an open network. With nopass you simply omit the P: field.
  • S: the network name (SSID).
  • P: the password. Leave it out for open networks.
  • H:true is optional and marks a hidden network whose SSID is not broadcast.

So an open guest network is just:

WIFI:T:nopass;S:Lobby_WiFi;;
Enter fullscreen mode Exit fullscreen mode

The part everyone forgets: escaping

SSIDs and passwords can legally contain the exact characters the format uses as delimiters. If your network is called Cafe; Bar or your password contains a colon, a naive string concatenation produces a payload phones misread. The rule: escape backslash, semicolon, comma, and colon with a backslash.

Here is a small builder that gets it right:

function escapeWifiField(s) {
  return String(s)
    .replace(/\\/g, '\\\\')
    .replace(/;/g, '\\;')
    .replace(/,/g, '\\,')
    .replace(/:/g, '\\:');
}

function buildWifiPayload({ ssid, password, encryption = 'WPA', hidden = false }) {
  const enc = encryption === 'nopass' ? 'nopass' : encryption === 'WEP' ? 'WEP' : 'WPA';
  let p = 'WIFI:T:' + enc + ';S:' + escapeWifiField(ssid) + ';';
  if (enc !== 'nopass') p += 'P:' + escapeWifiField(password) + ';';
  if (hidden) p += 'H:true;';
  return p + ';';
}

buildWifiPayload({ ssid: 'CoffeeShop_Guest', password: 'flatwhite42' });
// WIFI:T:WPA;S:CoffeeShop_Guest;P:flatwhite42;;
Enter fullscreen mode Exit fullscreen mode

From there, feed the string to any QR encoder. In the browser, the qrcode npm package renders it to a canvas or data URL in one call; nothing needs a server.

Two practical notes

First, a printed WiFi QR is a spare key: anyone who scans it reads your password in plain text on their device. For visitors, the smarter move is a separate guest network on your router, and share that one.

Second, error correction matters for print. The default Medium level survives about 15% damage, which is fine on a table tent. For a sign by the door that will get scuffed, bump it to High.

I built a free generator that handles the escaping, the hidden-network flag, and the print layout for you, including a ready-to-hang guest sign: https://www.theutilityhub.online/tools/wifi-qr-generator

It runs entirely in the browser, so your network name and password never leave your device. Useful the next time someone asks "what is the WiFi password" and you would rather just point at the wall.

Top comments (0)