Skip to content
UseQR
ESC

↑↓ MOVE↵ OPEN48 PLACES

Developers & agents

Generate a QR code in Svelte

In Svelte 5, derive the keyless API URL from state — const src = $derived(`https://useqr.app/api/v1/qr?data=${encodeURIComponent(text)}&size=512`) — and bind it to an img. For payloads that must stay on the device, render locally with the qrcode npm library inside $effect. No component library needed.

View as MarkdownPaste this page into any AI assistant — it is plain, portable Markdown.

Runes make this almost nothing

In Svelte 5, a QR display is one $state and one $derived:

<script>
  let text = $state("https://example.com");
  const src = $derived(
    `https://useqr.app/api/v1/qr?data=${encodeURIComponent(text)}&size=512`
  );
</script>

<input bind:value={text} />
<img {src} width="256" height="256" alt={`QR code linking to ${text}`} />

Edit the input and the code updates. No fetch code, no lifecycle, no dependency — the keyless API draws the image and the browser caches each distinct payload for a year (immutable), so toggling between values never refetches. In Svelte 4, the same thing is $: src = ... with a reactive statement.

encodeURIComponent is load-bearing: an unencoded & in the payload starts a new query parameter and truncates your data silently.

On-device with the qrcode library

Credentials do not belong in a URL to any server, ours included — the full argument is in client-side vs server-side generation. For WiFi passwords, vCards and payment strings, render locally with the qrcode package (npm install qrcode):

<script>
  import QRCode from "qrcode";

  let { value } = $props();
  let dataUrl = $state("");
  $effect(() => {
    QRCode.toDataURL(value, { margin: 4, width: 512 }).then((u) => (dataUrl = u));
  });
</script>

<img src={dataUrl} width="256" alt="QR code" />

$effect re-runs when value changes. margin: 4 is the required 4-module quiet zone — skipping it is the top cause of codes that fail to scan. The library's other output modes (SVG string, canvas, file) are covered on the JavaScript page.

SVG for crisp output

const svg = await QRCode.toString(value, { type: "svg", margin: 4 });

Render with {@html svg} — safe here because you generated the markup yourself; never use {@html} with strings you did not produce.

SvelteKit note

The <img> pattern server-renders as-is, since it is plain markup. The qrcode library runs in Node too, so you can generate in a +page.server.js load function and ship the data URL in page data — useful when the code must appear before hydration. For build-time or edge-cached codes at scale, the patterns on the Next.js page translate directly to SvelteKit endpoints.

Verify what you styled

If you pass color= or bg= to the API, add one call that proves the result still decodes:

const report = await fetch(
  `https://useqr.app/api/v1/verify?data=${encodeURIComponent(text)}&color=6366f1`
).then((r) => r.json());
// report.scannable, report.issues

That is the decode-verify loop in one GET — cheap insurance before a code goes to print or production.

FAQ

What is the simplest QR code in Svelte?

A $derived string that builds the keyless API URL from your state, bound to an img element. Two lines of script, no packages.

Does this work in Svelte 4?

Yes — replace $state with a plain variable and $derived with a reactive $: statement. The img pattern and the qrcode library are identical.

When should I render the QR code locally?

When the payload is a credential or personal data, such as WiFi passwords or contact cards. Local generation with the qrcode package keeps the data on the device.

Can SvelteKit generate QR codes on the server?

Yes. The qrcode library runs in Node, so a load function can produce a data URL, or an endpoint can stream PNG or SVG responses.

Try it — free, no signup