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で実装をお願いします。
今回は "Server Actionsで" と指定しました。Server Actionsと指定しない場合はサーバ側はAPIを作りfetch(~) で呼び出すことになることが多いようです。
Server ActionsはNext.js v14から正式リリースされたほやほやの新機能です。なのでまだリファレンスが多くないですし、基本から理解したいという方はfetchで呼び出した方がいいかもしれません。今回はコードが少なそうという単純な理由でこちらを選びました。その他の指示はお好みで指定して下さい。
クライアント側(contact-form.tsx)とサーバ側(actions.ts)2つのファイルを生成してくれました。クライアント側の方は選択して右上の[Add to Codebase]をクリックしてインストール用コマンドをコピーして下さい。サーバ側はファイルをダウンロードしておいて下さい。(サーバ側もコマンドが使えますが、ただファイルをもってくるだけのようなのでダウンロードしておきました。)
ローカル環境での作業
デプロイ前にこれらを自分のPCで動かせるようにします。前回と一緒のところは説明を省略します。
※PCにはNode.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もインストールしておきます。
npm i nodemailer
npm i -D @types/nodemailer
サーバ側となるactions.tsは手動で追加します(ファイルを置くだけです)。プロジェクトフォルダ以下ならどこでもいいですが今回は[プロジェクトフォルダ]下の"src"フォルダに"actions"というフォルダを作成して、そこに置きたいと思います。
src
├─actions ※手動で作成
│ └─actions.ts ※手動で追加
├─app
├─components
│ └─ui
│ └─ContactForm.tsx ※自動で追加されてます
├─hooks
└─lib
ここまできましたら一度立ち上げられるまで修正します。
import { ContactFormComponent } from "@/components/contact-form"
export default function Home() {
return (
<ContactFormComponent/>
);
}
ここからは生成結果により異なりますが、ContactForm.tsxからactions.tsアクセスするパスが違っているので修正します。
- import { submitForm } from './actions'
+ import { submitForm } from '../actions/actions'
※前回同様、必要であればuse-toastのパスを直してあげます。
- 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例で生成したソースよって異なります
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が送れるようにソースの一部を修正します。
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]からリポジトリに追加します。
先ほどのプロジェクトのパスを指定して[Add repository]。
名前を設定。リポジトリはプライベート・パブリックどちらでも構いません。
リポジトリが作成されました。ちなみに.env.localはリポジトリに含まれません。.gitignoreに記載されているとプッシュされない仕組みとなっています。
あとはこれをVercelと連携するだけです。Vercelにログイン。新しいプロジェクトを追加します。
名前と環境変数を設定してデプロイ。ここで.env.localに記載していた情報を設定します。
デプロイに少々時間がかかります。何もエラーにならなければ成功です。
プロジェクトページの[Domaine]が公開されるアドレスとなるので誰でもアプリが起動できるようになります。これで問い合わせフォーム完成です!(完成品)
修正する場合は[ローカルでコードを変更]→[GitHubにプッシュ]という流れとなります。
※環境変数がうまく設定できてないことがありましたので、その場合プロジェクトページのここから設定して下さい
おわりに
生成したコードで変わってきますので、同じようにして上手く行くか怪しいですがそこまで複雑なコードでもないですので、エラーになりましたらこちらのソースと見比べてみてください。
今回はシンプルすぎる見た目ですが、色々注文すればもっとおしゃれな感じになるかと思います!
補足とたわごと
React入門者の方に補足です。(※偉そうですが私も勉強の身です)
「クライアント側(contact-form.tsx)とサーバ側(actions.ts)としてソースが生成されました」と言いましたが、適当なフォルダに配置したファイルなのに何が違うのか?と疑問に持った方もいるかと思います。
この違いは拡張子…ではなく、それぞれの先頭の1行
'use client'
'use server'
によってそれぞれ動作する場所を指示されています。
(ですのでconsole.log(~)で出力した場合もクライアント側はchormeの検証などで確認できますが、サーバー側は検証には出力されず、実行中のコンソールからしか確認できません。)
これだけ?
と思うかもしれません。実際に誤りが起きやすいためサーバーで実行されるはずのコードがクライアントで実行されるセキュリティ上の懸念もあるとされています。
そういう意味ではServer Actionsを使わずサーバー側はGETやPOSTで待ち構えるサーバーサーバーしてるコードの方が誤りは起きにくいのかもしれません。
しかし、Next.jsなどReactフレームワークに入門すると「フルスタック!」「フルスタック!」と煽られるわりにやることはAPIで呼び出すなんとも家庭内別居のような関係でがっかりした記憶もあります。
(※フルスタックはフロントエンドとバックエンドの両方を開発できること)
フルスタックなんだからクライアントとサーバーは同居すべきか。それともセキュリティのため別居すべきか。
という議論がありそうです。
いや無いかもしれませんw。以上たわごとでした。