[아티클 03] DeepL 기획 및 v0로 UI 설계하기
사용하기 편리하고 아름다운 앱을 보며 ‘이건 어떻게 만들었을까?’ 궁금했던 경험이 있나요? 그렇다면 이번에 그 해답을 직접 확인할 수 있습니다. AI 디자이너 v0와 함께 클론 코딩을 통해 DeepL의 디자인과 기능을 분석하고 실제 앱을 구현해봅니다.
DeepL 핵심 기능 분해하기
본격적인 클론 코딩에 앞서 DeepL 웹사이트를 함께 살펴보며 앞으로 구현할 핵심 기능을 분석하고 정리해봅시다. 먼저 웹 브라우저에서 DeepL 웹사이트에 접속한 다음 화면에 나타나는 기능을 기준으로 정리해보겠습니다.
DeepL 웹사이트 : deepl.com
➊ 핵심 번역 인터페이스 : DeepL 사이트의 핵심 기능으로 왼쪽에는 입력 텍스트, 오른쪽에는 번역 결과가 표시되는 2단 레이아웃과 위쪽에 출발/도착 언어 선택 메뉴 및 언어 전환 버튼이 있습니다. 사용자가 번역에만 집중할 수 있도록 직관적으로 설계된 구조입니다.
➋ 텍스트-음성 변환 기능(Text-to-Speech, TTS) : 양쪽 패널의 스피커 아이콘을 누르면 브라우저 내장 웹 스피치 API를 이용해 번역된 텍스트를 자연스러운 발음으로 읽어주는 기능입니다. 클론 프로젝트에서도 이 기능을 그대로 재현해 사용자가 번역 결과를 귀로 확인할 수 있게 합니다.
➌ 대체 번역 제안 기능 : 번역된 문장의 특정 단어를 클릭하면 대체할 수 있는 비슷한 의미의 다른 단어를 팝업으로 보여주는 기능입니다. DeepL의 핵심 기능 중 하나로 클론 프로젝트에도 포함시켜 정교한 번역 경험을 제공합니다.
[추가] 음성-텍스트 변환 기능(Speech-to-Text, STT) : DeepL에는 음성 출력 기능은 있지만 음성 입력 기능은 없습니다. 따라서 이번 프로젝트에서는 스마트폰 음성 비서처럼 사용자의 목소리를 인식해 텍스트로 변환하는 STT 기능을 추가하여 기존 DeepL 번역 앱보다 더 편리한 번역기를 구현하는 것이 목표입니다.
이것이 앞으로 구현할 주요 기능입니다. DeepL의 핵심 장점을 유지하면서 편의 기능을 더해 한층 더 강력한 번역 앱을 만드는 여정이 될 것입니다. 이제 첫 번째 단계로 이 기능을 실제로 구현하기 위한 설계도를 준비해봅시다.
[바이브 코딩 53] v0와 함께 UI 설계하기
이제 기능들의 청사진을 완성했으니 본격적으로 UI를 구현할 차례입니다. v0와 함께 자연스럽게 대화하며 번역 앱에 필요한 핵심 기능과 모든 화면 요소를 차근차근 완성하겠습니다.
모든 것의 시작, 나만의 ‘설계도’ 만들기
건축에서 설계도가 중요하듯, UI 구현에서도 기준이 되는 시각 자료가 필요합니다. 여기서는 그 설계도로 DeepL 웹사이트의 번역기 인터페이스 스크린샷을 사용하겠습니다. 먼저 DeepL에서 간단한 문장을 번역한 뒤 번역 결과에서 원하는 단어를 클릭해 대안 팝업을 띄워보세요. 그다음 브라우저의 탭이나 주소창 등 불필요한 영역을 제외하고 번역기 인터페이스 부분만 정확히 사각형 형태로 캡처합니다. 이렇게 준비한 설계도는 v0가 UI 구현에만 집중할 수 있도록 도와주며 결과적으로 훨씬 더 정밀하고 깔끔한 화면을 완성하는 데 큰 도움이 됩니다.
v0의 클론 기능 활용하기
앞서 만든 설계도를 가지고 v0에서 UI 작업을 시작할 차례입니다. 채팅창 아래 첫 번째 버튼인 ➊ [Clone a Screenshot]을 클릭하고 방금 캡처한 설계도 ➋ 파일을 선택한 다음 ➌ [열기]를 누르세요. 그러면 파일을 선택하는 순간 v0가 즉시 이미지를 분석하고 UI 생성을 시작합니다.
별도의 전송 버튼을 누를 필요 없이 선택만으로 v0가 스크린샷을 기반으로 UI 코드 초안을 자동으로 만들어줍니다. 생성된 화면을 보니 제법 번역기 화면처럼 만들어주었습니다.
핵심 기능만 남기고 불필요한 부분 제거하기
1차 초안도 기본적인 구조를 갖추었지만 아직 프로젝트 목표와는 완벽히 일치하지는 않습니다. 이제 v0에게 핵심 기능만 남기고 불필요한 요소를 제거하도록 지시합니다. 이 과정은 AI와 함께 프로덕트를 점진적으로 개선해나가는 이터레이션Iteration의 핵심입니다.
v0가 지시에 따라 불필요한 버튼과 메뉴를 정리해주었습니다. 이제 UI는 프로젝트 목표에 맞춘 군더더기 없는 2차 화면으로 완성되었습니다. 이렇게 정제된 UI를 기반으로 다음 단계를 진행하면 v0가 의도를 보다 정확하게 이해하고 작업할 수 있습니다.
언어 선택 메뉴 정교하게 다듬기
v0의 클론 기능을 이용해 앱의 기본 화면과 구조를 완성했습니다. 이제 사용자가 직접 조작하는 핵심 부분, 즉 언어를 선택하고 바꾸는 영역을 더 세밀하게 완성해보겠습니다. 이를 위해 먼저 새로운 상세 설계도를 준비해야 합니다.
DeepL 웹사이트로 이동한 뒤, 화면 위쪽의 [출발 언어 선택] 버튼을 클릭해 드롭다운 메뉴를 열어보세요. 그 상태에서 브라우저의 불필요한 부분은 제외하고, 상단의 언어 전환 부분만 캡처하여 저장합니다. 이 이미지가 바로 앱 안에서 언어 선택 기능을 실제처럼 구현하기 위한 기준 자료가 됩니다.
01 언어를 고르는 드롭다운 메뉴는 앱의 첫인상과 완성도를 좌우하는 중요한 요소입니다. 방금 캡처한 이미지를 v0에게 전달하고 이 부분까지 세밀하게 구현해달라고 요청합니다.
02 이제 언어 선택 메뉴의 모양은 완성되었지만 아직 실제로 동작하지는 않습니다. 이번에는 상단 중앙에 출발 언어 버튼, 언어 전환 아이콘, 도착 언어 버튼을 나란히 정렬하고 전환 아이콘을 클릭하면 두 언어가 서로 바뀌는 기능을 추가해보겠습니다.
v0가 요청을 이해하고 상단 중앙에 언어 전환 영역을 정렬한 뒤, 실제로 전환 기능까지 완성했습니다. 이제 앱의 상단은 보기에도 깔끔하고, 실제로 동작까지 하는 완전한 형태의 언어 선택 바로 완성되었습니다.
음성 기능 UI 개선하기
이제 기본 인터페이스 위에 음성 기능 UI를 추가하고 다듬을 차례입니다. 여기서 구현할 기능은 두 가지로 하나는 DeepL에 있는 기존 텍스트-음성 변환Text-To-Speech, TTS 기능을 정교하게 다듬는 것이고, 다른 하나는 새로운 음성 입력 기능을 추가하는 것입니다.
01 먼저 기존 TTS 기능부터 시작하겠습니다. 이전 단계에서 []은 이미 배치되어 있지만 현재는 동작하지 않는 단순한 그림일 뿐입니다. [
]을 눌렀을 때 번역 결과를 읽어주는 동시에 사용자에게 ‘지금 번역 결과를 읽고 있습니다’라는 시각적 피드백을 제공하도록 기능 추가를 요청하겠습니다.
기존 스피커 아이콘에 ‘읽는 중’ 상태 디자인을 추가했습니다. 사용자가 []을 누르면 파동 애니메이션이 버튼 주변에 시각적으로 보이며 번역 결과가 재생되고 있음을 명확하게 보여줍니다.
02 다음으로는 DeepL 웹 버전에는 없는 특별한 기능을 추가해 번역기를 한층 더 편리하게 만들어보겠습니다. 바로 사용자의 목소리를 인식해 텍스트로 변환하는 음성-텍스트 변환Speech-To-Text, STT 기능입니다. 이 기능은 DeepL 원본에 존재하지 않기 때문에 새로운 마이크 아이콘을 추가하고 클릭 시 작동하는 인터랙션까지 디자인하도록 요청하겠습니다.
v0가 기획 의도를 이해하고 왼쪽 패널에 []과 이에 맞는 인터랙션 디자인을 새롭게 추가했습니다. 이로써 앱은 원본의 장점을 그대로 유지하면서 한층 더 높은 편의성과 독창성을 갖춘 형태로 완성되었습니다.
핵심 작업 공간 UI 구현하기
지금까지 앱의 전체적인 뼈대와 상단 컨트롤 영역을 완성했습니다. 이제 사용자가 실제로 글을 입력하고 번역 결과를 확인하게 될 가장 중요한 공간인 ‘핵심 작업 공간’을 만들 차례입니다. 왼쪽 입력 패널과 오른쪽 출력 패널의 세부적인 기능과 구조를 v0에게 한 단계씩 차근차근 지시하여 완성하겠습니다.
01 먼저 양쪽 패널에서 왼쪽은 사용자가 글을 쓸 수 있는 입력창으로 오른쪽은 번역된 결과가 표시될 출력 영역으로 만들어달라고 요청합시다.
양쪽 패널에 각각의 역할을 부여하여 이제 텍스트를 입력하고 결과를 볼 수 있는 기본적인 공간을 확보했습니다.
02 이제 왼쪽 입력 패널을 좀 더 편리하게 만들어봅시다. 먼저 입력창이 비어 있을 때 “번역할 내용을 입력하세요”라는 안내 문구가 표시되도록 합니다. 그리고 사용자가 입력한 내용을 한 번에 지울 수 있도록 입력창 오른쪽 위에 작은 ‘X’ 모양의 [삭제] 버튼을 추가하겠습니다.
입력창이 한층 더 똑똑해졌습니다. 이로 인해 사용자는 무엇을 해야 할지 바로 이해할 수 있고 입력 내용을 손쉽게 초기화할 수도 있습니다.
03 마지막으로 오른쪽 출력 패널의 구조를 더욱 체계적으로 정리해보겠습니다. 현재는 하나의 단일 영역이지만 앞으로 구현할 대안 기능에 대비해 이 공간을 메인 번역 영역과 대안 목록 영역으로 미리 구분해달라고 요청하겠습니다.
출력 패널의 내부 구조가 새롭게 설계되었습니다. 겉보기에는 큰 변화가 없어 보이지만 이제 메인 번역과 대체 번역을 각각 독립된 영역에 표시할 수 있는 체계적인 구조를 갖추게 되었습니다.
챕터 30 백엔드 API 구축 및 연결하기
UI가 완성되었으니 보이지 않는 곳에서 실제 번역을 처리하는 백엔드 API를 만들 것입니다. API는 UI로부터 들어오는 “이것 좀 번역해줘”라는 요청을 받아 오픈AI에게 전달하고 그 결과를 다시 UI에게 돌려주는 역할을 합니다. v0와 함께 두 종류의 전문 API를 단계별로 차근차근 구현해나갈 것입니다.
[바이브 코딩 54] API 준비하기
오픈의 AI 모델과 통신하려면 ‘API 키’라는 비밀 키가 필요합니다. 이 키는 외부에 절대 노출되어서는 안 되는 매우 중요한 정보입니다. 이전 [파트 04] AI 챗봇 만들기에서 발급받은 오픈AI API 키를 이번 프로젝트에서도 그대로 사용할 수 있습니다.
이 비밀 키는 코드에 직접 적는 대신 환경 변수Environment Variables라는 안전한 공간에 보관합니다. v0는 이러한 환경 변수를 손쉽게 설정할 수 있는 편리하고 안전한 기능을 제공합니다.
01 이제 v0 왼쪽 사이드바에 있는 [Vars]를 누르면 환경 변수를 추가할 수 있는 화면이 나타납니다. 여기서 [+]을 누른 뒤 API_KEY 입력창에는 OPENAI_API_KEY라고 적고, VALUE 입력창에는 여러분이 발급받은 오픈AI API 키를 입력하고 저장하세요.
02 앱과 오픈AI의 AI가 원활히 통신하려면 두 시스템을 이어 주는 ‘중간 다리’가 필요합니다. 그 역할을 하는 것이 바로 Vercel AI SDK입니다. 이 SDK는 복잡한 데이터 전송, 응답 처리, 실시간 스트리밍과 같은 어려운 과정을 자동으로 처리해 주는 매우 유용한 도구입니다. [파트 04] AI 챗봇 만들기에서도 사용했던 도구로 이번에도 간단한 프롬프트를 통해 v0에게 Vercel AI SDK를 설치하도록 요청하겠습니다.
필요한 라이브러리 설치를 모두 마쳤습니다. 이제 오픈AI의 비밀 키를 안전하게 보관했고 AI와의 소통을 담당할 Vercel AI SDK까지 준비가 완료되었습니다. 모든 환경 설정이 끝났으니 이제 본격적으로 백엔드 API 구축을 시작해보겠습니다.
핵심 번역 API 만들기
01 가장 먼저 해야 할 일은 번역 요청을 처리할 기본 API 엔드포인트를 만드는 것입니다. 프로젝트 내에 /api/translate 경로를 생성해 앱이 오픈AI와 통신할 수 있도록 설정하겠습니다.
v0가 요청을 정확히 이해해 번역 요청을 받을 수 있는 기본 API 구조를 자동으로 생성했습니다. 아직 구체적인 번역 로직은 포함되어 있지 않지만 이 단계에서 앱의 UI와 백엔드가 처음으로 연결되는 통신의 출발점이 만들어졌습니다.
02 이제 이 통신 창구가 사용자가 보낸 메시지를 이해할 수 있도록 만들어야 합니다. 사용자가 입력한 번역할 텍스트와 언어 정보를 읽어들이는 기능을 추가해달라고 요청합시다.
API가 사용자가 어떤 내용을 번역하려는지 정확히 파악하고 번역에 필요한 텍스트와 언어 정보를 확보할 수 있게 되었습니다.
03 사용자의 요청을 이해하는 API를 구현했으니 오픈AI와 앱을 연결해 번역된 텍스트 응답을 받아오는 핵심 로직을 구성할 차례입니다. 이전에 설치한 Vercel AI SDK를 활용해 AI가 번역을 완전히 마칠 때까지 기다렸다가 완성된 문장을 한 번에 받아오는 방식으로 구현하겠습니다.
v0가 SDK를 활용해 오픈AI에 번역을 요청하고 완성된 응답을 깔끔한 텍스트 데이터로 반환하는 핵심 로직을 성공적으로 구축했습니다. API는 SDK의 편리함을 그대로 유지하면서 완전한 번역 결과를 안정적으로 전달할 준비를 마쳤습니다.
04 모든 기술적 연결이 완료되었으니 이제 오픈AI에게 전달할 프롬프트를 작성할 차례입니다.
v0가 실시간 번역을 처리하는 강력한 백엔드 API를 완성했습니다. 이제 첫 번째 API는 사용자의 요청을 받아 실시간으로 생각하고 대답할 수 있게 되었습니다.
대체 번역 제안 API 만들기
01 DeepL의 주요 기능 중 하나인 대체 번역 제안을 구현하기 위해 일반 번역기와는 별도로 전문적인 역할을 담당할 두 번째 API를 만들겠습니다. 먼저 /api/alternatives 경로를 생성해 이 기능이 동작할 새로운 통신 창구를 준비합니다.
두 번째 API가 성공적으로 생성되었습니다.
02 이 API는 일반 번역과는 다른 특정한 임무를 수행해야 합니다. 사용자가 클릭한 특정 단어에 대해 동의어나 유사어를 찾아 JSON 배열 형식으로만 응답하도록 AI에게 명확히 지시합니다.
v0가 특정 단어의 대체 표현을 찾아주는 전문 API를 완성했습니다. 이제 앱은 빠른 번역을 담당하는 API와 어휘 확장을 담당하는 API로 두 가지 기능을 모두 갖추게 되었습니다.
[바이브 코딩 55] 핵심 기능에 생명 불어넣기
앞서 사용자가 보는 화면과 실제 기능을 처리하는 백엔드 API를 각각 완성했습니다. 하지만 이 둘은 아직 연결되어 있지 않아 현재 상태로는 아무런 동작도 하지 않습니다. 이번에는 두 부분을 연결해 사용자가 버튼을 누르면 API가 실행되고 결과가 화면에 표시되는 완전한 애플리케이션을 만들어보겠습니다.
핵심 번역 기능에 생명 불어넣기
가장 먼저 [번역하기] 버튼에 실제 기능을 연결합니다. 버튼을 클릭하면 메인 번역 API인 /api/translate와 통신하고 번역 결과가 화면에 표시되도록 설정합니다.
[번역하기] 버튼과 백엔드 API를 성공적으로 연결했습니다. 이제 앱의 핵심 번역 기능이 완벽하게 작동합니다.
번역 결과 복사 기능 추가하기
번역 기능을 테스트해보면 훌륭한 번역 결과를 보여줍니다. 하지만 사용자가 이 번역 결과를 메모장이나 이메일 등 다른 곳에 활용하려면 어떻게 해야 할까요? 바로 ‘복사하기’ 기능이 필요합니다.
이번에는 복사 아이콘에 실제 기능을 연결하겠습니다. 사용자가 아이콘을 클릭하면 브라우저의 기본 기능인 클립보드 API를 이용해 번역된 텍스트 전체를 복사하도록 v0에게 지시합니다. 또한 복사가 성공했음을 사용자에게 명확히 알릴 수 있도록 시각적 피드백을 함께 추가해 사용 경험을 더욱 향상시켜보겠습니다.
이제 사용자는 한 번의 클릭만으로 번역된 문장을 복사할 수 있으며 아이콘이 체크 표시로 전환되는 피드백을 통해 작업이 성공적으로 처리되었음을 직관적으로 확인할 수 있습니다. 작지만 매우 중요한 사용자 경험 개선이 이루어졌습니다.
대안 기능 UI 완성하기
이제 번역기 앱을 한 단계 더 발전시켜 줄 핵심 사용자 경험, 바로 대안 기능의 UI를 완성할 차례입니다. DeepL에서는 사용자의 만족도를 높이기 위해 두 가지 기능을 제공합니다. 이번에는 이 두 가지 기능을 차례로 구현해보겠습니다. 이 기능들은 단순히 고정된 화면 요소가 아니라 사용자의 행동에 따라 동적으로 반응하기 때문에 v0에게 각 상황을 구체적으로 설명하는 것이 중요합니다.
01 첫 번째 기능은 번역된 문장 속 특정 단어를 클릭했을 때 그 단어를 대체할 수 있는 동의어나 유사어를 보여주는 팝업Popover입니다. 이 기능을 통해 사용자는 번역의 미묘한 뉘앙스를 직접 조정할 수 있습니다. 이를 위해 먼저 DeepL 웹사이트에서 번역된 단어 하나를 클릭해 팝업이 열린 상태를 캡처합니다. 브라우저의 불필요한 영역을 제외하고 팝업이 표시된 번역 인터페이스 부분만 정밀하게 담은 ‘상세 설계도’를 준비합니다. 먼저 설계도를 만들기 위해 DeepL 사이트로 돌아가 번역을 완료합니다.
02 오른쪽 결과창에 있는 번역된 문장 속 단어 하나를 마우스로 클릭합니다. 해당 단어 아래에 대체 단어 목록이 담긴 팝업이 보이는 상태에서 이미지를 캡처합니다. 캡처한 이미지는 저장한 다음 v0에 첨부하고 다음 프롬프트를 요청합니다.
v0가 첨부한 설계도를 바탕으로 단어를 클릭했을 때 나타나는 정교한 팝업 UI를 완성했습니다. 이제 UI는 사용자의 세밀한 요구에 반응할 준비를 마쳤습니다.
03 이제는 단어 수준의 제안을 넘어 문장 전체의 뉘앙스를 조정할 수 있는 대체 번역 목록 기능의 UI를 구체화할 차례입니다. 이전 단계에서 이 목록이 들어갈 보조 영역을 이미 만들어 두었으므로 이번에는 그 공간에 실제 데이터가 채워졌을 때의 화면을 설계합니다. 또한 목록의 각 항목을 클릭했을 때 메인 번역 문장이 즉시 교체되는 인터랙션을 디자인하도록 AI에게 지시하겠습니다. 먼저 DeepL 사이트에서 번역을 실행하고 메인 결과창 아래에 대안으로 다른 번역 문장 목록이 나타나는 경우를 찾습니다.
04 이 문장의 단위 대체 번역 목록이 표시된 상태의 출력 패널 전체를 캡처하여 저장합니다. 그런 다음 v0에 첨부하고 다음 프롬프트를 요청합니다.
기존에 만들어 두었던 보조 영역에 실제 데이터가 채워졌을 때의 목록 디자인과 인터랙션이 완벽하게 구현했습니다. 이제 사용자는 목록에서 다른 번역 문장을 선택하면 메인 결과가 즉시 교체될 수 있도록 UI가 바뀌었습니다.
음성 기능 활성화하기
이제 이전 단계에서 추가했던 마이크와 음성 아이콘에 브라우저의 음성 인식 기술인 웹 스피치 APIWeb Speech API을 연결해 실제 기능을 완성할 차례입니다.
01 왼쪽 입력 패널의 마이크 아이콘에 듣기 기능을 부여합니다. 사용자가 아이콘을 클릭하면 브라우저가 사용자의 음성을 인식해 텍스트로 변환하고 그 내용을 입력창에 자동으로 채워 넣도록 AI에게 지시하겠습니다.
이제 마이크 아이콘이 브라우저의 귀 역할을 하게 되었습니다. 사용자는 키보드 없이도 목소리만으로 번역을 시작할 수 있는 완전한 핸즈프리hands-free 환경을 경험할 수 있습니다.
02 양쪽 패널의 스피커 아이콘에 말하기 기능을 추가합니다. 사용자가 아이콘을 클릭하면 번역된 텍스트를 해당 언어의 자연스러운 음성으로 읽어주도록 AI에게 지시하겠습니니다.
음성 아이콘에 앱의 목소리 기능을 추가하여 사용자는 텍스트를 눈으로 읽을 뿐만 아니라 원어민에 가까운 발음으로 직접 들어볼 수 있습니다.
마침내 앱이 듣고 말하는 두 가지 능력을 모두 갖추게 되었습니다. 여러분은 단순히 UI와 백엔드를 만드는 수준을 넘어 두 시스템을 유기적으로 연결해 복잡한 상호작용까지 구현해냈습니다. 사용자의 입력부터 실시간 번역, 단어 클릭, 대체 번역 제안 그리고 최종 교체에 이르는 전체 데이터 흐름을 v0에게 단계적으로 지시하여 완성한 것입니다.
이제 여러분의 상상력을 발휘해보세요. 다크 모드를 추가하거나 번역 기록을 저장하는 기능을 구현해 프로젝트를 자신만의 스타일로 발전시켜 보세요. 이 앱은 여러분의 첫 번째 포트폴리오로 손색없는 완성도 높은 작품이 될 것입니다.
