# 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.

Source: https://useqr.app/docs/developers/generate-a-qr-code-in-svelte · Last reviewed 2026-08-21 · UseQR is free forever, MIT licensed, no signup.

---

## Runes make this almost nothing

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

```svelte
<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](/docs/developers/free-qr-code-api-no-key) 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](/docs/security/client-side-vs-server-side-qr-generation).
For WiFi passwords, vCards and payment strings, render locally with the `qrcode` package
(`npm install qrcode`):

```svelte
<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](/glossary/quiet-zone) — skipping it is the top cause of codes that
[fail to scan](/docs/troubleshooting/qr-code-not-scanning-checklist). The library's other
output modes (SVG string, canvas, file) are covered on the
[JavaScript page](/docs/developers/generate-a-qr-code-in-javascript).

## SVG for crisp output

```js
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](/docs/developers/generate-a-qr-code-in-nextjs) 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:

```js
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](/docs/developers/why-verify-that-your-qr-code-decodes) 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

- https://useqr.app/url
- https://useqr.app/json
- https://useqr.app/validate
