4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React初心者向け】Vercel v0で問い合わせフォームを作る ~デプロイ編~

Posted at

UI生成AI『v0』

v0はVercel Labs社が開発したウェブデザインに特化した生成AIツールです。
WebサイトやWebアプリはもちろんプレゼン用のスライドや図解資料など様々なものをチャット形式でアシスタントが生成してくれます。

前回生成したものをローカルで開発できるようにしましたが、今回は実際に誰でも動かせるようにデプロイまでしてみたいと思います。

※概ねAIに開発してもらいますが、一部は手作業で修正を行います


今回も前回の続きとして『問い合わせフォーム』を作りたいと思います。

ただ問い合わせフォーム言っても、単に『入力された内容をGmailで送る』というだけでデータベースに内容を保管するとか状態管理するとかはしません。

もちろん今の時代問い合わせフォームはGoogle Formsなど様々なサービスがあるので自分で作る必要などないのですが、v0で作った方が見た目が綺麗ですし

こいつできる…


と思われること間違いなしです。(費用も無料です)

利用するものは
フレームワーク:Next.js
公開(デプロイ)先:Vercel
メールサービス:Gmail(nodemailerを利用)
その他:GitHub Desktop

必要なものは
・GitHubアカウント ・Googleアカウント(要アプリパスワード ※後述)

※実践するPCのOSはWindows11です。

v0を利用する

前回同様まずv0にコードを生成してもらいますが、指示は以下のようにしました。

「お名前」「メールアドレス」「お問い合わせ内容」だけの問い合わせフォームの作成をお願いします。送信ボタンを押した後はNodemailerで内容をメールで送信し、画面を切り替えて"ありがとうございました"とメッセージを表示するようにして下さい。Server Actionsで実装をお願いします。

スクリーンショット 2024-10-19 163335 - コピー - コピー.png


今回は "Server Actionsで" と指定しました。Server Actionsと指定しない場合はサーバ側はAPIを作りfetch(~) で呼び出すことになることが多いようです。

Server ActionsはNext.js v14から正式リリースされたほやほやの新機能です。なのでまだリファレンスが多くないですし、基本から理解したいという方はfetchで呼び出した方がいいかもしれません。今回はコードが少なそうという単純な理由でこちらを選びました。その他の指示はお好みで指定して下さい。

スクリーンショット 2024-10-19 163554.png

クライアント側(contact-form.tsx)とサーバ側(actions.ts)2つのファイルを生成してくれました。クライアント側の方は選択して右上の[Add to Codebase]をクリックしてインストール用コマンドをコピーして下さい。サーバ側はファイルをダウンロードしておいて下さい。(サーバ側もコマンドが使えますが、ただファイルをもってくるだけのようなのでダウンロードしておきました。)

Snapshot_142.PNG

Snapshot_144.PNG

ローカル環境での作業

デプロイ前にこれらを自分のPCで動かせるようにします。前回と一緒のところは説明を省略します。

※PCにはNode.jsをインストールしておいて下さい。(詳細はこちら

Next.js プロジェクト作成
npx create-next-app@latest
カレントディレクトリ移動
cd [作成したフォルダ名]

先ほどコピーしたコマンドをここで使います。

生成したコンポーネントの追加 ※コピーしたコマンドを利用して下さい
npx shadcn@latest add "https://v0.dev/chat/b/b_IYsZY80VYZP?token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..LNFwJsmWN_JWnOO1.-hnAiNrzYDblxYowsVUVBPRB_Fi50_v5uAIL94gbH46xJPPsYmy5k1fE_JQ.mC7s8AwYRuQ1GlLI6vw8eA"

このタイミングでついでにnodemailerもインストールしておきます。

nodemailerインストール
npm i nodemailer
npm i -D @types/nodemailer 

サーバ側となるactions.tsは手動で追加します(ファイルを置くだけです)。プロジェクトフォルダ以下ならどこでもいいですが今回は[プロジェクトフォルダ]下の"src"フォルダに"actions"というフォルダを作成して、そこに置きたいと思います。

src以下構成
src
├─actions ※手動で作成
│  └─actions.ts ※手動で追加
├─app
├─components
│  └─ui
│  └─ContactForm.tsx ※自動で追加されてます
├─hooks
└─lib

ここまできましたら一度立ち上げられるまで修正します。

src/app/page.tsxの修正 ※前回と同様パスなどは変更して下さい
import { ContactFormComponent } from "@/components/contact-form"

export default function Home() {
  return (
    <ContactFormComponent/>
  );
}

ここからは生成結果により異なりますが、ContactForm.tsxからactions.tsアクセスするパスが違っているので修正します。

ContactForm.tsxの修正①

- import { submitForm } from './actions'

+ import { submitForm } from '../actions/actions'

※前回同様、必要であればuse-toastのパスを直してあげます。

ContactForm.tsxの修正② ※前回と同様です

- import { toast } from "@/components/ui/use-toast"

+ import { toast } from "@/hooks/use-toast"


これで一度起動してみます。

開発モードで起動
npm run dev

http://localhost:3000 にアクセスしてエラーなく立ち上がればOKです。

nodemailerでのメール設定

起動までできましたら、メールが送れるようにしたいと思いますのでGoogleのアプリパスワードを取得します。アカウントの2段階認証が必須となっていますのでセキュリティ設定から2段階認証に変更の上、以下で作成して下さい。


取得しましたらプロジェクトフォルダ直下に.env.localファイルを作成してそこに環境変数として設定します。(テキストファイルとして作成し名前を".env.local"にして下さい。)

プロジェクトフォルダ構成
[プロジェクト名]
├─.next
├─node_modules
├─src
├─.env.local ※新規追加
└─.gitignore
… (以下省略)

ほんとはダメらしいですが、今回は簡略化のためここに設定します

.env.localの設定例はこちらです。※変数名は1例で生成したソースよって異なります

.env.local
SMTP_USER = "**********@gmail.com" # 送信元のアドレス
SMTP_PASS = "************" # 取得したアプリパスワード(スペースは消してください)
MAIL_FROM = '"お問い合わせフォーム" <noreply@example.com>'
MAIL_TO = "**********@****.****" # 送信先のアドレス

SMTP_USERが送信元のアドレス(アプリパスワードを取得したアカウント)となり、MAIL_TOが通知先の任意のメールアドレスとなります。
※今回は自身への通知が目的で問い合わせした人にメールを返信する仕様ではありません

MAIL_FROMは送信元になるのですが空白でもSMTP_USERになるので空白でも構いません。
ただこうやって書くとメールBOXで"お問い合わせフォーム"と表示されるので便利かと思います。(noreply@example.comはそのままです。仕組みはわかりません…)

あとはGmailが送れるようにソースの一部を修正します。

actions.ts修正
export async function submitForm(formData: FormData) {
  const name = formData.get('name') as string
  const email = formData.get('email') as string
  const message = formData.get('message') as string
  
  const transporter = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 587,
    auth: {
      user: process.env.SMTP_USER,
      pass: process.env.SMTP_PASS,
    },
  })

  try {
    // メールを送信
    await transporter.sendMail({
      from: process.env.MAIL_FROM,
      to: process.env.MAIL_TO,
      subject: '新しい問い合わせ',
      text: `
        名前: ${name}
        メールアドレス: ${email}
        メッセージ: ${message}
      `,
    })
    (省略)

※長いので一部のみを表示しています。全ソースはこちらからご確認ください。

hostを"smtp.gmail.com"にして、portを587にしました。
あとはもうnodemailerの使い方に従い.env.localの内容を当てはめるだけです。

これでフォームの内容を適当に入れて送信できるかテストしてみて下さい。
意外とあっさりメールが送れるはずです。

Vercelへデプロイ

ではこれをVercelにデプロイ、公開したいと思います。
Vercel以外にもNetlifなどのホスティングサービスがありますが、Vercelで作ったのでVercelに上げるのが筋なような気がしたので、そのままVercelにアップします。

まずは先にGitHubにプッシュします。(VercelがGitHubと連携できる仕組みがあります)
私はGitHub Desktopを利用しますが、日常的にGitを使っている強者の方はコマンドでやっちゃって下さい。(インストールは以下を参考にして下さい。)


GitHub Desktopインストール後にGitHubアカウントでログイン。
そして先ほど作ったNext.jsのプロジェクトを[Add local repository]からリポジトリに追加します。
Snapshot_145.PNG

先ほどのプロジェクトのパスを指定して[Add repository]。
Snapshot_146.PNG

①適当にコメントを入れて②コミット③プッシュします。
Snapshot_147.PNG

名前を設定。リポジトリはプライベート・パブリックどちらでも構いません。
Snapshot_148.PNG

Snapshot_149.PNG

リポジトリが作成されました。ちなみに.env.localはリポジトリに含まれません。.gitignoreに記載されているとプッシュされない仕組みとなっています。


あとはこれをVercelと連携するだけです。Vercelにログイン。新しいプロジェクトを追加します。
Snapshot_150.PNG

GitHubと連携してさ作成したリポジトリを追加します。
Snapshot_151.PNG

Snapshot_152.PNG

名前と環境変数を設定してデプロイ。ここで.env.localに記載していた情報を設定します。
Snapshot_153.PNG

Snapshot_154.PNG

Snapshot_155.PNG

デプロイに少々時間がかかります。何もエラーにならなければ成功です。

Snapshot_156.PNG


プロジェクトページの[Domaine]が公開されるアドレスとなるので誰でもアプリが起動できるようになります。これで問い合わせフォーム完成です!(完成品

Snapshot_157.PNG

Snapshot_158.PNG

修正する場合は[ローカルでコードを変更]→[GitHubにプッシュ]という流れとなります。

※環境変数がうまく設定できてないことがありましたので、その場合プロジェクトページのここから設定して下さい
Snapshot_159.PNG

おわりに

生成したコードで変わってきますので、同じようにして上手く行くか怪しいですがそこまで複雑なコードでもないですので、エラーになりましたらこちらのソースと見比べてみてください。

今回はシンプルすぎる見た目ですが、色々注文すればもっとおしゃれな感じになるかと思います!

補足とたわごと

React入門者の方に補足です。(※偉そうですが私も勉強の身です)

クライアント側(contact-form.tsx)とサーバ側(actions.ts)としてソースが生成されました」と言いましたが、適当なフォルダに配置したファイルなのに何が違うのか?と疑問に持った方もいるかと思います。

この違いは拡張子…ではなく、それぞれの先頭の1行

'use client'
'use server'

によってそれぞれ動作する場所を指示されています。

(ですのでconsole.log(~)で出力した場合もクライアント側はchormeの検証などで確認できますが、サーバー側は検証には出力されず、実行中のコンソールからしか確認できません。)

これだけ?

と思うかもしれません。実際に誤りが起きやすいためサーバーで実行されるはずのコードがクライアントで実行されるセキュリティ上の懸念もあるとされています。

そういう意味ではServer Actionsを使わずサーバー側はGETやPOSTで待ち構えるサーバーサーバーしてるコードの方が誤りは起きにくいのかもしれません。

しかし、Next.jsなどReactフレームワークに入門すると「フルスタック!」「フルスタック!」と煽られるわりにやることはAPIで呼び出すなんとも家庭内別居のような関係でがっかりした記憶もあります。
(※フルスタックはフロントエンドとバックエンドの両方を開発できること)

フルスタックなんだからクライアントとサーバーは同居すべきか。それともセキュリティのため別居すべきか。

という議論がありそうです。

いや無いかもしれませんw。以上たわごとでした。

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?