Nuxt3를 활용해 제비뽑기 웹 서비스를 개발한 과정을 정리했습니다. 랜덤 추첨 알고리즘 구현, 상태 관리, SEO 적용, 배포 과정까지 실제 개발 경험을 기반으로 설명합니다.

Nuxt3로 제비뽑기 웹 서비스를 만든 이유와 랜덤 추첨 기능 구현 방법
최근 간단한 이벤트나 모임에서 사용할 수 있는 웹 기반 제비뽑기 서비스를 만들게 되었습니다. 단순히 랜덤 숫자를 출력하는 수준이 아니라, 누구나 모바일에서 쉽게 사용할 수 있고 검색 유입까지 고려한 서비스가 필요했습니다. 그래서 선택한 기술이 바로 Nuxt3입니다.
이번 글에서는 실제로 제작한 제비뽑기 서비스인 '제비뽑기' 기능을 예시로, 왜 Nuxt를 선택했는지와 랜덤 추첨 기능을 어떻게 구현했는지 개발자 관점에서 정리해보겠습니다.
https://tool.daplus.co.kr/tools/lottery
제비뽑기 추첨 - 다플 도구모음
이름이나 항목을 입력하고 공정하게 무작위 추첨하세요.
tool.daplus.co.kr
왜 Nuxt로 만들었을까
처음에는 Vue SPA로만 구현할 생각이었습니다. 하지만 툴 서비스 특성상 검색 유입이 중요했습니다.
예를 들어 사용자는 다음과 같은 키워드로 검색합니다.
- 제비뽑기 사이트
- 랜덤 추첨
- 온라인 사다리타기
- 이름 추첨기
- 추첨 프로그램
일반적인 SPA는 검색 엔진이 페이지 내용을 수집하는 데 한계가 있을 수 있습니다. 반면 Nuxt는 SSR과 SSG를 지원하기 때문에 SEO 측면에서 훨씬 유리합니다.
특히 툴 사이트는 검색 유입이 곧 트래픽으로 연결되기 때문에 처음부터 SEO를 고려하는 것이 중요했습니다.
프로젝트 구조
pages/
└── tools/
└── lottery.vue
components/
├── LotteryForm.vue
├── LotteryResult.vue
└── LotteryAnimation.vue
composables/
└── useLottery.ts
페이지는 최대한 단순하게 유지하고, 랜덤 로직은 composable로 분리했습니다.
제비뽑기 기능 요구사항
생각보다 요구사항은 많았습니다.
입력
- 참가자 이름 입력
- 여러 명 추가 가능
- 빈 값 제거
- 중복 이름 허용 여부 결정
추첨
- 랜덤 선택
- 중복 당첨 방지
- 재추첨 가능
결과
- 애니메이션 출력
- 당첨자 강조
- 모바일 대응
랜덤 추첨 알고리즘 구현
가장 단순한 방법은 Math.random()입니다.
const index = Math.floor(Math.random() * users.length)
const winner = users[index]
하지만 여러 명을 동시에 뽑아야 하는 경우에는 문제가 발생합니다.
예를 들어 3명을 추첨해야 하는데 같은 사람이 여러 번 선택될 수 있습니다.
그래서 배열을 섞은 뒤 필요한 개수만큼 가져오는 방식으로 구현했습니다.
export const shuffle = (array) => {
const copied = [...array]
for (let i = copied.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[copied[i], copied[j]] = [copied[j], copied[i]]
}
return copied
}
사용 방법입니다.
const winners = shuffle(users).slice(0, count)
이 방식은 중복 당첨을 방지하면서 비교적 균등한 랜덤 결과를 얻을 수 있습니다.
Composable로 추첨 로직 분리
Nuxt에서는 재사용 가능한 로직을 composable로 분리하는 것이 좋습니다.
export const useLottery = () => {
const winners = ref([])
const draw = (users, count) => {
winners.value = shuffle(users).slice(0, count)
}
return {
winners,
draw
}
}
페이지에서는 매우 간단하게 사용할 수 있습니다.
const { winners, draw } = useLottery()
draw(users.value, 1)
애니메이션 구현
사용자가 버튼을 누르자마자 결과가 나오면 재미가 없습니다.
그래서 짧은 로딩 애니메이션을 추가했습니다.
const loading = ref(false)
const startLottery = async () => {
loading.value = true
await wait(2000)
draw(users.value, count.value)
loading.value = false
}
2초 정도의 대기 시간을 넣어주면 실제 제비를 뽑는 듯한 느낌을 줄 수 있습니다.
SEO를 고려한 Meta 설정
Nuxt의 장점 중 하나는 페이지 단위 메타 태그 설정입니다.
useSeoMeta({
title: '온라인 제비뽑기',
description: '무료 랜덤 추첨 및 제비뽑기 서비스',
ogTitle: '온라인 제비뽑기',
ogDescription: '이름 추첨, 랜덤 추첨 기능 제공'
})
툴 사이트는 검색 유입이 중요하기 때문에 페이지별 메타 설정을 반드시 해주는 것이 좋습니다.
모바일 대응
실제 사용자의 대부분은 모바일에서 접속합니다.
그래서 다음 사항을 고려했습니다.
항목적용
| 반응형 레이아웃 | O |
| 모바일 버튼 크기 | O |
| 터치 영역 확대 | O |
| 키보드 입력 대응 | O |
Nuxt와 TailwindCSS를 함께 사용하면 모바일 대응이 상당히 편해집니다.
성능 최적화
툴 사이트는 기능보다 속도가 더 중요할 때가 많습니다.
적용한 최적화는 다음과 같습니다.
컴포넌트 분리
<LotteryForm />
<LotteryAnimation />
<LotteryResult />
Lazy Loading
defineAsyncComponent(() => import('./LotteryAnimation.vue'))
Hydration 최소화
필요 없는 상태 관리를 제거하고 클라이언트 렌더링 비용을 줄였습니다.
배포 후 느낀 점
생각보다 "제비뽑기" 키워드의 검색량이 꾸준했습니다.
특히 다음과 같은 상황에서 사용됩니다.
- 회사 점심 메뉴 정하기
- 이벤트 당첨자 추첨
- 회식 자리 게임
- 학생 발표 순서 정하기
- 랜덤 팀 구성
작은 기능 하나라도 검색 의도가 명확하면 꾸준한 유입이 발생할 수 있다는 점을 다시 느끼게 되었습니다.

마무리
이번 프로젝트는 복잡한 서비스는 아니었지만 Nuxt3의 장점을 다시 한번 체감할 수 있는 프로젝트였습니다.
SSR과 SEO, 간단한 상태 관리, 빠른 개발 속도까지 고려하면 작은 웹 툴 서비스를 만들 때 Nuxt는 상당히 좋은 선택이라고 생각합니다.
단순한 제비뽑기 기능이라도 사용자가 실제로 필요로 하는 문제를 해결해 주는 서비스라면 충분히 의미 있는 프로젝트가 될 수 있습니다.
앞으로도 이런 작은 웹 도구들을 계속 만들어 보면서 Nuxt 기반의 서비스 운영 경험을 정리해볼 예정입니다.
서비스 체험:
https://tool.daplus.co.kr/tools/lottery
제비뽑기 추첨 - 다플 도구모음
이름이나 항목을 입력하고 공정하게 무작위 추첨하세요.
tool.daplus.co.kr
'실무개발 > Front' 카테고리의 다른 글
| Nuxt로 PDF 합치기 도구 만들기: 서버 업로드 없이 브라우저에서 PDF 병합 구현하기 (0) | 2026.06.30 |
|---|---|
| Nuxt와 PHP로 만든 정적 서비스 개발 사례 플랜앱트하우(플하) -plan.apthow.com 구조 분석 (0) | 2026.06.16 |
| PWA 앱 설치 방법 총정리: 안드로이드, 아이폰, PC에서 설치하는 방법 (0) | 2026.06.07 |
| Nuxt와 Codex로 만든 알뜰폰 요금제 비교 서비스 개발기 (0) | 2026.06.02 |
| Nuxt4 설치부터 실제 배포까지 완벽 정리 (0) | 2026.05.21 |
