情報の膨大さで私たちを圧倒するIT業界。そんな中で、きれいに整理された、視覚的に楽しいドキュメントやブログサイトを持つことの重要性は計り知れません。それでは、ウェブ開発に大量の時間を費やすことなく、これを実現するにはどうすればいいのでしょうか。

この記事では、シンプルでありながら高性能な静的サイトジェネレーター(SSG)であるVuePressを使って、素早くドキュメントサイトやブログサイトを作成し、カスタマイズする方法をご説明します。

VuePress documentation and blog demo
VuePressのドキュメント/ブログサイトのデモ

VuePressとは

VuePressはオープンソースのフレームワークで、主にドキュメントやブログ向けの静的なウェブサイトを生成することに特化しています。Vue.jsの生みの親であるEvan You氏によって開発され、Vue.jsの理念であるシンプルさと使いやすさを体現しています。

VuePressが選ばれている理由

VuePressが人気を博す理由は以下の通りです。

  1. Markdownのシンプルさ:VuePressは、Markdownを使用してコンテンツ作成を簡素化しています。複雑なフォーマットを使用せずに簡単にコンテンツを記述し、構成することができます。
  2. Vue.jsとの統合:VuePressはVue.jsとシームレスに統合します。インタラクティブでダイナミックなウェブ要素を実現し、魅力的なユーザー体験を提供可能です。
  3. パフォーマンスとカスタマイズ:VuePressは、静的ウェブサイトを素早く読み込む優れたパフォーマンスと、スタイルやニーズに合わせた豊富なカスタマイズオプションを誇ります。

VuePressの利用を開始する

VuePressを使い始める前に、お使いのコンピュータにNode.jsまたはYarn Classicがインストールされていることを確認してください。create-vuepress-siteジェネレーターを使用することで、VuePressの基本的なサイト構造を構築することができます。

この記事では、手動インストールを行なってみましょう。

  1. 新しいディレクトリを作成し、それに変更を加えます。
mkdir vuepress-starter && cd vuepress-starter
  1. お好みのパッケージマネージャで初期化します。今回はYarnを使います。
yarn init
  1. VuePressを開発者依存関係としてプロジェクトにインストールします。
yarn add -D vuepress
  1. すべてのコードを格納するdocsフォルダを作成し、index.htmlと同様にプロジェクトのインデックスファイルとなるREADME.mdファイルを作成します。
mkdir docs && echo '# Hello VuePress' > docs/README.md
  1. コードエディタでプロジェクトを開き、以下のスクリプトをpackage.jsonファイルに追加します。
"scripts": {
    "dev": "vuepress dev docs",
    "build": "vuepress build docs"
  },

yarn devコマンドを実行することで、サイトを配信できるようになります。VuePressの開発サーバーのURLはhttp://localhost:8080です。

Defualt theme for VuePress manual installation
VuePress手動インストール時に適用されるデフォルトテーマ

これでドキュメントサイトが作成できました。VuePressは、クリーンでミニマルなデフォルトテーマを採用しています。高度なカスタマイズが可能で、好みに応じてウェブサイトの見た目や雰囲気を調整できます。

ドキュメントページの作成

VuePressは、ドキュメント整理の整理が捗るわかりやすいディレクトリ構造になっています。プロジェクトフォルダ内にはdocsディレクトリがあり、ドキュメントページ用のMarkdown(.md) ファイルを作成することができます。

例えば、getting-started.mdusage.mdtroubleshooting.mdのようなファイルを作成することが可能です。これらのファイルは、http://localhost:8080/getting-started、http://localhost:8080/usage、http://localhost:8080/troubleshootingに移動すると、自動的にアクセスできます。

ドキュメントの構成をさらに整理するには、関連するドキュメントページ専用のフォルダを作成可能です。例えば、guideというフォルダを作成し、using-kinsta-stsh.mdなどのページを格納できます。この構造を採用すると、using-kinsta-stsh.mdのコンテンツはhttp://localhost:8080/guide/using-kinsta-stshというURLでアクセスできるようになります。

guideフォルダのルートレベルにREADME.mdまたはindex.mdファイルを作成することもできます。このファイルはインデックスページとして機能します。これにより、サイト訪問者は、http://localhost:8080/guide/にアクセスしたり、(次のセクションで設定方法をご紹介するように)サイドバーを使ってコンテンツ間を楽々移動したりできます。

こちらのVuePressのサンプルリポジトリでは、これらのファイルがすべて作成され、それぞれのファイルにマークダウンのコンテンツが追加されていることがわかります。状況や目的に応じてゼロから、あるいはリポジトリ内のコンテンツを参考にするなどして、お好みのファイルを自由に作成してください。

VuePressの外観を整える

一度コンテンツでドキュメントサイトを作成すると、特に管理するファイルが多い場合、管理が困難に感じるかもしれません。とはいえ、VuePressではサイトのナビゲーション構造をカスタマイズして、使いやすく整理することができます。

サイトの外観とナビゲーションをカスタマイズするには、プロジェクトのルートディレクトリに.vuepressフォルダを作成します。このフォルダには、VuePressサイトに関連する設定ファイルやアセットが格納されます。

ナビゲーション設定

.vuepressフォルダに、config.jsファイルを作成します。YAML (.yml)、TOML (.toml)、TypeScript (.ts)などの他のファイル形式を設定に使用することもできます。

config.jsファイルでは、themeConfigオブジェクトを使ってサイトのナビゲーション構造を定義できます。以下はコンフィギュレーションの例です。

module.exports = {
    title: 'Kinsta Vuepress',
    description: 'A VuePress QuickStart for Kinsta',
    themeConfig: {
        nav: [
            {
                text: 'Guide',
                link: '/guide/',
            },
            {
                text: 'Static Site Hosting',
                link: 'https://kinsta.com/static-site-hosting/',
            },
        ],
        sidebar: {
            '/guide/': [
                {
                    title: 'Guide',
                    collapsable: false,
                    children: ['', 'using-kinsta-stsh'],
                },
            ],
        },
    },
};

この例では、titledescriptionを設定し、ナビゲーションリンクを定義し、/guide/セクションにサイドバーを設定しています。

navの配列は、サイトのトップにあるナビゲーションリンクを指定します。サイドバーオブジェクトは、特定のセクションのサイドバー構造を定義するものです。ここでは、/guide/セクション用に設定されています。

ナビゲーションバーの設定については、VuePressのドキュメントをご参照ください。

スタイリング

VuePressでは、スタイルによってサイトの外観をカスタマイズすることができます。定義された変数を使用してデフォルトのスタイルを上書きするか、独自のスタイルを定義することができます。どちらかを行うには、.vuepressフォルダにstylesフォルダを作成します。

デフォルトプリセットのスタイルに簡単なオーバーライドを適用したり、後で使用する変数を定義するには、.vuepress/stylespalette.stylファイルを作成します。以下のような定義済みの変数を調整して使うことができます。

// colors
$accentColor = #5333ED
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34
$arrowBgColor = #ccc
$badgeTipColor = #42b983
$badgeWarningColor = darken(#ffe564, 35%)
$badgeErrorColor = #DA5961

// layout
$navbarHeight = 3.6rem
$sidebarWidth = 20rem
$contentWidth = 740px
$homePageWidth = 960px

// responsive breakpoints
$MQNarrow = 959px
$MQMobile = 719px
$MQMobileNarrow = 419px

これらの変数は、サイト全体で一貫したスタイルを維持するのに使用できます。VuePressでは、別のスタイルを追加するのも簡単です。.vuepress/stylesフォルダにindex.stylファイルを作成し、通常のCSS構文を使用することができます。

.content {
  font-size 30px
}

VuePressのスタイルについては公式ドキュメントをご覧ください。

コンポーネントの使用

VuePressは、ページの機能や外観をより良いものにするコンポーネントの使用をサポートしています。Vueコンポーネントを作成し、Markdownファイルに含めることができます。.vuepressにcomponentsフォルダを作成します。すると、.vuepress/componentsにある*.vueファイルが自動でグローバルコンポーネントとして登録されます。

例えば、HomeOptions.vueHostingBanner.vueの2つのコンポーネントを作成する例を考えてみると以下のようになります。

.
└─ .vuepress
   └─ components
      ├─ HomeOptions.vue
      └─ HostingBanner.vue

これらのvue.jsコンポーネントファイル内に、CSSコードを追加することができます。HomeOptions.vueHostingBanner.vueコンポーネントにコードを追加してみましょう。

以下のコードをHomeOptions.vueに追加します。

<template>
    <div class="options">
        <div class="option">
            <a
                href="https://kinsta.com/docs/static-site-hosting/static-site-quick-start-examples/"
                target="_blank"
            >
                <h3>Quick Start Examples</h3>
            </a>
            <p>Explore quick start examples for setting up static sites.</p>
        </div>
        <div class="option">
            <a
                href="https://kinsta.com/docs/static-site-hosting/getting-started-static-site-hosting/"
                target="_blank"
            >
                <h3>Getting Started</h3>
            </a>
            <p>Learn how to get started with static site hosting.</p>
        </div>
        <div class="option">
            <a
                href="https://kinsta.com/docs/static-site-hosting/manage-static-sites/"
                target="_blank"
            >
                <h3>Manage Static Sites</h3>
            </a>
            <p>Discover how to efficiently manage your static sites.</p>
        </div>
    </div>
</template>

<style scoped>
    a {
        color: #2c3e50;
    }
    a:hover {
        color: #5333ed;
    }
    .options {
        display: flex;
        gap: 10px;
        margin: 40px 0;
    }
    .option {
        border: 2px solid #eaecef;
        border-radius: 5px;
        padding: 10px;
    }
</style>

また、HostingBanner.vueに以下のコードを追加します。

<template>
    <div class="banner">
        <p>Host Your Static Site With Kinsta for Free!</p>
        <a
            href="https://kinsta.com/docs/static-site-hosting/"
            target="_blank"
            class="btn"
            >Read More</a
        >
    </div>
</template>

<style> scoped>
    .banner {
        background: rgb(156, 85, 34);
        background: linear-gradient(
            90deg,
            rgba(156, 85, 34, 1) 0%,
            rgba(32, 50, 103, 1) 42%,
            rgba(13, 18, 25, 1) 69%,
            rgba(22, 47, 60, 1) 100%
        );
        color: #fff;
        padding: 20px;
        border-radius: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
    }
    .banner p {
        width: 600px;
        font-size: 40px;
        font-weight: bold;
        text-align: center;
        line-height: 50px;
    }
    .banner .btn {
        border-radius: 5px;
        padding: 15px;
        color: #1f1f1f;
        font-weight: bold;
        background: #fff;
        display: inline-block;
        margin-bottom: 10px;
    }
    .banner .btn:hover {
        background: #111319;
        color: #fff;
    }
</style>

その後、任意のMarkdownファイル内で、用意したコンポーネントを呼び出して使用することができます(名前はファイル名から推測されます)。

<HomeOptions/>
<HostingBanner/>

VuePressのコンポーネントについて詳しくはこちらのドキュメントをご覧ください。

ホームページのカスタマイズ

VuePressにはデフォルトのテーマがあります。あらかじめ用意されたデザインをそのまま利用可能です。このホームページレイアウトを利用するには、home: trueを指定し 、ルートのREADME.mdファイル内YAMLフロントマターにメタデータを含める必要があります。

以下がYAMLフロントマターの例です。

---
home: true
heroImage: /hero.png
heroText: Hero Title
tagline: Hero subtitle
actionText: Get Started →
actionLink: /guide/
features:
- title: Simplicity First
  details: Minimal setup with markdown-centered project structure helps you focus on writing.
- title: Vue-Powered
  details: Enjoy the dev experience of Vue + webpack, use Vue components in markdown, and develop custom themes with Vue.
- title: Performant
  details: VuePress generates pre-rendered static HTML for each page, and runs as an SPA once a page is loaded.
footer: MIT Licensed | Copyright © 2018-present Evan You
---

この設定により、ドキュメントのホームページは以下のようになります。

VuePress default homepage
VuePressのデフォルトのホームページデザイン

よりシンプルなレイアウトがお好みであれば、nullに設定することでheroTexttaglineなどの値を無効にすることができます。YAMLフロントマター(つまりメタデータセクション)の後にあるコンテンツは通常のMarkdownとして扱われ、featuresセクションの後にレンダリングされます。

完全なオリジナルデザインのホームページが必要であっても問題ありません。VuePressはカスタムレイアウトもサポートしています。さらに、Markdown Slot Syntaxを使用することで、リッチテキストのフッターを作成し、フッターコンテンツをより柔軟に表示することができます。以下はリッチテキストフッターの設定例です。

---
home: true
---

::: slot footer
Made with ❤️ by Kinsta. [Static Site Hosting](https://kinsta.com/static-site-hosting/)
:::

この場合、::: slot footerセクション内のコンテンツを編集することで、ホームページのフッターエリアにリンクなどの情報を追加することができます。

上記のカスタマイズ方法を理解したところで、先ほど作成したコンポーネントをホームページに追加し、いくつかの箇所を削除して、ホームページの見栄えを整えましょう。

---
home: true
tagline: A VuePress QuickStart for Kinsta
actionText: Quick Start →
actionLink: /guide/
---

<HomeOptions/>
<HostingBanner/>

::: slot footer
Made with ❤️ by Kinsta. [Static Site Hosting](https://kinsta.com/static-site-hosting/)
:::
Using components in VuePress homepage
VuePressのホームページでコンポーネントを使用する

ここまででご紹介したVuePressカスタマイズテクニックを取り入れることで、価値あるコンテンツを提供するだけでなく、ナビゲーションを整理しながら、魅力的なスタイルで優れたユーザーエクスペリエンスを提供することができるはずです。

デフォルトテーマのカスタマイズについてはこちらのドキュメントをご覧ください。

VuePressでブログセクションを構築する

VuePressサイトにブログセクションを追加するのは簡単です。自分でVueコンポーネントを書き、任意のMarkdownファイルに挿入できます。ブログ記事の一覧をレンダリングするコンポーネントを作ってみましょう。

componentsフォルダにBlogIndex.vueファイルを作成し、以下のコードを追加します。

<template>
    <div>
        <div v-for="post in posts" v-bind:key="post.path">
            <h2>
                <router-link> :to="post.path">{{ post.frontmatter.title }}</router-link>
            </h2>
            <p>{{ post.frontmatter.description }}</p>
            <p><router-link> :to="post.path">Read more</router-link></p>
        </div>
    </div>
</template>

<script>>
    export default {
        computed: {
            posts() {
                return this.$site.pages
                    .filter(
                        (x) => x.path.startsWith('/blog/') && !x.frontmatter.blog_index
                    )
                    .sort(
                        (a, b) =>
                            new Date(b.frontmatter.date) - new Date(a.frontmatter.date)
                    );
            },
        },
    };
</script>

上のコードでは、v-forを使用してブログ記事をループするVueテンプレートを定義し、各記事のタイトル、説明、「続きを読む」リンクを表示しています。

<script>セクションでは、ブログの記事を取得するVueコンポーネントをエクスポートします。投稿がパス(/blog/で始まる)とblog_indexフロントマター属性がないことに基づいてフィルタリングされます。そして、日付の降順でソートした上で、最新の投稿が最初に表示されます。

新しいブログ記事を作成する際には、フロントマター情報の一部として投稿日を指定する必要があります。そうすることで、新しい記事が最初に表示できます。

ブログ記事の格納場所については、プロジェクトのルートにblogという名前のフォルダを作成し、このフォルダにREADME.mdファイルを追加します。ここがブログのインデックスとなり、すべてのブログ記事を一覧表示するためのBlogIndexコンポーネントがここに組み込まれることになります。

---
blog_index: true
---

# Blog

Welcome To Our Blog

<BlogIndex />

blog_indexフロントマター属性を必ず追加するようにしてください。この属性によって、ブログインデックス自体が個々のブログ記事の一覧から除外されます。この属性は、BlogIndex.vueコンポーネントで投稿をフィルタリングするときに利用されます。

次に、すべてのブログ記事を格納するblogフォルダをプロジェクトのルートに用意し、各記事を作成します。例えば、first-post.mdファイルを作成し、以下のコンテンツを記述します。

---
title: "My Exciting VuePress Blog Journey"
date: 2023-09-28
description: "Exploring VuePress, a versatile static site generator, and sharing my experiences along the way."
---

# My Exciting VuePress Blog Journey

In this inaugural blog post, I embark on an exciting journey with VuePress, a powerful static site generator that's perfect for creating documentation, blogs, and more. As I delve into the world of VuePress, I'll be sharing my experiences, insights, and tips on making the most out of this fantastic tool.

各ブログ記事について、投稿タイトル、日付、その他の関連するメタデータなど、重要なフロントマターの情報を定義します。このように綿密に構成することで、ブログ記事がまとまった形で表示され、読みやすいサイトに仕上がります。

Adding blog to VuePress
VuePressにブログを追加する

最後に、.vuepress/config.jsファイルでブログのナビゲーションを追加します。

nav: [
            {
                text: 'Guide',
                link: '/guide/',
            },
            { text: 'Blog', link: '/blog/' },
            {
                text: 'Static Site Hosting',
                link: 'https://kinsta.com/static-site-hosting/',
            },
        ],

プラグインを追加したり、別のテーマを使用したり、独自のテーマを作成したりと、VuePressでできることはまだまだたくさんあります。

VuePress静的サイトをKinstaにデプロイする

Kinstaでは、100件までの静的ウェブサイト無料でホストすることができます。お好みのGitサービス(BitbucketGitHub、またはGitLab)にコードをプッシュし、Kinstaにデプロイすることが可能です。

ファイルをGitサービスにプッシュする前に、(コードプッシュ時にGitが除外するファイルとフォルダを指定するために)ルートに.gitignoreファイルを作成してください。

# dependencies
/node_modules

# build directory
./docs/.vuepress/dist
/public

この説明ではGitHubを使用することにします。GitHubにソースコードをプッシュするリポジトリを作成します。リポジトリの準備ができたら、以下の手順に従って静的サイトをKinstaにデプロイしてください。

  1. ログインするか、アカウントを作成してMyKinstaを表示
  2. お好みのGitサービスでKinstaを認証
  3. 左サイドバーの「静的サイト」をクリックし「サイトの追加」クリック
  4. デプロイしたいリポジトリとブランチを選択
  5. サイトに一意の名前を割り当てる
  6. 次の形式でビルド設定を追加
    • ビルドコマンドnpm run build
    • Nodeのバージョン16.20.0
    • 公開ディレクトリ./docs/.vuepress/distまたはpublic
  1. 最後に「サイトを作成」をクリック

これで完了です。数秒待てばサイトのデプロイ完了です。サイトのリンクが表示されます。必要に応じて、独自ドメインSSL証明書を追加することもできます。

静的サイトホスティングの代わりに、Kinstaのアプリケーションホスティングで静的サイトをデプロイすることも可能です。例えば、高度なスケーラビリティ、Dockerファイルを使用した柔軟なデプロイメント性能、リアルタイムと過去のデータを網羅する包括的な分析機能などが付帯します。

まとめ

VuePressは、ドキュメントサイトやブログサイトを素早く構築するのに便利な多機能ツールです。シンプルなセットアップ、カスタマイズのしやすいテーマ、プラグインにより、情報量が豊富で視覚的に美しいサイトを構築することができます。

早速VuePressサイトを作成し、Kinstaの静的サイトホスティングで無料でホスティングして、あなたの知識を世界に発信しましょう。

VuePressを利用して何かを構築したことはありますか?あなたのプロジェクト活用例や実際の経験について、以下のコメント欄でお聞かせください。

Joel Olawanle Kinsta

Kinstaでテクニカルエディターとして働くフロントエンド開発者。オープンソースをこよなく愛する講師でもあり、JavaScriptとそのフレームワークを中心に200件以上の技術記事を執筆している。