7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nuxt+Bulma+S3でライブハウス支援サイトを作った

Last updated at Posted at 2020-05-04

最近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 以下に置きました。

pages/index.vue
<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 に記載していきます。

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 を編集すると上記のメッセージが出ました。原因はルートエレメントが複数あるからのようです。

こうではなく

pages/index.vue
<template>
  <div class="container">
  <div>

  <div class="container">
  <div>
</template>

こうします

pages/index.vue
<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でサイトを作ったまとめでした!初歩的な内容が多いですが、少しでも誰かの参考になれば幸いです!最後までお読みいただきありがとうございました!

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?