最近Nuxt+Bulma+S3でコロナウィルスで苦しんでいるライブハウスを支援するまとめサイトを作ったので、それについて書いていきます。最終的に完成したものは以下になります。
https://besidethemusic.tokyo
作ろうと思った経緯などはこちらのnoteをご覧ください。
https://note.com/gch/n/n881c9d0cb72d
技術選定は何か自分が触ったことがない技術で作ってみたいということで、Nuxt+Bulmaにしました。バックエンドはCloudFront+S3で良く触ってる技術なのですが、がっつりTerraformで作りました。
NuxtはSSRやSPAとして使うケースが多いと思いますが、静的サイトジェネレーターとしても使うことができ便利です。
Nuxt.js
Nuxt.jsはVue.jsベースのJavaScriptのフレームワークで、簡単にアプリケーションを作ることができます。完成したものはこちらです。
https://github.com/yuzoiwasaki/besidethemusic-nuxt
Nuxtでアプリケーションを作るにはまず create-nuxt-app
します。
$ npx create-nuxt-app <project-name>
or
$ yarn create-nuxt-app <project-name>
そうするといくつか質問されるので答えていきましょう。内容は後から変更することも可能です。今回はCSSフレームワークにBulmaを使ったため、UIフレームワークはBulmaを選択しました。また、NuxtのモードはSSRではなくSPAを選択します。
全ての質問に答え終わるとアプリケーションの雛形が作成されます。この状態で yarn dev
としてサーバを立ち上げ localhost:3000
にアクセスするとデフォルトページが立ち上がっています。ここから自分好みにカスタマイズしていきましょう。
Nuxtのディレクトリ構成
.
└── besidethemusic
├── README.md
├── assets
├── components
├── layouts
├── middleware
├── node_modules
├── nuxt.config.js
├── package.json
├── pages
├── plugins
├── static
├── store
└── yarn.lock
デフォルトのトップページが pages/index.vue
なので、こちらのファイルを編集していきます。何も考えずに作るならひたすらこのファイルにコードを書いていけばいいのですが、肥大化してしまうのでコンポーネント化して components
以下に置きました。
<template>
<div id="main">
<Hero />
<Statement />
<SupportSite />
<Crowdfunding />
<Footer />
</div>
</template>
<script>
import Hero from '@/components/Hero.vue'
import Statement from '@/components/Statement.vue'
import SupportSite from '@/components/SupportSite.vue'
import Crowdfunding from '@/components/Crowdfunding.vue'
import Footer from '@/components/Footer.vue'
export default {
components: {
Hero,
Statement,
SupportSite,
Crowdfunding,
Footer
}
}
</script>
...
メタタグ系は nuxt.config.js
に記載していきます。
const title = 'Beside the Music'
const description = 'コロナウィルスで苦しんでいるライブハウスを支援するためのまとめサイトです。みんなで音楽を支援しよう!いつも音楽のそばに'
const type = 'website'
const url = 'https://besidethemusic.tokyo'
const image = 'https://besidethemusic.tokyo/images/ogp.jpg'
export default {
mode: 'spa',
/*
** Headers of the page
*/
head: {
title: title,
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: description },
{ hid: 'og:type', property: 'og:type', content: type },
{ hid: 'og:title', property: 'og:title', content: title },
{ hid: 'og:description', property: 'og:description', content: description },
{ hid: 'og:url', property: 'og:url', content: url },
{ hid: 'og:image', property: 'og:image', content: image },
{ hid: 'fb:app_id', property: 'fb:app_id', content: '667885473990531' },
{ hid: 'twitter:card', name: 'twitter:card', content: 'summary_large_image' },
{ hid: 'twitter:site', name: 'twitter:site', content: '@besidethemusic' },
],
...
今回はwebpackなどは使わないため、アセットは static
以下に置きました。
サイトが完成したら yarn generate
とすると dist
以下に成果物が生成されるので、こちらを丸ごとホスティングサイトにアップロードします。
Bulma
BulmaはBootstrapのようなCSSフレームワークで、CSSのみで完結し軽量な点が特徴です。Flexboxをベースにしているため、簡単にレイアウトを作ることができます。レスポンシブに対応しているのも嬉しいところです。
https://bulma.io
Bootstrapで作るとjQueryがセットになってしまうのと、どうしてもBootstrapっぽさが出てしまうので、Bulmaはなかなか良かったです。
Vue.jsだとBuefyというVuejs+Bulmaで実装されたUIコンポーネントライブラリもあるので、こちらでも良かったかもしれません。
https://buefy.org
BulmaはBootstrapに馴染みがある人なら問題なく触れると思います。自分のように普段あまりCSSを書かない人間にとってはこうしたCSSフレームワークはありがたいです。
こちらにBulmaで作られたサイトがまとまっておりとても参考になります。
https://bulma.io/expo
S3
インフラはAWSのCloudFront+S3で作りました。自分はSREなのでこちらの作業は速かったです。全てTerraformで作ってますので、興味がある人は覗いてみてください。
https://github.com/yuzoiwasaki/besidethemusic-terraform
ハマったところ
どれも初歩的なものなのですが、同じようにつまづいた人のために実装中にハマったところを書いておきます。
Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
pages/index.vue
を編集すると上記のメッセージが出ました。原因はルートエレメントが複数あるからのようです。
こうではなく
<template>
<div class="container">
<div>
<div class="container">
<div>
</template>
こうします
<template>
<div id="main">
<div class="container">
<div>
<div class="container">
<div>
</div>
</template>
index.htmlを開いても何も表示されない
yarn generate
してできた index.html
をクリックしても何も表示されませんでした。が、S3にアップロードすると問題なく表示されたためそういうもののようです。
TwitterのみOGPが表示されない
FacebookやLINE、Slackなどは問題なくOGPが表示されたのに、なぜかTwitterだけ表示されませんでした。結論としてはパスの指定の仕方が悪かったようで、URLでフルパス指定したら表示されました。
Facebookでもエラーになっていたようですが、推測して表示できていたようです。シェアデバッガーでエラーが出ていたので気づきました。
https://developers.facebook.com/tools/debug/?locale=ja_JP
Twitter Card Validatorでは成功したログしか出ていなかったため解決に苦労しました。Twitter。。
最後に
以上、Nuxt+Bulma+S3でサイトを作ったまとめでした!初歩的な内容が多いですが、少しでも誰かの参考になれば幸いです!最後までお読みいただきありがとうございました!