microCMS + Vercel カスタムフックを設定しよう

実はめるろって氏、ホームページがあります。ご存知でしたか?笑

www.meru-lotte.com

以前こちらの記事で、構成を説明した時、Netlifyを利用していたのですが、
管理ページやデプロイが重くてVercelに乗り換えました。

kuroneko22.hatenablog.com

今回タイトルにある「カスタムフック」ですが、
microCMSではコンテンツを作成・更新・削除した場合など、
特定のタイミングでビルドを走らせることができます。

逆にいうと、私のポートフォリオサイトはSSGなので、
記事を更新しただけでは、サイトには反映されず、
一度サーバー側でビルドを行う必要がありました。

結果、何が起こるかというと、
更新頻度が下がる...(これだけが理由ではないですが。)

なので、もっと快適にポートフォリオを更新できるように、カスタムフックを利用してみました。


変更前の画面

最新は左上です。ここに「新人魔女の初仕事」という作品を追加します。

f:id:canopy-4160:20210510141148p:plain

microCMSの設定

右上の「APIの設定」から「Webhook」を選択
f:id:canopy-4160:20210510141210p:plain

「追加」を押すとこんな画面になります。
... Netlifyはあるんですよね。
f:id:canopy-4160:20210510141220p:plain
今回は「カスタム通知」を使用します。

こんな画面になるので、追加するだけ...なのですが、

f:id:canopy-4160:20210510141226p:plain

任意のURLに対してAPIやコンテンツの更新をPOSTリクエストで通知します。

こちらのURLは、Vercel側で発行する必要があります。
やっていきましょう。

VercelでのDeploy Hooksの発行

Vercelの画面から Settings > Git > Deploy Hooks で以下の画面にたどり着きます。

f:id:canopy-4160:20210510141248p:plain

  1. My Example Hook (今回は art hookにしました。自由につけてOK)
  2. main(どのブランチをビルドするかなので、基本mainでOK)
  3. Create Hookを押下
  4. アドレスが発行されます(※このアドレスは外部に漏れないように注意してください。不審なビルドがあったら再発行しましょう。)

こんな感じで、アドレスが発行されたら先程のmicroCMSの画面に入力して「設定」ボタンを押してください。

わくわくビルドタイム

うまく設定できたか試してみます。

f:id:canopy-4160:20210510141158p:plain

絵を追加しました。記事を公開。

Vercelへ f:id:canopy-4160:20210510141153p:plain ちゃんとビルドが始まってますね!やった〜〜。

f:id:canopy-4160:20210510141232p:plain ビルドもちゃんと完了。

サイトに反映されたか確認 f:id:canopy-4160:20210510141236p:plain されてますね💮

追加された作品気になる方は、ぜひサイトにアクセスしてみてください〜

www.meru-lotte.com


というわけで、microCMSでカスタムフックを設定する方法を紹介しました。
と〜〜〜っても簡単なので、ここで躓く方も少ないかもしれませんが、
どこかで少しでもお役に立てればと思います。

最後まで読んでいただき、ありがとうございました〜mm

イラスト制作環境が整いました

2月末で前職を退職し、フリーランスイラストレーターとして活動を開始しました。(並行してエンジニアのお仕事もしています。)

今までの環境

ipad

f:id:canopy-4160:20210329103802j:plain:w550
作業環境

はい、よくないですね。

ipadなのは全然良いのですが、
首への負担、肩こり、もろもろ姿勢が悪すぎました。

完成

f:id:canopy-4160:20210329104710j:plain:w350
作業環境

(もうちょっと映える写真なかったの...🤔)

液タブ

購入した液タブはこちらです。


HUIONの液晶タブレット
Kamvas 16 (2021) 15.6インチ
Full HDなので普段4Kなどに目が慣れてしまっている方には
少し画面の滲みが気になるかなと思います。
それでも、液晶タブレットがこの値段で...と思うと良い世の中になりましたね。
視差も少なく、画面の端で線画ずれたりすることもなく、これからも長く愛用していけそうです。

スタンド

ちなみに、HUIONさんのKamvas16(2021)はamazonでは4つ展開があり、
それぞれ、

  • スタンドなし、PCとの接続3in1
  • スタンドあり、PCとの接続3in1
  • スタンドなし、PCとの接続USB Type-C to Type-C
  • スタンドあり、PCとの接続USB Type-C to Type-C

となっています。


私はもともとこちらを持っていたので、
スタンドなし、PCとの接続USB Type-C to Type-Cを選択しました。
こちらのスタンドも、一時期Twitterで話題になっていましたが、
めちゃくちゃ硬いので少し体重かけたくらいでは位置変わりません。
すごく重宝しています。

照明

もともと部屋の照明がそんなに明るい部屋ではないのと、
部屋の少し奥まったとこになるのとで、
夕方以降はすごく暗くて作業がしにくくなるんですよね。
ということで

これ、可愛くないですか?? 3000円なんですよ?!IKEA産です。

イス

このカウンター高さが90cmなんですが、通常のカウンターチェアだと高さが合わないんですよね。

大体椅子の座面から机までが25〜30cmくらいあると作業しやすいということで、
座面60〜65cmの椅子を探しに探し回りました...全然なくてびっくりしました。

こちらの椅子が、高さを2wayで切り替えられるということで高い状態にすると座面がちょうど65cmだったので購入しました。
組み立てがめちゃくちゃ大変でした...。
パーツをはめるのに力がいる箇所があるのでご注意ください。
座り心地は最高です。
もうしばらく動きたくなくなります。


ちなみに、ipad→液タブに買えたのと同時に、
お絵描きソフトもProcreateからクリスタ(Clip Studio Paint)に変えました。
それぞれ2つのメリット・デメリットなんかも次の記事で紹介できたらなと思います。

Gatsby+Netlify+microCMS+Material UI 実装ではまったところ

タイトルの通りですが、Gatsby+Netlify+microCMS+Material UIで個人のwebサイトを作成しました。

www.meru-lotte.com

まだ色々と修正したいところだらけなのですが、現状作ってきた中でハマったところを忘れないうちに書き留めておきます。
願わくば、同じような構成でwebサイトを作っている方のヒントになればと思います。
ということでソースコードも公開しています。
細かいところはおおめに見てください。

github.com

※注意※
細かい設定手順については色々なサイトで丁寧に解説しているので、省略させていただきますmm

WebpackError: ReferenceError: window is not defined

ローカル環境では動くけれど、Netlifyでデプロイしようとするとコケる。

   20 | 
   21 | export default function ContentsContiner(props) {
 > 22 |   const windowHeight = window.innerHeight;
      |                        ^
   23 |   const classes = useStyles(windowHeight);
   24 |   return (
   25 |     <Container fixed className={classes.container} id={props.id}>
 
   WebpackError: ReferenceError: window is not defined
   
   - contentContiner.jsx:22 

こちらは調べるとわりとすぐ出てくるけれど、windowが取得できないらしい。
ので、手取り早く修正するのであればこんな感じでundefinedで一回判定を入れてあげれば解決します。

  if ( typeof window !== 'undefined' ) {
    windowHeight = window.innerHeight;
  }

WebpackError: TypeError: Cannot read property 'allMicrocmsArt' of undefined

こちらも、ローカルではうまく動くけれども、Netlifyにデプロイするとコケるパターン。
allMicrocmsArtはmicroCMSから取得しようとしている要素名です。
各々の環境で別の名称になってくると思います。

エラーが出た時の構成はこんな感じです。

./src/pages
├── about.tsx
├── art.tsx    // 実際にdataを使用するコンポーネント
├── index.js
├── index.tsx  // ここでgraphqlでdata取得
├── skill.tsx
└── top.tsx

index.tsxにかいていたコードはこんな感じです。

const App = ({data}) => {
  const classes = useStyles();
  return (
      <>
        <Header/>
        <Top id="top" />
        <About id="about"/>
        // ↓↓↓↓丸ごとdataを渡している
        <Art data={data} />
        <Skill id ="skill" />
        <Footer/>
        <ScrollTop classes={classes} >
      </>
  )}

export const query = graphql`
query {
  allMicrocmsArt {
    nodes {
      id
      title
      createdAt
      picture {
        url
      }
      thumbnail {
        url
      }
    }
  }
}
`
export default App;

結局のところ、取得するデータがどこで使われるかを適切に判断し、必要なものを必要な場所で必要な分だけ取得してあげる必要があります。(それがgraphqlの良さでもありますしね)
エラー自体は親からもらったdataをそのまま子コンポーネントに渡していたので、型解決ができずに子コンポーネントで落ちると言った状況でした。
今回の場合、親コンポーネントは取得したallMicrocmsArtを全く使用しないため、データは子コンポーネント内で取得されるべきでした。
そして、子コンポーネントで静的なデータとして使用する場合には、useStaticQueryを使用するのが良いようです。

const Art = () => {
  const data = useStaticQuery(
    graphql`
      query {
        allMicrocmsArt {
          nodes {
            id
            title
            createdAt
            picture {
              url
            }
            thumbnail {
              url
            }
          }
        }
      }
    ` 
  )

-- 中略 --

  return (
    <ContentsContiner id='art'>
      <Typography variant="h3" gutterBottom>
        art work.
      </Typography>
      <GridList cellHeight={160} className={classes.gridList} cols={col}>
        // ↓↓↓↓ この辺から
        {data.allMicrocmsArt.nodes.map( node =>
        <GridListTile key={node.id} cols={1}>
            <img 
              src={node.thumbnail.url} 
              alt={node.title} 
              className={classes.thumbnail}
              onClick={() => handleToggle(node.picture)} />
          </GridListTile>
        )}
      </GridList>
    </ContentsContiner>
  );
}

export default Art;

Qeryをコンポーネント内に記述するので少し長くなって読みにくくなるのはちょっといまいちだなぁとは思いますが、
こんな感じでuseStaticQueryで取得した値をconstに入れてあげればデータを取得することができます。

Material UIでCSSアニメーションを設定する

こちらは、以下の記事を参考にしました。ありがとうございます。

qiita.com

こんな感じです。

const useStyles = makeStyles((theme) => ({
  image: {
    animation: '$fadeIn 1 1s linear'
  },
  '@keyframes fadeIn': {
    from: {
      opacity: 0
    },
    to: {
      opacity: 1
    }
  }
}));

本当にメモ程度で恐縮です。
Netlifyちゃんと触ったの初めてだったのですが、設定簡単すぎて拝みました。
それとCMSにmicroCMSを採用した理由ですが、日本製だからというのが10割りです。
困ったときに母国語でドキュメントが整備されているのはこれ以上ないアドバンテージです。
管理画面も見やすくて推せます。

Material UIは今回レイアウトで結構うんうん唸ってたので、一から自分で作っても良かった説はありますが、
Reacのファイル内にCSSを記述する上でuseStylesが見やすくて好きなので、これで良かったのだと思います。

今後もウェブサイトの細かい修正は続いていくので、また何かあればかこうと思います。

父の話を聞くのが好きだった

ふと思い出して検索してみたけれどこれといって引っ掛からなかったので、今回の話は、書き留めておこうと思った。

私は親の話を聞くのが好きで、よくいろいろ聞いていたのだけれど、今回もその中の一つ。聞いていて、一番へ〜っとなった、中馬場・上馬場の話をしようと思う。

一般の人は、中馬場?上馬場?となると思うのだが、検索してもらうとすぐわかる埼玉県八潮市にある地名である。区画整備とかでおそらく残っているのはほんのごく一部だと思う。

私は、その辺りで生まれ育って、おそらく町内会が上馬場に属していた。

ちなみに、読み方は
上馬場(かみばんば)
中馬場(なかばんば)
で、なかなか声に出すと楽しい響きだ。
※あくまでこの辺の地名としての読み方

で、この上馬場・中馬場の由来だけれど、松尾芭蕉も歩いたという、草加宿と関係がある。

八潮市と隣接する草加市は、日光街道および奥州街道の2番目の宿場町である。 この草加宿に馬で旅人達がやってくる。そして、その馬を休める場所が、隣の八潮市にある馬場なのだ。そして、上馬場と中馬場、文字だけ見ると上馬場が北側にあるかと思いきや、東西に並んでいて、草加宿に近い西側に上馬場がある。これもまたなるほどとなる。

ちなみに、戦争に行ったおじいちゃんは、この馬場町出身ということで、前線には出ずに馬の世話を任されたから無事に帰ってきたみたいな話も聞いた。

文字だけ見ればなんとなくそんな予想は立てられるけれども、自分が普段から何気なく使っている言葉と、知識が紐づく瞬間てとても楽しい。

そして、こういう話もとても好きなので、そういうのあったらください。

また何か思い出したら書こうと思います。

読むサプリメント「1分自己肯定感 一瞬でメンタルが強くなる33のメソッド」

この本を読もうと思ったきっかけと期待した内容

リモート勤務が続き、職場の人とのコミュニケーションが減り、
自分ってちゃんと組織に受け入れられているのかな?ここにいていい人間なのかな?と疑いだしてしまいました。
でも待って、それって今まですくならかず思ったことくらいはあったけれど、
ここまで酷くはなかったよね🤔 と冷静になって考えてみました。
そして、「これってもしや自己肯定感の低まりでは」ということに気づきました。
(余談ですが、テレワーク鬱というのがあるらしいですね。)

なので、この本は自己肯定感が低まった時に抜け出す方法を知りたくて読み始めました。

メタ認知力を高める

自己認識力・自己評価力・自己修正力・自己行動力これらの感情と向き合う力を総称して「メタ認知」と呼ぶそうです。

  1. 大局的に考えて「ま、いっか」と鷹揚になった方がいい
  2. 相手も自分も肩の力を抜くことができる
  3. 「なんとかなるよ!」ということで未来の可能性へ希望を託すことができる

なんとなくここだけ読んだだけでも、少し気が楽になりますね。

自分を眺めるもう1人の自分を意識することで、感情を「メタ認知」して距離を置くことが大事なようです。

その距離を置く方法がいくつかの手法によって説明されていて、読んでくうちになんか自分にもできそうだなぁと心が軽くなりました。

どんなところが発見だったか

・心が弱ってると内省が自己への過剰攻撃になってしまう  →内省で出て来た答えの真逆の発想を問うてみる  →次回のチャンスがあれば何かよくできないかと改善を考える

・自己肯定感が低まると行動にブレーキがかかる  →「全部、実験♪」って思えばその悪循環から抜け出せる

・自分の弱みにフォーカスしすぎて価値がないと決断を他人に委ねてしまう  →弱みと強みは隣り合わせ  →弱みも強みも全部合わせて自分には価値があると考えること

上であげた以外にも、たくさんのアドバイスがあります。 読んでいくうちに、それが心の栄養になって、「なんか悩むほどのことでもなかったなぁ」とか「世界はもっと楽しいものだったかもしれない」と前向きな気持ちを思い出すことができました。


もちろん、冒頭で触れていたもっと深刻なうつ状態に陥ってしまった人には手厚いフォローがいると思いますが、私と同じように「あれ?なんか心の調子、おかしいかもしれない。」と不安になってしまった方には是非この本を読んで元気を取り戻して欲しいなと思いました。

最近読んで良かった本「哲学シンキング」

仕事や生活の中で、何か不便なことや新たな目標を立てることってあると思います。
その時、その不便なことや目標を解決/達成したらもっと良い明日が待っていると思われます。でも、果たしてその不便さに対する解決は正しいのか、あるいは立てた目標の目指すところって本当に正しいのだっけと考えることはないでしょうか。

それで、最近そう言った「課題を発見すること」に対して参考になった本を紹介したいと思います。

この本はストーリー仕立てで課題発見の方法を説明していてとてもわかりやすかったです。

小学生の主人公が、おばあちゃんの和菓子屋さんに遊びに行くと、新しくできたスーパーにお客がとられてしまい売り上げが下がってしまった。悲しむおばあちゃんをみて主人公はなんとかそれを解決したいと悩むところから話が始まります。

哲学シンキングの詳細な内容は本を読んでいただいた方が良いと思いますが、要約すると以下になります。

  1. かたっぱしから問いを出す(問いを集める)
  2. 1.をグルーピングする
  3. 優先度付をする
  4. 議論を組み立てる
  5. 新しい洞察・視点の発見

読んでいてなるほど。となったのが一番初めの「問いを集める」と言うところをとても重要視していると言うことです。

例えば、「会員登録数を向上する」と言うテーマがあった場合、すぐに手法を考えがちです。でも、この哲学シンキングの方法を適用するとしたら、まずすることは「会員登録について問いを集める」ことです。

「会員登録について問い」とは具体的には、以下のような感じでしょうか。

  • 会員登録を行うと何が良いのか
  • 会員登録してくれる/してくれない人はどんな人なのか
  • どういう時会員登録をしようと思うのか

こんな感じで、会員登録数をアップすることとは直接結びつけず、一旦純粋に会員登録についての問いを考えてみるのです。

そしてそのあとは、上に書いた順でグルーピングしたりして問いに対する解答を書き出していきます。

この手法の何が良いのか

課題に対する視野が広くなるというのがこの哲学シンキングの良さです。

極端な話、始めにたてた課題がもしかしたら解決する必要のない課題である可能性もあります。

課題に対する解決策をすぐに探そうとするのではなく、一旦問いを集めることで理解を深め、最終的にいろいろな視点から課題を見つめ直し新しい洞察や視点を発見することができるのがこの手法の良さです。

複数人のグループワークはもちろん、仕事や生活の中で自分1人で何か考えをまとめなければいけない場面でも、視野が広がりより良いアイディアを出せます。

だんだん、考えるのが楽しくなってきますので、課題発見に悩んでる方もそうでない方も是非ご一読ください。