A Next.js app that renders QR codes as you type and lets you restyle every part — dots, corners, colors, an embedded logo — then export to PNG, JPEG, SVG, or WEBP.

In today’s digital age, QR codes have become a powerful tool for sharing information quickly and seamlessly. Whether it’s a website link, event details, or product information, QR codes make data sharing effortless. Inspired by this convenience, I created a QR Code Generator app, hosted at qr.handiani.my.id, that allows users to create and customize QR codes easily.
In this blog post, I’ll walk you through how I developed this project using Next.js and other modern tools. If you’re interested in building your own QR code generator or learning about my tech stack, read on!
Here’s the stack I used for this project:
The project is divided into two main components:
1. QrCode Component This component handles the QR code rendering and downloading functionality. Below is a brief overview of how it works:
import { useEffect, useRef, useState } from "react";
import QRCodeStyling from "qr-code-styling";
const QrCode = ({ data, options }) => {
const qrCodeRef = useRef(null);
const qrCode = useRef(null);
const [extension, setExtension] = useState("png");
const [name, setName] = useState("qr");
const onDownloadClick = () => {
qrCode.current?.download({ name, extension });
};
useEffect(() => {
if (!qrCode.current) {
qrCode.current = new QRCodeStyling({ data, ...options });
}
qrCode.current.update({ data, ...options });
if (qrCodeRef.current) {
qrCode.current.append(qrCodeRef.current);
}
}, [data, options]);
return (
<div>
<div ref={qrCodeRef}></div>
<button onClick={onDownloadClick}>Download QR Code</button>
</div>
);
};
export default QrCode;2. Home Component The home page integrates the QrCode component and provides user-friendly controls for customization. Features include:
Users can adjust the following settings:
Here’s an example of the controls:
<Input
label="Text or URL"
value={data}
onChange={(e) => setData(e.target.value)}
placeholder="Input your text"
/>
<RadioGroup
label="Shape"
value={options.shape}
onChange={(shape) => setOptions({ ...options, shape })}
>
<Radio value="circle">Circle</Radio>
<Radio value="square">Square</Radio>
</RadioGroup>
<HexAlphaColorPicker
color={options.backgroundOptions?.color}
onChange={(color) => setOptions({ ...options, backgroundOptions: { color } })}
/>Building this QR Code Generator was a rewarding experience that combined creativity and technical skills. The app offers users a seamless way to create and customize QR codes for personal or professional use.
Try it out for yourself at gaweqr.my.id, and let me know your thoughts! Happy coding!

A walkthrough of making a portfolio fully bilingual (EN/ID) — subpath routing with next-intl, per-field content localization in Payload CMS, and the 404 and SEO gotchas I hit along the way.

Building a type-safe registration form in Next.js with React Hook Form and a Zod schema — setup, validation, and wiring the component into a page, step by step.

A reusable AnimatedSection component that animates content in and out of the viewport based on scroll direction and position, built with Framer Motion and React hooks.