Skip to content
UseQR
ESC

↑↓ MOVE↵ OPEN48 PLACES

Developers & agents

Generate a QR code in Vue

In Vue 3, compute the keyless API URL from your reactive state and bind it to an img — computed(() => `https://useqr.app/api/v1/qr?data=${encodeURIComponent(text.value)}`) — or render locally with the qrcode npm library when the payload must not leave the browser. Verify styled codes with GET /api/v1/verify.

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

A computed URL is the whole component

Vue's reactivity does the work. Derive the API URL from state with computed, bind it to an <img>, and the code re-renders whenever the payload changes:

<script setup>
import { computed, ref } from "vue";

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

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

No package, no key. The keyless API marks responses immutable and cacheable for a year, so flipping back to a previously seen payload never refetches. encodeURIComponent is not optional — a payload containing & will be silently truncated without it.

Client-side with the qrcode library

A WiFi password or contact card should never be sent to a server just to become an image — the reasoning is laid out in client-side vs server-side generation. Render locally with the same qrcode package used on the JavaScript page:

<script setup>
import QRCode from "qrcode";
import { ref, watchEffect } from "vue";

const props = defineProps({ value: String });
const dataUrl = ref("");
watchEffect(async () => {
  dataUrl.value = await QRCode.toDataURL(props.value, { margin: 4, width: 512 });
});
</script>

<template>
  <img :src="dataUrl" width="256" alt="QR code" />
</template>

watchEffect tracks props.value automatically, so the component regenerates on any change. margin: 4 is the 4-module quiet zone; several libraries default lower, and a thin margin is the most common reason a generated code will not scan.

SVG instead of a data URL

For print or crisp scaling, ask qrcode for SVG markup and inject it:

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

Bind with v-html on a wrapper div. Only do this with SVG you generated yourself — v-html with untrusted content is an XSS vector.

Dark mode

A transparent-background code on a dark theme becomes a light-on-dark code, which many scanners refuse to read. Give the code an explicit light plate regardless of theme:

.qr { background: #fff; padding: 12px; border-radius: 12px; }

Verify styled output

Passing brand colours through the API (color=, bg=)? Prove the result decodes before it ships:

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

The endpoint renders, rasterises and decodes with a real decoder — the decode-verify loop as one GET.

FAQ

What is the simplest way to show a QR code in Vue?

A computed property that builds the keyless API URL from your state, bound to an img element. Reactivity handles updates; the browser cache handles repeat renders.

Do I need a Vue-specific QR component library?

No. The plain qrcode npm package inside a small script-setup component covers local generation, and an img against the API covers everything else.

When should I generate the code in the browser instead of via the API?

When the payload is sensitive — WiFi credentials, contact details, payment strings. Those should be encoded locally so the data never leaves the device.

Why is my Vue-generated QR code not scanning?

Check the quiet zone first: set margin to 4 modules. Then check contrast — a themed or transparent background on a dark page is the next most common cause.

Try it — free, no signup