0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js】Resendでメール送信

Last updated at Posted at 2025-05-18

Resendとは

Resendは、開発者がアプリケーションから
メールを簡単に送信できるようにするためのメールAPIサービスで、
シンプルな実装でメール送信機能を実装できます。

Resendの環境構築

  1. アカウント作成とセットアップ
    Resendでアカウント作成を行い、APIキーを取得する
  • API Keysを選択
    スクリーンショット 2025-05-18 17.31.04.png
  • Create API Keyを押下
    スクリーンショット 2025-05-18 17.31.20.png
  • nameを記入してAddを押下
    スクリーンショット 2025-05-18 17.34.14.png
  • 生成されたAPIKeyをコピーしてDoneを押下
    ※こちらで必ずコピーして環境変数に設定するかローカルに保存しておくこと。
    スクリーンショット 2025-05-18 17.37.59.png
  1. パッケージインストール
    npm install resend
  2. 環境変数に1.で生成したAPIキーを設定
    RESEND_API_KEY=
  3. 実装例

メール送信用フォーム

MailForm.tsx
import React, { useState } from 'react'

const SimpleMailForm = () => {
  const [email, setEmail] = useState('')
  const [subject, setSubject] = useState('')
  const [content, setContent] = useState('')
  const [message, setMessage] = useState('')
  const [imageFile, setImageFile] = useState(null);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setMessage('')
    
    const formData = new FormData()
    formData.append('email', email)
    formData.append('subject', subject)
    formData.append('content', content)
    
    if (imageFile) formData.append('imageFile', imageFile)
    
    const res = await fetch(`${process.env.NEXT_PUBLIC_BASE}/api/send`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: formData,
    })
    if (res.ok) {
      setMessage('送信しました')
      setEmail('')
      setSubject('')
      setContent('')
    } else {
      setMessage('送信に失敗しました')
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>メールアドレス</label>
        <input value={email} onChange={e => setEmail(e.target.value)} required />
      </div>
      <div>
        <label>件名</label>
        <input value={subject} onChange={e => setSubject(e.target.value)} required />
      </div>
      <div>
        <label>本文</label>
        <textarea value={content} onChange={e => setContent(e.target.value)} required />
      </div>
      <div>
        <label>画像ファイル</label>
        <input
          type="file"
          accept="image/*"
          onChange={e => setImageFile(e.target.files[0])}
        />
  </div>
      <button type="submit">送信</button>
      <div>{message}</div>
    </form>
  )
}

export default SimpleMailForm

メール送信用API

/api/send/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { Resend } from 'resend'

const resend = new Resend(process.env.RESEND_API_KEY)

export async function POST(req: NextRequest) {
  const formData = await req.formData()
  const email = formData.get('email') as string
  const subject = formData.get('subject') as string
  const content = formData.get('content') as string
  const imageFile = formData.get('imageFile') as File | null

  let attachments = []
  if (imageFile) {
    const arrayBuffer = await imageFile.arrayBuffer()
    const buffer = Buffer.from(arrayBuffer)
    attachments.push({ filename: imageFile.name, content: buffer })
  }

  try {
    const data = await resend.emails.send({
      from: 'Acme <onboarding@resend.dev>',
      to: email,
      subject,
      html: `<p>${content}</p>`,
      attachments
    })
    return NextResponse.json({ success: true, data })
  } catch (error) {
    return NextResponse.json({ success: false, error: String(error) }, { status: 500 })
  }
}

注意点として、送信先のメールアドレスは
Resendアカウントのメールアドレスしか送信できません。
任意のメールアドレスを指定して送信したい場合は、
独自ドメインの設定が必要となります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?