웹사이트 문의하기 기능에 자동 답변 이메일을 추가하고 싶으신가요? Resend를 사용하면 간단한 코드만으로 전문적인 이메일 발송 시스템을 구축할 수 있습니다.
왜 Resend인가?
Resend는 개발자 친화적인 이메일 발송 서비스로, 다음과 같은 장점이 있습니다:
- 간편한 API: REST API로 몇 줄의 코드만으로 이메일 발송 가능
- React 이메일 템플릿: JSX로 아름다운 이메일 템플릿 작성
- 무료 플랜: 월 3,000건까지 무료 (개인 프로젝트에 충분)
- 높은 도달률: 전문적인 이메일 인프라로 스팸 처리 최소화
- 상세한 로그: 발송 내역, 열람률, 클릭률 등 추적 가능
1. Resend 회원가입 및 프로젝트 생성
- Resend.com에 접속하여 회원가입
- 로그인 후 대시보드에서 새 프로젝트 생성
- 프로젝트 이름 입력 (예: "telepasi-contact")
2. 도메인 등록 및 DNS 설정
2.1 Resend에 도메인 추가
Resend 대시보드에서 "Domains" 메뉴로 이동하여 도메인을 추가합니다.

주요 설정 항목:
- Domain: 이메일 발송에 사용할 도메인 (예:
telepasi.com) - Region: 발송 지역 선택 (한국의 경우
US East권장)
도메인 추가 후 Resend가 제공하는 DNS 레코드를 확인합니다:
- SPF 레코드 (TXT): 발송 서버 인증
- DKIM 레코드 (TXT): 이메일 무결성 검증
- DMARC 레코드 (TXT): 이메일 정책 설정
2.2 DNS 설정 (가비아 예시)
도메인 등록 업체(예: 가비아)에서 DNS 레코드를 추가합니다.

가비아 설정 방법:
- 가비아 로그인 → My가비아 → 서비스 관리
- 도메인 관리 → DNS 정보 → DNS 관리
- Resend가 제공한 레코드 추가:
| 타입 | 호스트 | 값/위치 |
|---|---|---|
| TXT | @ | v=spf1 include:_spf.resend.com ~all |
| TXT | resend._domainkey | (Resend에서 제공한 DKIM 값) |
| TXT | _dmarc | v=DMARC1; p=none; rua=mailto:admin@telepasi.com |
주의사항:
- DNS 전파에는 최대 48시간 소요 (보통 10분~1시간)
- 설정 후 Resend 대시보드에서 "Verify" 버튼으로 확인
- 검증 성공 시 도메인 상태가 "Verified"로 변경됨
3. API 키 발급
- Resend 대시보드 → "API Keys" 메뉴
- "Create API Key" 클릭
- 이름: 용도 명시 (예: "Production API Key")
- 권한:
Sending access: 이메일 발송 권한Full access: 전체 권한 (필요 시)
- 생성된 API 키를 안전하게 보관 (
.env파일)
# .env
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠️ 보안 주의: API 키는 절대 Git에 커밋하지 마세요!
4. 이메일 템플릿 작성
4.1 React Email 설치 (선택사항)
npm install @react-email/components
# 또는
pnpm add @react-email/components
4.2 HTML 템플릿 예시
React Email 없이 간단한 HTML로도 충분합니다:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 10px 10px 0 0;
text-align: center;
}
.content {
background: #f9f9f9;
padding: 30px;
border: 1px solid #e0e0e0;
border-top: none;
}
.footer {
text-align: center;
padding: 20px;
color: #666;
font-size: 12px;
}
.button {
display: inline-block;
background: #667eea;
color: white;
padding: 12px 30px;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
}
</style>
</head>
<body>
<div class="header">
<h1>📧 문의해 주셔서 감사합니다!</h1>
</div>
<div class="content">
<p>안녕하세요, <strong>{{name}}님</strong></p>
<p>텔레파시를 이용해 주셔서 감사합니다.</p>
<p>고객님의 문의 내용을 잘 받았으며, 영업일 기준 1-2일 내에 답변드리겠습니다.</p>
<div style="background: #fff; padding: 15px; border-left: 4px solid #667eea; margin: 20px 0;">
<strong>문의 내용:</strong><br>
{{message}}
</div>
<p>추가 문의사항이 있으시면 이 이메일에 직접 답장해 주세요.</p>
<a href="https://telepasi.com" class="button">사이트 방문하기</a>
</div>
<div class="footer">
<p>© 2026 Telepasi. All rights reserved.</p>
<p>서울시 강남구 테헤란로 123 | contact@telepasi.com</p>
</div>
</body>
</html>
5. SvelteKit에서 Resend 사용하기
5.1 Resend SDK 설치
npm install resend
# 또는
pnpm add resend
5.2 API 엔드포인트 생성
src/routes/api/send-contact-email/+server.js 파일을 생성합니다:
import { Resend } from 'resend';
import { RESEND_API_KEY } from '$env/static/private';
import { json } from '@sveltejs/kit';
const resend = new Resend(RESEND_API_KEY);
/** @type {import('./$types').RequestHandler} */
export async function POST({ request }) {
try {
const { name, email, message } = await request.json();
// 입력값 검증
if (!name || !email || !message) {
return json(
{ error: '필수 항목을 모두 입력해주세요.' },
{ status: 400 }
);
}
// HTML 템플릿 생성 (변수 치환)
const htmlTemplate = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 10px 10px 0 0;
text-align: center;
}
.content {
background: #f9f9f9;
padding: 30px;
border: 1px solid #e0e0e0;
border-top: none;
}
.footer {
text-align: center;
padding: 20px;
color: #666;
font-size: 12px;
}
.button {
display: inline-block;
background: #667eea;
color: white;
padding: 12px 30px;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
}
.message-box {
background: #fff;
padding: 15px;
border-left: 4px solid #667eea;
margin: 20px 0;
white-space: pre-wrap;
}
</style>
</head>
<body>
<div class="header">
<h1>📧 문의해 주셔서 감사합니다!</h1>
</div>
<div class="content">
<p>안녕하세요, <strong>${name}님</strong></p>
<p>텔레파시를 이용해 주셔서 감사합니다.</p>
<p>고객님의 문의 내용을 잘 받았으며, 영업일 기준 1-2일 내에 답변드리겠습니다.</p>
<div class="message-box">
<strong>문의 내용:</strong><br>
${message}
</div>
<p>추가 문의사항이 있으시면 이 이메일에 직접 답장해 주세요.</p>
<a href="https://telepasi.com" class="button">사이트 방문하기</a>
</div>
<div class="footer">
<p>© 2026 Telepasi. All rights reserved.</p>
<p>서울시 강남구 테헤란로 123 | contact@telepasi.com</p>
</div>
</body>
</html>
`;
// Resend로 이메일 발송
const { data, error } = await resend.emails.send({
from: 'Telepasi <noreply@telepasi.com>',
to: [email], // 문의자 이메일
replyTo: 'contact@telepasi.com', // 답장 받을 이메일
subject: `[Telepasi] ${name}님의 문의가 접수되었습니다`,
html: htmlTemplate
});
if (error) {
console.error('Resend 발송 오류:', error);
return json(
{ error: '이메일 발송에 실패했습니다.' },
{ status: 500 }
);
}
// 관리자에게도 알림 (선택사항)
await resend.emails.send({
from: 'Telepasi <noreply@telepasi.com>',
to: ['admin@telepasi.com'],
subject: `[신규 문의] ${name}님으로부터 문의가 들어왔습니다`,
html: `
<h2>신규 문의 알림</h2>
<p><strong>이름:</strong> ${name}</p>
<p><strong>이메일:</strong> ${email}</p>
<p><strong>내용:</strong></p>
<pre>${message}</pre>
`
});
return json({
success: true,
message: '이메일이 성공적으로 발송되었습니다.',
emailId: data.id
});
} catch (err) {
console.error('이메일 발송 오류:', err);
return json(
{ error: '서버 오류가 발생했습니다.' },
{ status: 500 }
);
}
}
5.3 프론트엔드에서 호출
문의하기 폼 컴포넌트 예시:
<script>
let name = $state('');
let email = $state('');
let message = $state('');
let loading = $state(false);
let success = $state(false);
let error = $state(null);
async function handleSubmit() {
loading = true;
error = null;
success = false;
try {
const response = await fetch('/api/send-contact-email', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name, email, message })
});
const result = await response.json();
if (response.ok) {
success = true;
name = '';
email = '';
message = '';
alert('문의가 접수되었습니다. 이메일을 확인해주세요!');
} else {
error = result.error || '전송에 실패했습니다.';
}
} catch (err) {
error = '네트워크 오류가 발생했습니다.';
} finally {
loading = false;
}
}
</script>
<form onsubmit={handleSubmit}>
<input type="text" bind:value={name} placeholder="이름" required />
<input type="email" bind:value={email} placeholder="이메일" required />
<textarea bind:value={message} placeholder="문의 내용" required></textarea>
<button type="submit" disabled={loading}>
{loading ? '전송 중...' : '문의하기'}
</button>
{#if error}
<p class="error">{error}</p>
{/if}
</form>
6. 테스트 및 확인
6.1 로컬 테스트
- 개발 서버 실행:
npm run dev - 문의하기 폼에서 테스트 데이터 입력
- 이메일 수신함 확인

6.2 Resend 대시보드에서 확인
- Logs: 발송 내역 및 상태 확인
- Analytics: 열람률, 클릭률 통계
- Errors: 발송 실패 원인 분석
7. 프로덕션 배포 시 체크리스트
- 도메인 DNS 설정 완료 및 검증
- API 키 환경 변수 설정 (
.env파일) -
from이메일 주소가 검증된 도메인 사용 - 이메일 템플릿 모바일 반응형 테스트
- 스팸 필터 테스트 (Gmail, Naver, Daum 등)
- 에러 핸들링 및 로깅 구현
- Rate limiting 설정 (남용 방지)
8. 추가 기능 구현 아이디어
8.1 이메일 템플릿 다양화
// 템플릿 파일 분리
import { welcomeTemplate } from '$lib/email-templates/welcome.js';
import { contactTemplate } from '$lib/email-templates/contact.js';
import { resetPasswordTemplate } from '$lib/email-templates/reset-password.js';
8.2 발송 실패 시 재시도 로직
async function sendEmailWithRetry(emailData, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const result = await resend.emails.send(emailData);
return result;
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
8.3 이메일 큐 시스템
대량 발송이 필요한 경우 Redis + Bull Queue 사용:
pnpm add bull redis
9. 비용 및 제한사항
무료 플랜
- 발송량: 월 3,000건
- API 호출: 무제한
- 도메인: 1개
Pro 플랜 ($20/월)
- 발송량: 월 50,000건
- 추가 도메인: 무제한
- 전용 IP: 옵션
발송 제한
- 초당 최대 10건 (Rate limit)
- 이메일 크기 최대 40MB
10. 문제 해결 (Troubleshooting)
이메일이 스팸함으로 가는 경우
- SPF, DKIM, DMARC 레코드 재확인
- 발송 주소를
noreply@도메인형식으로 변경 - 이메일 내용에 스팸 키워드 제거
- "Warm-up" 기간 필요 (처음엔 소량 발송)
API 키 인증 실패
// API 키 확인
console.log('API Key:', RESEND_API_KEY?.substring(0, 10) + '...');
// 환경 변수 로드 확인
if (!RESEND_API_KEY) {
throw new Error('RESEND_API_KEY가 설정되지 않았습니다.');
}
도메인 검증 실패
- DNS 전파 대기 (최대 48시간)
- DNS 레코드 오타 확인
- 호스트명 정확히 입력 (@ 또는 빈 문자열)
dig명령어로 DNS 확인:dig TXT telepasi.com dig TXT resend._domainkey.telepasi.com
마무리
Resend를 활용하면 복잡한 이메일 서버 설정 없이도 전문적인 이메일 발송 시스템을 구축할 수 있습니다.
핵심 요약:
- 도메인 등록 및 DNS 설정 (SPF, DKIM, DMARC)
- API 키 발급 및 환경 변수 설정
- HTML 이메일 템플릿 작성
- SvelteKit API 엔드포인트 구현
- 테스트 및 프로덕션 배포
질문이나 문제가 있으시면 댓글로 남겨주세요. 도움이 되었다면 좋아요도 부탁드립니다! 👍
참고 자료:


주파수 소통방 (0)
로딩 중...