📌

gatsby.js + netlifyでお問い合わせフォーム付きの静的サイトを作ってみた

2021/07/18に公開

はじめに

先日、gatsby.js+netlifyで静的サイトを公開しました。
https://otaka-no-kaze.work/

まだまだ初学者ですが、公開まで意外とサクサク進んだので以下を備忘録として書き残します。

  • gatsby-starter-defaultのインストール
  • emotionの導入(CSS-in-JS)
  • netlifyを使ったホスティング
  • お問い合わせフォームの導入

gatsby-starter-defaultのインストール

事前にnodeのバージョンが11.10以上であることを確認します。
その後gatsbyをグローバルインストールします。

npm install -g gatsby-cli

今回はNetlifyを使ってホスティングすることを前提にしているので、Githubに適当なリポジトリを作ります。

cloneしてきたら、以下のコマンドを叩いてgatsby-starter-defaultをインストールします。

gatsby new gatsby-site

インストール完了後はディレクトリを移動してコマンドを叩けばhttp://localhost:8000でページの表示が確認できます。

cd gatsby-site
gatsby develop

インストールできたら後はガシガシ実装しましょう。

emotionの導入(CSS-in-JS)

gatsby(react)はcssを色々な書き方で実装できるのですが、今回はemotionを導入してみました。

npm install gatsby-plugin-emotion @emotion/react

使用例

import * as React from "react"
import {css} from "@emotion/react"

const Index = () => {
 return(
  <p css={title}>Hello Gatsby!</p>
 )
}

const title = css({
 fontSize:'20px',
 color:'red'
})
// プロパティはキャメルケースで書く

export default Index

記述した変数名はコンパイル後に変数をランダムな文字列に変換してくれるので、CSSの命名規則を考えなくて良いのが最高ですね。

コンパイル後
<p class="css-92na9r">Hello Gatsby!</p>

emotionを使うメリットについては下記がわかりやすいです。
https://qiita.com/Sotq_17/items/91760691081db50b1f03

netlifyを使ったホスティング

サイトの構築が終わったらnetlifyを使ってサイトを公開します。

netlifyにアカウントを作ります。
※GitHubと連携するのでGitHubでアカウントを作った方が後々便利です。

New Site from Gitをクリックします。

Continuous DeploymentからGitHubを選択します

アカウント連携後、netlify上にGitHubのリポジトリが表示されるので、対象リポジトリを選択します。

公開設定

以下を設定します。

  • デプロイ用のブランチ
    • master
  • デプロイ時に実行するコマンド
    • npm run build
  • 公開するディレクトリ
    • public

デプロイ

公開設定が終わったら、Deploy Siteをクリックします。
クリックした跡はデプロイ作業が始まり、上記で設定した内容が実行されます。

デプロイ処理中は、以下のようにSite deploy in progressと表示されます。

デプロイ完了後は下記のように表示され公開したサイトを閲覧することができます。

数分でサイトが公開できてインターネット強いなと思います。

独自ドメイン設定

先日公開したサイトはお名前.comでドメインを取得したのですが、ドメイン設定も簡単です。
参考に記載した記事が親切なのでそちらをご覧ください。

参考

https://note.com/koushikagawa/n/n407cde93bdca

お問い合わせフォームの設定

gatsbyとnetlifyを組み合わせれば、簡易なお問い合わせフォームも実装することが可能です。
専用のプラグインがあるので、インストールします。

npm install gatsby-plugin-netlify

お問い合わせフォーム用のコンポーネントを作成します。

import React, { useState } from "react";
import { navigate } from "gatsby-link";
import { makeStyles, TextField, Button } from "@material-ui/core";

const useStyles = makeStyles(() => ({
  root: {
    "& > *": {
      marginBottom: "15px",
      width: "100%",
    },
  },
}));

const encode = (data) => {
  return Object.keys(data)
    .map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
    .join("&");
};

const Form = () => {
  const classes = useStyles();

  const [state, setState] = useState({});

  const handleChange = (e) => {
    setState({ ...state, [e.target.name]: e.target.value });
    console.log(setState)
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const form = e.target;
    fetch("/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: encode({
        "form-name": form.getAttribute("name"),
        ...state,
      }),
    })
      .then(() => navigate(form.getAttribute("action")))
      .catch((error) => alert(error));
  };

  return (
    <form
      name="contact"
      method="post"
      action="/thanks"
      className={classes.root}
      data-netlify="true"
      data-netlify-honeypot="bot-field"
      onSubmit={handleSubmit}
    >
      <input type="hidden" name="form-name" value="contact" />
      <label hidden>
        {" "}
        <input name="bot-field" onChange={handleChange} />
      </label>

      <TextField
        type="text"
        label="お名前"
        variant="outlined"
        name="name"
        onChange={handleChange}
        required
      />

      <TextField
        type="email"
        label="メールアドレス"
        variant="outlined"
        name="email"
        onChange={handleChange}
        required
      />

      <TextField
        name="message"
        label="本文"
        multiline
        rows={4}
        variant="outlined"
        onChange={handleChange}
        required
      />

      <Button type="submit" variant="contained" size="large" color="primary">
        送信する
      </Button>
    </form>
  );
};

export default Form;

後は作ったコンポーネントを設置したい箇所に配置しデプロイすればフロント側の実装は終了です。

管理画面で確認するとnameに設定したものが反映されています。

スパムメールの振り分けや、メール・slack通知もnetlify側で設定することができるので、
個人レベルで運用するサイトであれば、十分な機能が備わっています。

参考

material ui

https://qiita.com/h-yoshikawa44/items/efa33101b0a02cba7759

netlify formのドキュメント

https://www.netlify.com/blog/2017/07/20/how-to-integrate-netlifys-form-handling-in-a-react-app/

まとめ

はじめてのSSG実装でしたが、ドキュメントが充実しているので初学者レベルでもサイトを公開することができました。
今後も様々なことにチャレンジしたいです。

Discussion