← cd ..
ReactTypeScripti18n사이드프로젝트qrcode

WiFi QR 코드 생성기를 만들었다 — AI로 처음 완성한 사이드 프로젝트

May 5, 20261 min read

손님이 오면 항상 같은 상황이 반복된다.

  1. "WiFi 비밀번호가 뭐예요?" 질문
  2. 공유기 뒤 스티커 확인
  3. 복잡한 비밀번호 받아쓰기
  4. 오타 → 재시도

QR 코드로 찍으면 자동 연결되는 게 있으면 어떨까? 찾아보니 표준 포맷도 있고, qrcode.react 같은 라이브러리도 있었다. 직접 만들어보기로 했다.

이게 AI와 함께 처음으로 완성한 사이드 프로젝트다. 사이트 주소는 wi-fi-qr.xyz.


만든 것들 한눈에

기능내용
WiFi QR 코드 생성SSID, 비밀번호, 암호화 방식 입력 → 즉시 QR 생성
인쇄 기능QR 코드 + 네트워크 이름 카드 형식으로 인쇄
히스토리이전에 생성한 QR 코드 목록 (로컬스토리지)
다국어 지원한국어 / 영어 / 중국어 / 독일어
Hidden SSID숨겨진 네트워크도 지원

기술 스택

분류라이브러리
프레임워크React + Vite + TypeScript
라우팅wouter
폼 관리react-hook-form + zod
QR 생성qrcode.react
SEOreact-helmet-async
아이콘lucide-react
분석@vercel/analytics

Step 1 — QR 코드 포맷 이해

WiFi QR 코드는 특정 문자열 포맷을 따른다.

WIFI:T:WPA;S:네트워크이름;P:비밀번호;H:false;;
  • T: 암호화 방식 (WPA, WEP, nopass)
  • S: SSID (네트워크 이름)
  • P: 비밀번호
  • H: Hidden SSID 여부

iOS 11+, Android 10+ 기기에서 카메라 앱으로 스캔하면 바로 연결 화면이 뜬다. qrcode.react에 이 문자열을 넘기면 QR 코드를 렌더링해준다.

import QRCode from "qrcode.react";

function buildWifiString(config: WifiConfig): string {
  const { ssid, password, encryption, hidden } = config;
  if (encryption === "nopass") return `WIFI:T:nopass;S:${ssid};;`;
  return `WIFI:T:${encryption};S:${ssid};P:${password};H:${hidden};;`;
}

<QRCode value={buildWifiString(config)} size={200} />

Step 2 — 폼 구성: react-hook-form + zod

입력 폼은 react-hook-formzod로 관리했다. 암호화 방식이 nopass이면 비밀번호 필드 자체를 숨기는 방식이다.

// shared/schema.ts
export const insertWifiConfigSchema = z.object({
  ssid: z.string().min(1, "SSID를 입력해주세요"),
  password: z.string().optional(),
  encryption: z.enum(["WPA", "WEP", "nopass"]),
  hidden: z.boolean().default(false),
});

폼 변경이 일어날 때마다 부모로 현재 값을 올려보내 QR 코드가 실시간으로 갱신된다.

// WifiForm.tsx
const handleChange = (data: Partial<InsertWifiConfig>) => {
  const newConfig = { ...form.getValues(), ...data };
  onUpdate(newConfig); // 부모로 올려서 QR 즉시 갱신
};

<form onChange={() => handleChange(form.getValues())}>

비밀번호 필드는 show/hide 토글을 달았다. WiFi 비밀번호는 길고 복잡한 경우가 많아서 입력 확인이 필요하다.

const [showPassword, setShowPassword] = useState(false);

<Input type={showPassword ? "text" : "password"} />
<button onClick={() => setShowPassword(!showPassword)}>
  {showPassword ? <EyeOff /> : <Eye />}
</button>

Step 3 — 다국어 지원 (i18n)

라이브러리 없이 직접 구현했다. i18n.ts에 번역 키-값 객체를 언어별로 관리하고, Context로 전체에 공유하는 방식이다.

// lib/i18n.ts
type Language = "en" | "ko" | "zh" | "de";

const translations: Record<Language, Record<string, string>> = {
  en: { "form.ssid": "Network Name (SSID)", ... },
  ko: { "form.ssid": "네트워크 이름 (SSID)", ... },
  zh: { "form.ssid": "网络名称 (SSID)", ... },
  de: { "form.ssid": "Netzwerkname (SSID)", ... },
};

언어 감지는 브라우저 설정을 먼저 보고, 없으면 영어로 폴백한다. 선택한 언어는 localStorage에 저장해서 다음 방문 때도 유지된다.

// App.tsx
function detectLanguage(): Language {
  const saved = localStorage.getItem("wifi-qr-lang");
  if (valid.includes(saved as Language)) return saved as Language;

  const browserLang = navigator.language.toLowerCase();
  if (browserLang.startsWith("ko")) return "ko";
  if (browserLang.startsWith("zh")) return "zh";
  if (browserLang.startsWith("de")) return "de";
  return "en";
}

Step 4 — 인쇄 기능

인쇄용 카드 컴포넌트(PrintableCard)를 별도로 만들고, window.print()를 호출했다. CSS @media print로 UI 요소를 숨기고 카드만 인쇄되게 했다.

// WifiForm.tsx
const handlePrint = () => {
  window.print();
};

<Button onClick={handlePrint} disabled={!form.watch("ssid")}>
  <Printer className="w-5 h-5 mr-2" />
  {t("form.print")}
</Button>

카드에는 QR 코드와 네트워크 이름이 함께 나온다. 카페나 사무실에서 인쇄해서 붙여두면 손님이 직접 스캔해 연결할 수 있다.


Step 5 — 라우팅과 SEO

wouter로 라우팅을 잡았다. 페이지는 총 4개다.

// App.tsx
<Route path="/" component={Home} />
<Route path="/guide" component={Guide} />
<Route path="/about" component={About} />
<Route path="/privacy" component={Privacy} />

각 페이지에 react-helmet-async로 title과 description, canonical URL을 달았다.

<Helmet>
  <title>Free WiFi QR Code Generator | WiFi QR Print</title>
  <meta name="description" content="Generate a printable WiFi QR code..." />
  <link rel="canonical" href="https://wi-fi-qr.xyz" />
</Helmet>

초기 사이트 구조

배포 당시 홈 페이지 구성은 이랬다.

홈 (/)
  ├── 헤더 + 언어 선택기
  ├── WiFi QR 폼 (좌) + QR 미리보기 (우)
  ├── How-to 섹션 (4단계)
  ├── FAQ (5개)
  └── 푸터 → Privacy 링크

도구로서는 충분했다. 폼 채우면 QR 나오고, 인쇄도 되고, 4개 언어로 쓸 수 있었다. 그래서 구글 애드센스도 달아보기로 했다.


정리 — 핵심 흐름 한눈에

WiFi 비밀번호 공유 불편
  ↓
WIFI:T:WPA;S:...;P:...;; 포맷으로 QR 생성
  ↓
react-hook-form + zod 폼 → 실시간 QR 갱신
  ↓
window.print() 인쇄 카드
  ↓
4개 언어 i18n (브라우저 자동 감지)
  ↓
Vercel 배포 → wi-fi-qr.xyz

사이트는 잘 돌아갔다. 그런데 애드센스 신청 후 거절 메일이 왔다. 다음 편에서 그 이야기를 쓰겠다.


WiFi QR 코드 생성기 개발기

PM

backtodev

40대 PM, 다시 개발자로 돌아갑니다. 실패하고 배우며 성장하는 기록.

WiFi QR 코드 생성기를 만들었다 — AI로 처음 완성한 사이드 프로젝트 | backtodev