@@ -100,7 +100,7 @@ <h1 class="post-detail__title">静的サイトにお問い合わせフォーム
100100 < section class ="post-detail__body markdown-body "> < p > こんにちは!パン君です。</ p >
101101< p > このポートフォリオサイトは GitHub Pages でホスティングしている静的なWebサイトです。 </ p >
102102< p > そしてお問い合わせを実装するにはメールに送信するための仕組みがいります。< br > API実装を常駐サーバーでトンネル通信をPlayit.ggを利用して行っていますが、数週間前からトンネルの作成が出来ずに困っています...< br > (公式には連絡したのですが...)</ p >
103- < p > そこで今回は、 < strong > Google Apps Script (GAS)</ strong > を簡易的なバックエンドAPIとして利用し、完全無料でメール送信機能を実装しました。 </ p >
103+ < p > そこで今回は < strong > Google Apps Script (GAS)</ strong > を簡易的なバックエンドAPIとして利用し、完全無料でメール送信機能を実装しました。 </ p >
104104< h2 id ="なぜ-gas-google-apps-script-なのか "> なぜ GAS (Google Apps Script) なのか</ h2 > < p > 静的サイトでフォームを実装する方法はいくつかあります。 </ p >
105105< ol >
106106< li > < strong > Formspree などの外部サービスを使う</ strong > < ul >
@@ -174,9 +174,9 @@ <h3 id="ポイント">ポイント</h3><ul>
174174</ code > </ pre >
175175< p > これを「ウェブアプリ」としてデプロイし、アクセス権限を「全員 (Anyone)」に設定することで、外部から叩ける API URL が発行されます。 </ p >
176176< hr >
177- < h2 id ="フロントエンド実装-javascript "> フロントエンド実装 (JavaScript)</ h2 > < p > 次に、この API を叩くフロントエンド側の処理です。< br > < code > fetch</ code > API を使って非同期送信を行います。</ p >
177+ < h2 id ="フロントエンド実装-javascript "> フロントエンド実装 (JavaScript)</ h2 > < p > 次にこの API を叩くフロントエンド側の処理です。< br > < code > fetch</ code > API を使って非同期送信を行います。</ p >
178178< h3 id ="corsのエラーを回避するコツ "> CORSのエラーを回避するコツ</ h3 > < p > GAS に対して < code > application/json</ code > で POST すると、CORS (Cross-Origin Resource Sharing) のプリフライトリクエスト (OPTIONS) が発生し、GAS がうまく返答できずにエラーになることがあります。</ p >
179- < p > これを回避するために、あえて < code > text/plain</ code > としてデータを送信する方法を採用しました。</ p >
179+ < p > これを回避するためにあえて < code > text/plain</ code > としてデータを送信する方法を採用しました。</ p >
180180< pre > < code class ="language-javascript "> const GAS_API_URL = "https://script.google.com/macros/s/xxxx/exec";
181181
182182form.addEventListener("submit", async (e) => {
@@ -208,19 +208,19 @@ <h3 id="corsのエラーを回避するコツ">CORSのエラーを回避する
208208</ code > </ pre >
209209< p > GAS側では < code > JSON.parse(e.postData.contents)</ code > で受け取ることで、問題なく JSON として扱えます。</ p >
210210< hr >
211- < h2 id ="デザインの調整 "> デザインの調整</ h2 > < p > 機能だけでなく、見た目もサイトのトーン &マナーに合わせました。</ p >
211+ < h2 id ="デザインの調整 "> デザインの調整</ h2 > < p > 機能だけでなく見た目もサイトのトーン &マナーに合わせました。</ p >
212212< ul >
213213< li > 必須項目のバッジ表示</ li >
214214< li > 送信ボタンのローディングアニメーション</ li >
215215< li > スマホでの入力しやすさ(< code > input type="email"</ code > や < code > type="tel"</ code > の活用)</ li >
216216</ ul >
217- < p > 特に送信ボタンは、押した後に 「送信中...」であることが視覚的に分かるように、CSSアニメーションでスピナーを表示するようにしました。ユーザーが何度も連打してしまうのを防ぐ効果もあります。</ p >
218- < h2 id ="まとめ "> まとめ</ h2 > < p > サーバーレスな環境でも、 GAS を組み合わせることで本格的なお問い合わせフォームが実装できました。</ p >
217+ < p > 特に送信ボタンは押した後に 「送信中...」であることが視覚的に分かるように、CSSアニメーションでスピナーを表示するようにしました。< br > ユーザーが何度も連打してしまうのを防ぐ効果もあります。</ p >
218+ < h2 id ="まとめ "> まとめ</ h2 > < p > サーバーレスな環境でも GAS を組み合わせることで本格的なお問い合わせフォームが実装できました。</ p >
219219< ul >
220220< li > < strong > GAS</ strong > は無料かつ手軽なバックエンドとして優秀。</ li >
221221< li > < code > fetch</ code > の < code > Content-Type</ code > を工夫することで CORS 問題を回避できる。</ li >
222222</ ul >
223- < p > これで、ポートフォリオサイトから直接お仕事の相談を受け付ける準備が整いました !</ p >
223+ < p > これでポートフォリオサイトから直接お仕事の相談を受け付ける準備が整いました !</ p >
224224</ section >
225225 < div class ="share-buttons ">
226226 < p class ="share-buttons__title "> SHARE</ p >
0 commit comments