안녕하세요. 정지현 입니다. :)
최근에 포트폴리오 페이지에 간단한 Contact 섹션을 추가 하였는데요.
언제든 저에게 메일을 보낼 수 있도록 하고 싶지만 서버를 24시간 돌리고 싶지는 않아서...😅 javascript API로 바로 메일을 보낼 수 있도록 구현 하였습니다.
방법을 찾던 중 emailjs가 월 500건까지는 무료로 사용이 가능함을 알게 되었고 공식문서도 친절하여서 emailjs로 선택을 했습니다 !
( 만약 파일 첨부와 같은 기능을 사용하려면 돈을 지불해야 합니다. )
그럼 emailjs 사용법을 간단하게 알아볼게요.
원하는 이메일 서비스 선택하기.
서비스를 원하는 이메일을 선택하시면 됩니다.
connect Acount 버튼을 눌러 사용할 이메일 계정을 연결하면 위와 같이 연결된 메일이 보일거에요. 해당 메일이 발신자가 됩니다 !
다 작성 하셨으면 서비스를 생성해주시면 됩니다.
3. Templates 생성
메일 템플릿을 만들어 줄게요.
상단 좌측 Email Templates 클릭 후 Create 버튼을 눌러주시면 아래와 같은 화면이 나올거에요.
To email : 메일을 받을 주소를 적어주시면 됩니다. 저는 포트폴리오 페이지에 실을거라서 제 개인 메일로 적었어요.
From name : 옵셔널 값입니다.
From email : 보내는 메일 계정이고, emailjs에서는 저희가 연결한 계정이 됩니다.
Replay to : 회신을 보낼 이메일을 명시합니다.
BCC , CC : 숨은 참조, 참조 입니다.
content에 보시면
{{ to_name }} {{ from_name }} {{ message }} 중괄호 표시가 있죠?
중괄호 표현을 사용하여 변수 값을 받을 수 있습니다.
저희 프로젝트에 똑같은 이름으로 변수를 만들어 input을 받고 emailjs에 파라미터로 넘겨주면 각각 맞는 값들이 동적으로 들어오게 됩니다 !
emailjs SDK 설치
npm install @emailjs/browser --save
Form UI를 생성
사용자 input을 처리하는 방법을 여러가지가 있지만, emailjs에서 권장하는 방법대로 해볼게요.
form을 사용했구요 form의 value를 가져오기 위해 useRef를 사용하였습니다.
import { useRef } from 'react'
import emailjs from '@emailjs/browser'
import style from './Contact.module.scss'
const Contact = () => {
const form = useRef()
return (
<div className={style.contact}>
// ...
<form ref={form} onSubmit={onSubmitForm}>
<label>Name *</label>
<inputtype="text" name="name" required />
<label>Email *</label>
<input type="email" name="email" required />
<label>Message *</label>
<textarea name="message" required />
<input
className={style.submit}
type="submit"
value="submit"
/>
</form>
</div>
</div>
)
}
export default Contact
메일 보내는 함수 추가
import { useRef } from 'react'
import emailjs from '@emailjs/browser'
import style from './Contact.module.scss'
const Contact = () => {
const form = useRef()
// send mail
const onSubmitForm = (event) => {
event.preventDefault()
try {
emailjs.sendForm(
process.env.NEXT_PUBLIC_NEXT_PUBLIC_MAIL_SERVER_KEY,
process.env.NEXT_PUBLIC_MAIL_TEMPLATE_KEY,
form.current,
process.env.NEXT_PUBLIC_MAIL_PRIVATE_KEY
)
toast.success('소중한 의견 감사드립니다.', {
position: toast.POSITION.TOP_CENTER,
icon: '💌',
hideProgressBar: true,
className: 'toast-message'
})
} catch (error) {
toast.error('메일 전송에 실패하였습니다. ', {
position: toast.POSITION.TOP_CENTER,
icon: '🥲',
hideProgressBar: true,
className: 'toast-message'
})
}
}
return (
<div className={style.contact}>
// ...
<form ref={form} onSubmit={onSubmitForm}>
<label>Name *</label>
<inputtype="text" name="name" required />
<label>Email *</label>
<input type="email" name="email" required />
<label>Message *</label>
<textarea name="message" required />
<input
className={style.submit}
type="submit"
value="submit"
/>
</form>
</div>
</div>
)
}
export default Contact
onSubmitForm 함수를 추가해줍니다.
서버 전송 후 새로고침이 되지 않게 preventDefault를 사용합니다.
emailjs.sendForm쪽을 자세히 보면, 기본 형태는 아래와 같습니다. 저는 환경변수를 사용해서 각 키들을 숨겨두었어요.
각각의 키들을 emailjs에서 잘 매칭해서 넣어주기만 하면 되고, 저희는 ref 사용했기 때문에 form.current를 세 번째 인자로 넣어주면 저희가 만들어둔 변수들이 템플릿에 매칭되어서 출력됩니다.
emailjs.sendForm('YOUR_SERVICE_ID','YOUR_TEMPLATE_ID', form.current, 'YOUR_PUBLIC_KEY')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
각각의 키들은 요기서 찾을 수 있어요 👀
YOUR_SERVICE_ID
YOUR_TEMPLATE_ID
YOUR_PUBLIC_KEY
전체 코드
import { useRef } from 'react'
import emailjs from '@emailjs/browser'
import style from './Contact.module.scss'
const Contact = () => {
const form = useRef()
const onSubmitForm = (event) => {
event.preventDefault()
try {
emailjs.sendForm(
process.env.NEXT_PUBLIC_NEXT_PUBLIC_MAIL_SERVER_KEY,
process.env.NEXT_PUBLIC_MAIL_TEMPLATE_KEY,
form.current,
process.env.NEXT_PUBLIC_MAIL_PRIVATE_KEY
)
toast.success('소중한 의견 감사드립니다.', {
position: toast.POSITION.TOP_CENTER,
icon: '💌',
hideProgressBar: true,
className: 'toast-message'
})
} catch (error) {
toast.error('메일 전송에 실패하였습니다. ', {
position: toast.POSITION.TOP_CENTER,
icon: '🥲',
hideProgressBar: true,
className: 'toast-message'
})
}
}
return (
<div className={style.contact}>
// ...
<form ref={form} className={style.form} onSubmit={onSubmitForm}>
<label>Name *</label>
<input className={style.input} type="text" name="name" required />
<label>Email *</label>
<input className={style.input} type="email" name="email" required />
<label>Message *</label>
<textarea className={style.message} name="message" />
<input
className={style.submit}
type="submit"
value="submit"
required
/>
</form>
</div>
</div>
)
}
export default Contact
위의 과정을 잘 마쳤다면 로컬에서 정상적으로 테스트 해볼 수 있을 텐데요.
환경 변수등으로 따로 emailjs 관련 key를 빼두었다면, 빌드 후 프로덕션 환경에서는 메일이 정상적으로 발송되지 않을거에요.
vercel이 해당 변수에 엑세스 할 수 없기 때문이죠.
이럴 땐 배포 대상의 프로젝트에서 직접 환경 변수를 세팅해주면 쉽게 해결 됩니다. 👏
원하는 값을 key value 형태로 입력해서 등록해주시고, 재배포 진행해주세요!
이제 정상적으로 동작할 겁니다 🎉