# Generate a QR code in Next.js

> Point next/image at the keyless API (add useqr.app to images.remotePatterns), or proxy it through a route handler so codes are cached at your own edge. For build-time codes, fetch during static generation; for OG images, compose the PNG into ImageResponse. No key or SDK required.

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

---

## next/image against the API

The [keyless API](/docs/developers/free-qr-code-api-no-key) is just an image URL, so
`next/image` can optimise it like any remote image. Allow the host first:

```js
// next.config.js
module.exports = {
  images: {
    remotePatterns: [{ protocol: "https", hostname: "useqr.app" }],
  },
};
```

```jsx
import Image from "next/image";

<Image
  src={`https://useqr.app/api/v1/qr?data=${encodeURIComponent(url)}&size=512`}
  width={256}
  height={256}
  alt={`QR code linking to ${url}`}
/>
```

Honestly, `next/image` buys little here (the API already serves an optimised PNG with
`Cache-Control: immutable`), so a plain `<img>` (see the
[React page](/docs/developers/generate-a-qr-code-in-react)) is equally good and skips the
config.

## Route-handler proxy

To serve codes from your own domain (same-origin CSPs, your own CDN keys, no third-party
hostname in the markup) proxy through a route handler:

```ts
// app/qr/route.ts
export async function GET(request: Request) {
  const data = new URL(request.url).searchParams.get("data") ?? "";
  const upstream = await fetch(
    `https://useqr.app/api/v1/qr?data=${encodeURIComponent(data)}&size=512`,
    { cache: "force-cache" }
  );
  return new Response(upstream.body, {
    headers: {
      "Content-Type": "image/png",
      "Cache-Control": "public, max-age=31536000, immutable",
    },
  });
}
```

`<img src="/qr?data=...">` now works anywhere in your app. `cache: "force-cache"` lets
Next's data cache absorb repeat upstream fetches, and the `immutable` response header lets
your CDN edge hold the bytes, after the first request per payload, useqr.app is never
contacted again. Broader caching patterns are in
[caching and CDN strategy for QR images](/docs/developers/caching-and-cdn-strategy-for-qr-images).

## Build-time generation

For a static site with many codes (one per product page, say) fetch during static
generation so zero requests happen at runtime:

```ts
// in a server component with generateStaticParams
const res = await fetch(
  `https://useqr.app/api/v1/qr?data=${encodeURIComponent(url)}&format=base64`
);
const b64 = await res.text();
// <img src={`data:image/png;base64,${b64}`} ... />
```

`format=base64` returns the PNG as base64 text, which drops straight into a data URI in the
prerendered HTML. For thousands of pages, batch it: `POST /api/v1/qr/batch` takes up to
100 items per call. Fully offline builds can use the `qrcode` npm package instead: see the
[Node page](/docs/developers/generate-a-qr-code-in-node).

## QR codes in OG images

`ImageResponse` (from `next/og`) composes JSX to a PNG for social cards. It renders plain
`<img>` elements, so a QR code is just another element in the card:

```tsx
new ImageResponse(
  <div style={{ display: "flex", width: "100%", height: "100%" }}>
    <img src={`https://useqr.app/api/v1/qr?data=${encodeURIComponent(url)}`}
         width={220} height={220} />
  </div>,
  { width: 1200, height: 630 }
);
```

Keep the code at least 200 px in a 1200 px card and leave the
[quiet zone](/glossary/quiet-zone) clear of background art, OG images get scanned off
other people's screens more often than you would think.

## Verify before deploy

A build step that generates codes should decode them too: `GET /api/v1/verify` with the
same parameters returns `scannable` and a list of issues. Wire it into CI as described in
[why verify that your QR code decodes](/docs/developers/why-verify-that-your-qr-code-decodes).

## FAQ

### How do I show a QR code in a Next.js app?
Point an img or next/image at the keyless API with the payload URL-encoded. For next/image, add useqr.app to images.remotePatterns first.

### How do I serve QR codes from my own domain?
A small route handler that fetches the API and streams the PNG back with an immutable cache header. Your CDN then holds each code after the first request.

### Can I generate QR codes at build time?
Yes: fetch with format=base64 during static generation and inline the result as a data URI, or use the qrcode npm package for a fully offline build.

### Can I put a QR code in an Open Graph image?
Yes. ImageResponse renders img elements, so include the API URL as an element in the card. Keep it at least 200 px wide with a clear margin.

## Try it

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