
QR 코드 하나 예쁘게 뽑으려다 만들어버린 생성기, QR Studio
링크·와이파이·연락처까지 여덟 가지 QR을 색·점 모양·로고까지 입혀서 PNG/SVG로 뽑아요. 입력값은 서버로 안 가고 전부 브라우저에서 처리됩니다.
자랑 포인트
- 입력한 주소·비밀번호·연락처가 서버로 전송되지 않고 전부 브라우저 안에서 처리되는 100% 클라이언트 사이드 QR 생성기
- 가운데 로고를 넣으면 오류정정 레벨을 자동으로 올리고 로고 크기에 상한을 둬서 스캔이 깨지지 않아요
- 렌더된 QR을 jsQR로 다시 디코드해 입력값과 정확히 일치하는지 검증 — 와이파이 특수문자 이스케이프까지 확인
QR 코드 생성기야 널리고 널렸죠. 저도 압니다. 그런데 막상 하나 뽑으려고 들어가 보면 꼭 하나씩 걸려요. 광고가 덕지덕지 붙어 있거나, 색 하나 바꾸려면 로그인을 하라거나, 다 만들고 나니 구석에 워터마크가 박혀 나오거나. 결정적인 계기는 카페 와이파이였어요. 손님용으로 비밀번호를 QR로 만들어 붙여두려는데, 모르는 사이트에 와이파이 비번을 그대로 쳐 넣는 게 영 찜찜하더라고요. 생각해 보면 QR 만드는 건 그냥 문자열 인코딩이라 서버로 뭘 보낼 이유가 전혀 없는 작업이거든요. 그래서 "그럼 내가 만들지 뭐" 하고 주말에 손을 댔습니다.

이름은 QR Studio. 주소든 텍스트든 입력하면 그 자리에서 QR이 뜨고, 색이랑 점 모양을 취향대로 바꾼 다음 PNG나 SVG로 내려받는 게 전부예요. 처음엔 링크만 만들 생각이었는데, 하다 보니 "이것도 되면 좋잖아" 하면서 타입이 자꾸 늘었어요. 결국 링크, 텍스트, 와이파이, 연락처(vCard), 이메일, 전화, 문자, 위치까지 여덟 개가 됐네요. 색 프리셋 여섯 개에 전경·배경색 직접 지정, 점 모양 여섯 종류, 모서리 세 종류, 오류정정 레벨까지 만지작거릴 수 있어서 밋밋한 흑백 말고 꽤 그럴듯한 QR이 나옵니다.
손이 제일 많이 간 건 의외로 와이파이였어요. 와이파이 QR은 WIFI:T:WPA;S:이름;P:비번;; 같은 정해진 포맷이 있는데, 여기서 SSID나 비밀번호에 세미콜론이나 따옴표, 콤마가 들어가면 그냥 깨져버립니다. 백슬래시로 하나하나 이스케이프를 해줘야 하는데, 이걸 안 하면 "QR 스캔은 되는데 비번이 틀렸다고 나와요" 같은 상황이 생기는 거죠. 저도 여기서 두 번 당했어요. 그래서 특수문자 이스케이프를 타입별로 전부 테스트로 묶어뒀습니다.

제일 애착이 가는 건 가운데 로고 넣는 기능이에요. 이미지 하나 올리면 QR 정중앙에 박히는데, 그냥 덮어버리면 그 자리 데이터가 가려져서 스캔이 안 돼요. 그래서 로고를 넣는 순간 오류정정 레벨을 자동으로 올리고, 로고가 너무 커지지 않게 크기에 상한도 뒀습니다. 복원력을 미리 확보해 두니까 가운데가 가려져도 스캔이 멀쩡하더라고요.

그래도 좀 불안했어요. 이게 진짜 스캔 되는 거 맞나, 눈으로 봐선 모르잖아요. 그래서 렌더된 QR을 jsQR로 다시 디코드해서 내가 넣은 값이랑 정확히 같은지 자동으로 맞춰보게 했어요. 와이파이 특수문자가 섞인 값이든, 로고를 최대로 키운 상태든, 디코드한 결과가 입력값과 똑같이 나오는 걸 확인하고 나서야 마음이 놓이더라고요. URL은 https:// 를 빼먹어도 알아서 붙여주고요.

기술 스택은 가볍게 갔어요. React 19에 Vite, TypeScript, Tailwind CSS v4. QR 렌더링이랑 로고·SVG 지원은 qr-code-styling을 썼고, 방금 말한 디코드 검증은 jsQR을 붙였습니다. 서버를 안 둔 건 무슨 대단한 철학이 있어서가 아니라 그냥 QR 인코딩에 서버가 필요 없어서예요. 입력한 값은 어디로도 전송되지 않고 전부 이 브라우저 안에서 처리되고, 색이나 설정 정도만 localStorage에 남아요(로고는 저장 안 합니다).
완성하고 나서 실제로 집 와이파이랑 명함 연락처를 QR로 뽑아서 써봤는데, 폰 갖다 대니까 바로 연결되고 연락처도 쏙 들어가더라고요. 별거 아닌 토이앱이지만 직접 쓰는 재미가 쏠쏠합니다. QR 하나 급하게 필요한 분들 가볍게 써보세요. 광고도, 워터마크도 없어요.