Next.jsだけでお問い合わせフォームを作る方法を解説
2023.12.232024.5.10
この記事は約3分で読めます
この記事の筆者:三好アキ
🔹 専門用語なしでプログラミングを教えるメソッドに定評があり、1200人以上のビギナーを、最新のフロントエンド開発入門に成功させる。
🔹 Amazonベストセラー1位を複数回獲得している『はじめてつくるReactアプリ with TypeScript』著者。
Amazon著者ページはこちら → amazon.co.jp/stores/author/B099Z51QF2
React、Next.js、TypeScriptなどのお役立ち情報や実践的コンテンツを、ビギナー向けにかみ砕いて無料配信中。登録はこちらから → 無料メルマガ登録
作業の流れ
本記事では、Next.jsをフロントエンドとバックエンドに使ってお問い合わせ機能を作ります。
AppフォルダとPagesフォルダ、両方のコードを紹介するので参考にしてください。
作業は以下の流れで進みます。
1 ― Next.jsをインストール
2 ― フロントエンドに「お問い合わせページ」を作成
3 ― バックエンドのapi
フォルダに、「お問い合わせページ」からPOSTリクエストを受ける機能を作成
お問合せがあったことをメールで知るために、Nodemailerというパッケージを使用します。
(*本記事ではNext.jsバージョン13で導入されたAppフォルダを使って解説を進めますが、以前使われていたPagesフォルダでも同じ流れでお問合せ機能を開発できるので、その互換性を重視して、サーバーコンポーネントとServer Actionsは使いません。)
Next.jsでつくるフルスタックアプリ
【最新バージョンのNext.jsとAppフォルダで、フルスタックアプリを自力で作る力を手にいれる】
1980円 → 0円
Next.jsのインストール
まずNext.jsの新しいプロジェクトを用意しましょう。
npx create-next-app example-site
インストール時に出てくる質問については、下から2つ目のAppフォルダに関するもの以外はすべてNo
を選びます。
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? › No / Yes
Next.jsをVSコードで開きましょう。
本記事ではCSSのスタイル関係には触れませんが、globals.css
のコードがやや邪魔になるので、globals.css
のコードはすべて消しておいてください。
お問い合わせページ作り(フロントエンド)
フロントエンド側にお問い合わせページを作りましょう。
app
フォルダ内にcontact
フォルダを作り、その中にpage.js
ファイルを作ってください。
そこに次のコードを打ちます。なおPagesフォルダを使っている場合は、1行目のuse client
は不要です。
// app/contact/page.js
"use client"
const Contact = () => {
return (
<div>
<h1>コンタクト</h1>
<form>
<input type="text" placeholder="お名前" required/>
<input type="text" placeholder="メールアドレス" required/>
<textarea type="text" placeholder="メッセージ" rows="10" required></textarea>
<button type="submit">送信</button>
</form>
</div>
)
}
export default Contact
保存してnpm run dev
でNext.jsを起動し、http://localhost:3000/contact
を開くと、次のように表示されます。
次は、データをバックエンドに投稿するコードを追加しましょう。現時点ではまだバックエンドがないので、fetch()
のURLはxxx
としています。
// app/contact/page.js
"use client"
import { useState } from "react"
const Contact = () => {
const [name, setName] = useState("")
const [email, setEmail] = useState("")
const [message, setMessage] = useState("")
const handleSubmit = async(e) => {
e.preventDefault()
try{
const response = await fetch("xxx", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
name: name,
email: email,
message: message
})
})
const jsonData = await response.json()
alert("メッセージを送信しました")
}catch(err){
alert("メッセージの送信が失敗しました")
}
}
return (
<div>
<h1>コンタクト</h1>
<form onSubmit={handleSubmit}>
<input value={name} onChange={(e) => setName(e.target.value)} type="text" placeholder="お名前" required/>
<input value={email} onChange={(e) => setEmail(e.target.value)} type="text" placeholder="メールアドレス" required/>
<textarea value={message} onChange={(e) => setMessage(e.target.value)} type="text" placeholder="メッセージ" rows="10" required></textarea>
<button type="submit">送信</button>
</form>
</div>
)
}
export default Contact
ユーザーがメッセージを入力するフロントエンド側のページができたので、次はここから問い合わせを受け付けるバックエンド機能を作ります。
問い合わせを受け付ける機能の開発(バックエンド)
app
フォルダ内にapi
フォルダを作り、その中にフォルダcontact-handler
、さらにその中にファイルroute.js
を作りましょう。
ここにフロントエンドからのデータ(=メッセージ)を受け付けるコードを書きますが、その前にまず必要なパッケージをインストールしましょう。
npm install nodemailer
そこに次のコードを打ちます。
注意してもらいたいのはtransporter
に入力するSMTP関連のデータで、これはOutlookやZohoなど各自のメールアカウントから持ってきてください(OutlookのSMTPデータ)。なおGmailは、Vercelにデプロイしたあと、意図通りに動かないことがあります。
// app/api/contact-handler/route.js
import { NextResponse } from "next/server"
import nodeMailer from "nodemailer"
export async function POST(request) {
const reqBody = await request.json()
const { email, name, message } = reqBody
try{
const transporter = nodeMailer.createTransport({
host: "smtp-mail.outlook.com", // メールサーバー。ここではHotmail/Outlookを使った例
port: 587,
secure: false,
auth: {
user: "my-email@hotmail.co.jp", // メールアドレス
pass: "my-password" // パスワード
}
})
const mailOptions = {
from: "My website",
to: "receive-email@gmail.com",
subject: "Next.jsコンタクトページ",
text: `名前: ${name} \n\nメールアドレス: ${email} \n\nメッセージ: ${message}`
}
const info = await transporter.sendMail(mailOptions)
return NextResponse.json({message: "成功しました"})
}catch(err){
return NextResponse.json({message: "失敗しました"})
}
}
もしPagesフォルダを使っている場合は、pages
フォルダ内にapi
フォルダ、その中にcontact-handler.js
ファイルを作り、次のコードを打ちます。
// pages/api/contact-handler.js
import nodeMailer from "nodemailer"
export default function contactHandler(req, res){
if (req.method === "POST") {
const { email, name, message } = req.body
const transporter = nodeMailer.createTransport({
host: "smtp-mail.outlook.com", // メールサーバー。ここではHotmail/Outlookを使った例
port: 587,
secure: false,
auth: {
user: "my-email@hotmail.co.jp", // メールアドレス
pass: "my-password" // パスワード
}
})
const mailOptions = {
from: "My website",
to: "receive-email@gmail.com",
subject: "Next.jsコンタクトページ",
text: `名前: ${name} \n\nメールアドレス: ${email} \n\nメッセージ: ${message}`
}
transporter.sendMail(mailOptions, (err, info) => {
if(err){
return res.json({message: "失敗しました"})
}else{
return res.json({message: "成功しました"})
}
})
}
}
これでバックエンド側の機能は完成です。
最後にフロントエンド側のfetch()
のURLを修正しましょう。
// app/contact/page.js
const response = await fetch("http://localhost:3000/api/contact-handler", {....
なおデプロイする場合には、http://localhost:3000
をデプロイ後の公開URLに変更することを忘れないようにしましょう。
Next.jsでつくるフルスタックアプリ
【最新バージョンのNext.jsとAppフォルダで、フルスタックアプリを自力で作る力を手にいれる】
1980円 → 0円
メルマガ配信中
(from 三好アキ/エンジニア)
React、Next.js、TypeScriptなど最新のウェブ開発のお役立ち情報を、ビギナー向けにかみ砕いて無料配信中。
(*配信はいつでも停止できます)