1年の終わりにNetlifyのアドオンを試す

この記事は 2018年[Shinjuku.LT Advent Calendar 2018](https://qiita.com/advent-calendar/2018/shinjukult)の9日目の記事です。
Shinjuku.LTは**世界で一番LTのハードルが低い勉強会を目的に開催している勉強会**です。詳しくは[こちら](https://shinjukult.netlify.com/)！

## はじめに

[2日目の記事](https://qiita.com/mnuma/items/15f2e8a5f34a392bc604) ではNetlifyでのWebサイト公開やカスタマイズについて紹介させて頂きました。
Netlifyにはそれ以外にもアドオンとして、AWS Lambdaを提供する**[Functions](https://www.netlify.com/docs/functions/)**や認証機能を提供する**[Identity](https://www.netlify.com/docs/identity/)**、フォーム処理を提供する **[Forms](https://www.netlify.com/docs/form-handling/)** などの機能があります。前々から触ってみたかったのですがなかなか機会がなく今回アドベントカレンダーということでようやく触ってみたので、それについてご紹介させて頂きます！

<img src=https://i.imgur.com/NdFYeAb.png width=100%>

## Functions

[Netlify Functions](https://www.netlify.com/docs/functions/)はNetlifyを使って簡単にAWS Lambdaを使える機能です。

- AWSアカウント無しでLambdaの機能を使えることが出来ます
- Webホスティングの機能と同様にプレビュー機能が使えます

### Free planと料金体系

Functionの利用状況の画面です。

- Free Planでは毎月、**実行回数125,000回**、**実行時間100時間**まで無料
- Pro Planにすると、毎月$25となりますが**2,000,000回**、**1000時間**まで使えるようになるようです

<img src=https://i.imgur.com/fnzBGpb.png width=60%>

> Your plan will upgrade automatically to fit your usage.

ただしFunctionでは使用量が増えるにつれて自動的にプランが変更されるようです。
詳しい料金体系は[こちら](https://www.netlify.com/pricing/)！

### Functionsを試してみる

[Netlify Functions Examples](https://functions-playground.netlify.com/) というデモサイトにサンプルが案内されているので、こちらを試すのが早そうです。

<img src=https://i.imgur.com/ZGpHpOh.png width=80%>

こちらを進めると、`netlify-functions-example` というリポジトリが自動で作成されて、Netlify上でデプロイされます。
簡単にソースコードを見てみましょう。ちなみに本家のリポジトリはこちらにあります。
https://github.com/netlify/netlify-functions-example/blob/master/src/lambda/hello.js

```js
exports.handler = function(event, context, callback) {
  callback(null, {
    statusCode: 200,
    body: "Hello, World"
  });
};
```

そのまんまAWS Lambdaでの実行コードですね。
[Node.js の AWS Lambda 関数ハンドラ - AWS Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-prog-model-handler.html)

ちなみに、呼び出しは以下のようなURLになります。

```
https://{site-name}.netlify.com/.netlify/functions/hello
```

### netlify.tomlによる設定

`Settings > Functions` にある`Functions directory` で関数ファイルのあるディレクトリの指定が出来ます。

![](https://i.imgur.com/s7hzkt7.png)

この設定は`netlify.toml`という設定ファイルでも可能で、サンプルでは`functions`という項目で設定されていました。

```toml
[build]
  command = "yarn build"
  publish = "dist/client"
  functions = "dist/server"
```

こちらのリンクからデモサイトが確認できます！ <a href="https://functions-playground.netlify.com/.netlify/functions/hello">Say hello!</a>

### 環境変数の設定

`Settings > Build & deploy > Build environment variables
` から環境変数の設定も可能で、ビルド時の埋め込みも可能です。

![](https://i.imgur.com/ybyb78q.png)


## Identity

こちらもまた手軽にNetlifyの認証機能をサイトにつけることが出来るものです。


### Identityを試してみる

こちらもまたデモサイトがあるので確認してみましょう。
https://identity.netlify.com/


サンプルコードはこちらです。
https://github.com/netlify/netlify-identity-widget#usage
導入は非常にシンプルでNetlifyから提供されている、`Auth widget`を設置することで利用出来ます。


### 認証ウィジェットの導入

まずはじめに、サイト内に以下を埋め込みます。


```html
<!-- include the widget -->
<script type="text/javascript" src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
```

設置出来るウィジェットは2種類あります。
1つは`Log in/Log out`の表示切り替えが行われる、ボタンだけを表示するウィジェット。


```html
<!-- Add a simpler button: Simple button that will open the modal. -->
<div data-netlify-identity-button>Login with Netlify Identity</div>
```

![](https://i.imgur.com/6uURlNS.png)

![](https://i.imgur.com/5hlo0dq.png)


`Log in/Log out`の表示が切り替わるボタンと、サインアップ用のボタンが`Sign up/メールアドレス` で切り替わる2つのボタンが自動で設置されるものの2つです。


```html
<!-- Add a menu:
   Log in / Sign up - when the user is not logged in
   Username / Log out - when the user is logged in
  -->
<div data-netlify-identity-menu></div>
```

![](https://i.imgur.com/mLTVyug.png)

![](https://i.imgur.com/Na1qIcQ.png)


### 認証とユーザ管理

これらのウィジェットを埋め込んで、Netlify上でデプロイすると勝手に`Netlify Identity`との連携が行われ、メール認証型でユーザ登録/ログインが可能になります。

![](https://i.imgur.com/G7Kwmd7.png)

Netlify Identity側では以下の様にユーザ管理されます。
![](https://i.imgur.com/af9FOxK.png)

### イベントのバインド

読み込まれたウィジェットは自動的にWindowオブジェクトに　`window.netlifyIdentity`としてアタッチされます。各種イベントは以下のようにバインドすることが可能です。

```js
// Bind to events
netlifyIdentity.on('init', user => console.log('init', user));
netlifyIdentity.on('login', user => console.log('login', user));
netlifyIdentity.on('logout', () => console.log('Logged out'));
netlifyIdentity.on('error', err => console.error('Error', err));
netlifyIdentity.on('open', () => console.log('Widget opened'));
netlifyIdentity.on('close', () => console.log('Widget closed'));
```

### ローカル環境での開発

ちなみに、ローカル環境で開発する時は初期表示で以下のようになり、自分のNetlifyのサイトURLを渡すと直接連携ができる仕組みになっています。

![](https://i.imgur.com/AIoM8uL.png)


## Forms

最後にFormsについて簡単に紹介します。
`Netlify Forms`はフォームを簡単に作ってNetlifyの管理画面上で簡単に確認できるような仕組みです。簡易的なお問い合わせフォームやアンケート機能に活用できそうです。


### Netlify Formsの導入

`<form>`タグに`netlify`属性を追加すると、Netlifyのフォーム処理に送信されるという仕組みです。
このような一般的な送信フォームを記述して、Netlify上にデプロイすると自動的にNetlify Formに連携されるようになります。


```html
<form name="contact" method="POST" netlify>
  <p>
    <label>お名前: <input type="text" name="name" /></label>   
  </p>
  <p>
    <label>メールアドレス: <input type="email" name="email" /></label>
  </p>
  <p>
    <label>年齢: <select name="age[]" multiple>
      <option value="teens">10代</option>
      <option value="twenties">20代</option>
      <option value="thirties">30代</option>
    </select></label>
  </p>
  <p>
    <label>メッセージ: <textarea name="message"></textarea></label>
  </p>
  <p>
    <button type="submit">Send</button>
  </p>
</form>
```

例えば、このようなフォーム画面を作成し、ポストします。

<img src=https://i.imgur.com/bQlJLL1.png width=30%>


すると、Netlify側の管理画面ではこのように確認出来ます。

<img src=https://i.imgur.com/45qMBi0.png width=80%>

### 通知の連携

Netlify Formsは地味ながら実用的な仕組みであり、[ドキュメント](https://www.netlify.com/docs/form-handling/) に色々な機能が紹介されています。気になったところでは[Zapier](http://zapier.com/)と連携したフック設定が紹介されいます。

<img src=https://i.imgur.com/ZziqMgN.png width=70%>

## まとめ

はじめてNetlifyを試した時、シンプルな操作性とスムーズなワークフローにとても感動しました。
Netlifyは「[JAMstack](https://jamstack.org/)」というコンセプトを提唱している会社でもあり、これらのサービスはJAMstackなアーキテクチャを実現するためのとても強力なツールになっていくと思いました。

今回は、[Shinjuku.LT](https://shinjukult.netlify.com/)のサイトで使っている 高機能ホスティングサービスNetlifyとそのアドオン機能について紹介させて頂きました。
[Shinjuku.LT Advent Calendar 2018](https://qiita.com/advent-calendar/2018/shinjukult)最後までがんばりましょう。よろしくお願いします！