Nuxt.js+Contentful+NetlifyでサーバーレスなSPAサイトを作成する

こんにちは!

株式会社SCOUTER開発部フロントエンドエンジニアの佐藤(@r_sato1201)です

先日、社内でプログラミング歴が浅い社員対象の、初学者LT大会というものが開催されました。
LT大会の様子は後日このブログにて公開されると思いますが、
今回はそのLT大会で私が作成したものを、使った技術の紹介も含めて紹介したいと思います。

主にNuxtとNetlifyについて紹介します。

作成物

休日に活動しているバンドのHPを作成しました。


技術構成

Nuxt + Contentful + Netlify

この構成を選んだ理由は大きく2点あります。

HPの更新を誰でも更新できるようにしたかった

バンドHPでは主に、ライブ情報や発売したCDなどの情報を定期的に更新する必要があります。
その更新を、私以外のバンドメンバーでも更新できるようにしたかった為、CMS化することを考えました。
その中で、ContentfulはAPIファーストでコンテンツの作成・管理を簡単にできるので選択しました。

サーバーを自前で用意・運用したくなかった

上記の通りなのですが、サーバーを自前で運用するのはコストもかかりますし、知見もなかったので
静的サイトホスティングサービスであるNetlifyを選択しました。
GitHubリポジトリからwebhookを受け取ると自動でリポジトリをビルドやデプロイしてくれるので非常に便利なサービスです。

1.Nuxtでサイトの作成

Nuxtプロジェクト作成

yarn create nuxt-app <プロジェクト名>

まずは上記コマンドでNuxtプロジェクトを作成します。

layoutの作成

各ページ共通であるヘッダー、フッターをレイアウトテンプレートに記述しました。

default.vue

<template>
<div>
<Header/>
<nuxt/>
<Footer/>
</div>

</template>

<script>
import Header from '~/components/item/Header.vue'
import Footer from '~/components/item/Footer.vue'

export default {
components: {
Header,
Footer,
},
}
</script>

ヘッダー、フッター部分のコードは割愛します。

Contentfulの設定

Contentfulについて

Nuxtでプロジェクトを作り、外見をつくったら次はContentfulの設定です。
Contentfulはコンテンツを管理するためのREST APIを提供してくれます。


Contentfulの概念は上図のようになっています。
各々をイメージで説明すると

Space:コンテンツを管理する単位
ContentModel:データベースのテーブル定義のようなもので、テーブルのカラム定義を設定する場所Entry:ContentModelに定義したテーブルのデータ

となります。

Spaceの作成→ContentModelの作成→Entryの作成という順序でコンテンツを作成します。

次に、Contentfulを呼び出す用のプラグイン、contentful.jsを作成します

contentful.js

const contentful = require('contentful')

const config = {
space: process.env.CTF_SPACE_ID,
accessToken: process.env.CTF_CDA_ACCESS_TOKEN,
}

module.exports = {
createClient() {
return contentful.createClient(config)
},
}

次に、Contentfulと接続するためのAPI keyを取得し、接続設定を以下のように.env に記述します

.env

CTF_SPACE_ID="Your Space ID"
CTF_CDA_ACCESS_TOKEN="Your Access Token"
CTF_BLOG_POST_TYPE_ID="Your Post Type ID"

nuxt.config.jsにて先程.env に記述した内容をenvプロパティにて呼び出します。

nuxt.config.js

const config = require('./.contentful.json')

module.exports = {
// ...
env: {
CTF_SPACE_ID: config.CTF_SPACE_ID,
CTF_CDA_ACCESS_TOKEN: config.CTF_CDA_ACCESS_TOKEN,
CTF_BLOG_POST_TYPE_ID: config.CTF_BLOG_POST_TYPE_ID
}
// ...
}

最後に、Vueファイルを記述し記事を取得します。
asyncData内でContentfulから記事情報を取得し、Liveコンポーネントに渡しています。

※Vueファイルは分かりやすくするため、簡略化しています

pages/live/index.vue

<template>
<div class="container">
<live
v-for="post in posts"
:key="post.fields.slug"
:image="post.fields.image"
:title="post.fields.title"
:place="post.fields.place"
:fee="post.fields.fee"
/>
</div>
</template>

<script>
import Live from '~/components/Live'
import { createClient } from '~/plugins/contentful'

const client = createClient()
export default {
transition: 'slide-left',
components: {
Live,
},
asyncData({ env }) {
return client
.getEntries({
content_type: env.CTF_BLOG_POST_TYPE_ID,
order: '-fields.date',
})
.then(entries => {
return {
posts: entries.items,
}
})
.catch(console.error)
},
}
</script>

components/Live.vue

<template>
<div class="live-card">
<div class="live-card_image">
<img :src="image.fields.file.url">
</div>
<div class="live-card_contents">
<p class="live-card_title">{{ title }}</p>
<p class="live-card_place">{{ place }}</p>
<p class="live-card_fee">{{ fee }}</p>
</div>
</div>
</template>
<script>
export default {
props: {
image: {
type: Object,
},
title: {
type: String,
},
place: {
type: String,
},
fee: {
type: String,
},
}
}

これでContentfulの設定は完了しました。

※詳しくは、Contentful公式ドキュメントに詳しく書かれているので参照して下さい。

Netlifyの設定

Netlify Formsについて

Netlifyを選んだ理由として、サーバーレスで実装できる以外にもフォームが簡単に実装できることが挙げられます。

HTMLの

タグの属性に

netlify

と追加で記述することで、そのフォームが動きます。
以下は公式ドキュメントの例です。

<form name="contact" method="POST" data-netlify="true">
<p>
<label>Your Name: <input type="text" name="name" /></label>
</p>
<p>
<label>Your Email: <input type="email" name="email" /></label>
</p>
<p>
<label>Your Role: <select name="role[]" multiple>
<option value="leader">Leader</option>
<option value="follower">Follower</option>
</select></label>
</p>
<p>
<label>Message: <textarea name="message"></textarea></label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>

上記のように記述するだけで、NetlifyのFromページ上で送られた情報が確認できます。

サイトの作成

最後にNetlifyの設定について書きたいと思います。
「New Site From Git」を押下するとリポジトリ選択画面に移動するので、Nuxtプロジェクトをプッシュしたリポジトリを選択してください。


次に、デプロイするブランチを選択して下さい。
基本的にはmasterでいいと思います。


デプロイブランチを選択したら、ビルドの設定を行います。
今回は、Nuxtから静的サイトジェネレートするので nuxt generateと記述をします。

nuxt generate
によってdistディレクトリが生成されるので、Publish Directoryにはdistと記述します。


環境変数の設定

最後に環境変数の設定です。

.envに設定したContentfulのSpace ID
,Access Token
,Post Type ID を設定する必要があるので設定します。


サイトの公開

以上までで、設定は完了です。
Netlify上で、「Deploy Site」をクリックすることでサイトが公開されます。

まとめ

Nuxt+Contentful+Netlifyという構成で簡単にSPAサイトを作成することができました。
初学者でも非常に簡単に作成できるので非常にオススメの構成です。

今後は、現在作成途中のバンドHPを最後まで作り切ると共に
Contentful,Netlifyで出来ることに関してもっと理解を深めていきたいと考えています。

さいごに

現在、株式会社SCOUTERでは、エンジニア、デザイナーの募集をしております。

興味のある方は、是非下記からご応募お願い致します!


フロントエンドエンジニア
最新技術で成長業界の波に乗りたいVue.jsフロントエンドエンジニア募集!
ROXXは「人を想い、社会に問う」をビジョンに、2013年に設立。この先何十年も使い続けられるような社会的意義のあるサービスを目指し、現在はHRTechサービスを展開しています。 ■月額制リファレンスチェックサービス『back check』( https://backcheck.jp )  書類選考や面接だけでは分からない採用候補者の経歴や実績に関する情報を、候補者の上司や同僚といった一緒に働いた経験のある第三者から取得することができる、リファレンスチェックサービスです。業界水準の1/10ほどの低コストで実施ができ、大手企業からスタートアップベンチャーまで、幅広い企業様にご利用いただくことができます。 ■ 採用企業と人材紹介会社を繋ぐ、求人プラットフォーム『agent bank』  サービス上に掲載されている1,500社以上の求人情報を、自社で抱える求職者へ自由に紹介することができる求人プラットフォームです。人材紹介会社は、自社で無駄な営業コストを抱えず、目の前の転職者支援に注力することができます。今後は、AIを活用した書類の自動作成、求職者に適した求人提案の自動化などのエージェント業務の大幅な効率化を進めていきます。中小規模の人材紹介会社を集約し、数年後には日本最大の人材紹介会社になることを目指します。
株式会社ROXX
UI/UX designer
ユーザーの行動設計を変えていく!話題のSaaSデザイナー募集!
ROXXは「人を想い、社会に問う」をビジョンに、2013年に設立。この先何十年も使い続けられるような社会的意義のあるサービスを目指し、現在はHRTechサービスを展開しています。 ■月額制リファレンスチェックサービス『back check』( https://backcheck.jp )  書類選考や面接だけでは分からない採用候補者の経歴や実績に関する情報を、候補者の上司や同僚といった一緒に働いた経験のある第三者から取得することができる、リファレンスチェックサービスです。業界水準の1/10ほどの低コストで実施ができ、大手企業からスタートアップベンチャーまで、幅広い企業様にご利用いただくことができます。 ■ 採用企業と人材紹介会社を繋ぐ、求人プラットフォーム『agent bank』  サービス上に掲載されている1,500社以上の求人情報を、自社で抱える求職者へ自由に紹介することができる求人プラットフォームです。人材紹介会社は、自社で無駄な営業コストを抱えず、目の前の転職者支援に注力することができます。今後は、AIを活用した書類の自動作成、求職者に適した求人提案の自動化などのエージェント業務の大幅な効率化を進めていきます。中小規模の人材紹介会社を集約し、数年後には日本最大の人材紹介会社になることを目指します。
株式会社ROXX
サーバーサイドエンジニア
Laravelでマーケット成長の波に乗りたいエンジニアを募集!
ROXXは「人を想い、社会に問う」をビジョンに、2013年に設立。この先何十年も使い続けられるような社会的意義のあるサービスを目指し、現在はHRTechサービスを展開しています。 ■月額制リファレンスチェックサービス『back check』( https://backcheck.jp )  書類選考や面接だけでは分からない採用候補者の経歴や実績に関する情報を、候補者の上司や同僚といった一緒に働いた経験のある第三者から取得することができる、リファレンスチェックサービスです。業界水準の1/10ほどの低コストで実施ができ、大手企業からスタートアップベンチャーまで、幅広い企業様にご利用いただくことができます。 ■ 採用企業と人材紹介会社を繋ぐ、求人プラットフォーム『agent bank』  サービス上に掲載されている1,500社以上の求人情報を、自社で抱える求職者へ自由に紹介することができる求人プラットフォームです。人材紹介会社は、自社で無駄な営業コストを抱えず、目の前の転職者支援に注力することができます。今後は、AIを活用した書類の自動作成、求職者に適した求人提案の自動化などのエージェント業務の大幅な効率化を進めていきます。中小規模の人材紹介会社を集約し、数年後には日本最大の人材紹介会社になることを目指します。
株式会社ROXX
株式会社ROXX's job postings
1 Likes
1 Likes

Weekly ranking

Show other rankings
If this story triggered your interest, go ahead and visit them to learn more