GridsomeでTailwind CSSを使ってみる
下記で使ったGridsomeのプロジェクト(Gridsomeのblog starter)にTailwind CSSを導入してみます。
ここではGridsomeのプロジェクトに簡単にTailwindを導入できるプラグインgridsome-plugin-tailwindcssを使用します。
gridsome-plugin-tailwindcssのインストール
下記コマンドを実行してgridsome-plugin-tailwindcssをインストールします。
$ cd frontend
$ yarn add --dev gridsome-plugin-tailwindcss tailwindcss@latest
postcss-importやpostcss-preset-envが必要な場合は下記コマンドも実行します。
$ yarn add --dev postcss-import postcss-preset-env
tailwind.config.jsの作成
下記コマンドを実行してtailwind.config.jsを作成します。
$ npx ./node_modules/.bin/tailwind init
tailwind.config.jsの編集
作成したfrontend/tailwind.config.jsを下記のように編集してPurgeの設定を追加します。
Purgeの設定をしないとビルド後に作成されるCSSのファイルサイズが非常に大きくなってしまいます。
module.exports = {
purge: {
content: [
'./src/**/*.html',
'./src/**/*.js',
'./src/**/*.vue',
],
options: {
keyframes: true,
},
},
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
プラグインの読み込みを追加
frontend/gridsome.config.jsにgridsome-plugin-tailwindcssの読み込みを追加します。
module.exports = {
siteName: "Strapi Gridsome Blog",
siteDescription: "A blog site made using Gridsome and Strapi",
plugins: [
{
use: "@gridsome/source-graphql",
options: {
url:
(process.env.GRIDSOME_STRAPI_URL || "http://localhost:1337") +
"/graphql",
fieldName: "strapi",
typeName: "strapiTypes",
},
},
// 下記を追加
{
use: "gridsome-plugin-tailwindcss",
options: {
tailwindConfig: './tailwind.config.js',
// postcss-importを有効にする場合
shouldImport: true
// postcss-preset-envを有効にする場合
shouldTimeTravel: true
presetEnvConfig: {}, //postcss-preset-envの設定
}
},
],
};
postcss-importをインストールしている場合、optionsにshouldImport: true
を追加することで有効になります。
また、postcss-preset-envをインストールしている場合はoptionsにshouldTimeTravel: true
を追加することで有効にでき、presetEnvConfig
にpostcss-preset-envの設定のオブジェクトを記述できます。
ビルドして確認
下記コマンドでGridsomeをビルドして動作確認します。
$ yarn develop
ビルドが成功し、表示されたページをChromeのデベロッパーツール等で見るとTailwindが読み込まれているのが確認できます。
Tailblocksのコンポーネントをベースにトップページを編集
下記のTailwindのコンポーネント集を使用してGridsomeのblog starterのトップページを編集してみます。
ヘッダーは下記をベースにしました。
"VIEW CODE"をクリックすると下記のように選んだコンポーネントのソースを見ることができます。
記事一覧は下記をベースにしました。
frontend/src/index.htmlのUIkit CSSの読み込み部分を削除します。
<!DOCTYPE html>
<html ${htmlAttrs}>
<head>
${head}
</head>
<body ${bodyAttrs}>
${app}
${scripts}
</body>
</html>
frontend/src/pages/Index.vueのtemplateの変更およびarticlesのクエリにdescriptionを追加します。
<template>
<Layout>
<Articles :articles="$page.strapi.articles" />
</Layout>
</template>
<page-query>
query {
strapi {
global {
siteName
favicon {
url
}
defaultSeo {
metaTitle
metaDescription
shareImage {
url
}
}
}
homepage {
hero {
title
}
seo {
metaTitle
metaDescription
shareImage {
url
}
}
}
articles(where: { status: "published" }) {
slug
title
description
category {
name
}
image {
url
}
author {
name
picture {
url
}
}
}
}
}
</page-query>
<script>
import Articles from "~/components/Articles";
import { getMetaTags } from "~/utils/seo";
import { getStrapiMedia } from "~/utils/medias";
export default {
components: {
Articles,
},
metaInfo() {
const { seo } = this.$page.strapi.homepage;
const { defaultSeo, favicon } = this.$page.strapi.global;
// Merge default and article-specific SEO data
const fullSeo = {
...defaultSeo,
...seo,
};
return {
title: fullSeo.metaTitle,
meta: getMetaTags(fullSeo),
link: [
{
rel: "favicon",
href: getStrapiMedia(favicon.url),
},
],
};
},
};
</script>
frontend/src/layouts/Default.vueのstyleを削除します。
<template>
<div>
<Navbar />
<slot />
</div>
</template>
<script>
import Navbar from "~/components/Navbar";
export default {
components: {
Navbar,
},
};
</script>
<style>
</style>
frontend/src/components/Navbar.vueのtemplateを変更します。
<template>
<header class="text-gray-600 body-font">
<div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
<g-link to="/" class="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0">{{ $static.strapi.global.siteName }}</g-link>
<nav class="md:ml-auto flex flex-wrap items-center text-base justify-center">
<g-link v-for="category in $static.strapi.categories" :key="category.id" :to="'/category/' + category.slug" class="mr-5 hover:text-gray-900">{{
category.name
}}</g-link>
</nav>
</div>
</header>
</template>
<static-query>
query {
strapi {
categories {
id
name
slug
}
global {
siteName
}
}
}
</static-query>
frontend/src/components/Articles.vueのtemplateを変更します。
<template>
<section class="text-gray-600 body-font">
<div class="container px-5 py-4 mx-auto">
<div class="flex flex-wrap -m-4">
<Card
v-for="article in articles"
:article="article"
:key="article.id"
/>
</div>
</div>
</section>
</template>
<script>
import Card from "~/components/Card";
export default {
props: {
articles: Array,
},
components: {
Card,
},
computed: {
},
};
</script>
frontend/src/components/Card.vueのtemplateを変更します。
<template>
<div class="p-4 md:w-1/3">
<g-link
:to="{ path: '/article/' + article.slug }"
:key="article.id"
>
<div class="h-full border-2 border-gray-200 border-opacity-60 rounded-lg overflow-hidden">
<g-image :src="getStrapiMedia(article.image.url)" class="lg:h-48 md:h-36 w-full object-cover object-center" alt="blog" />
<div class="p-6">
<h2 v-if="article.category" class="tracking-widest text-xs title-font font-medium text-gray-400 mb-1">{{ article.category.name }}</h2>
<h1 class="title-font text-lg font-medium text-gray-900 mb-3">{{ article.title }}</h1>
<p class="leading-relaxed mb-3">{{ article.description }}</p>
<div class="flex items-center flex-wrap ">
<span class="text-gray-400 inline-flex items-center lg:ml-auto md:ml-0 ml-auto leading-none text-sm py-1">
{{ article.author.name }}
<g-image
class="rounded-full h-12 w-12 flex items-center justify-center ml-3"
:src="getStrapiMedia(article.author.picture.url)"
:alt="article.title"
/>
</span>
</div>
</div>
</div>
</g-link>
</div>
</template>
<script>
import { getStrapiMedia } from "~/utils/medias";
export default {
props: {
article: Object,
},
methods: {
getStrapiMedia,
},
};
</script>
変更前
変更後
まとめ
gridsome-plugin-tailwindcssを使うことで簡単にGridsomeでTailwindを使うことができました。
Tailwindは今回使用したTailblocksだけでなく、Tailwind公式のTailwind UIなど無料・有料含めたくさんのコンポーネント集があり、これらを利用することでより簡単に、よりスピーディにサイトを制作できると思います。
Discussion