0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Astroを使ってマークダウンファイルをアップロードするだけで公開できるWebサイトを構築

Posted at

注意:この記事はAIが作成しています
参照元の存在、参考元のリンクの信頼度、事実の歪曲がないかをAIによりセルフチェックしています

Astroを使ってマークダウンファイルをアップロードするだけで公開できるWebサイトを構築

はじめに

静的サイトジェネレーター(SSG)の選択肢が増える中、Astroは特にコンテンツ重視のWebサイト構築において注目を集めています。本記事では、Astroを使用してマークダウンファイルを配置するだけで即座に公開可能なWebサイトを構築する方法と、Remarkプラグインを活用した機能拡張について解説します。

Astroとは

Astroは、2021年にリリースされた比較的新しい静的サイトジェネレーターです。「Islands Architecture(アイランドアーキテクチャ)」という設計思想を採用し、必要な部分にのみJavaScriptを使用することで、高速なWebサイトを実現します。

Astroの主な特徴

  • ゼロJavaScript by デフォルト: 静的なHTMLを生成し、必要最小限のJavaScriptのみを送信
  • マルチフレームワーク対応: React、Vue、Svelte、SolidJSなど複数のフレームワークを同時に使用可能
  • 優れたDX(開発者体験): TypeScript、Sass、Tailwind CSSなどをネイティブサポート
  • コンテンツファースト: マークダウンやMDXを第一級市民として扱う

プロジェクトのセットアップ

1. Astroプロジェクトの初期化

# npmを使用する場合
npm create astro@latest my-markdown-site

# yarnを使用する場合
yarn create astro my-markdown-site

# pnpmを使用する場合
pnpm create astro@latest my-markdown-site

セットアップウィザードでは以下を選択します:

  • テンプレート: "Empty" または "Blog"
  • TypeScript: "Strict"(推奨)
  • 依存関係のインストール: Yes

2. ディレクトリ構造

my-markdown-site/
├── src/
│   ├── content/
│   │   └── blog/        # マークダウンファイルを配置
│   ├── layouts/
│   │   └── BlogPost.astro
│   └── pages/
│       ├── index.astro
│       └── blog/
│           └── [...slug].astro
├── astro.config.mjs
└── package.json

コンテンツコレクションの設定

1. コンテンツスキーマの定義

src/content/config.tsを作成し、記事のスキーマを定義します:

import { defineCollection, z } from 'astro:content';

const blogCollection = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.date(),
    author: z.string(),
    tags: z.array(z.string()).optional(),
    image: z.string().optional(),
  }),
});

export const collections = {
  blog: blogCollection,
};

2. マークダウンファイルの作成

src/content/blog/ディレクトリに.mdファイルを配置:

---
title: "Astroで始める静的サイト構築"
description: "Astroを使った効率的なWebサイト開発"
pubDate: 2024-01-15
author: "開発太郎"
tags: ["Astro", "SSG", "Web開発"]
---

# 記事の内容

ここに記事の本文を記述します...

動的ルーティングの実装

ブログ記事ページの作成

src/pages/blog/[...slug].astroを作成:

---
import { getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';

export async function getStaticPaths() {
  const blogEntries = await getCollection('blog');
  return blogEntries.map(entry => ({
    params: { slug: entry.slug },
    props: { entry },
  }));
}

const { entry } = Astro.props;
const { Content } = await entry.render();
---

<BlogPost {...entry.data}>
  <Content />
</BlogPost>

Remarkプラグインによる拡張

1. 基本的なRemarkプラグインの導入

npm install remark-gfm remark-toc rehype-slug rehype-autolink-headings

2. astro.config.mjsの設定

import { defineConfig } from 'astro/config';
import remarkGfm from 'remark-gfm';
import remarkToc from 'remark-toc';
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';

export default defineConfig({
  markdown: {
    remarkPlugins: [
      remarkGfm,           // GitHub Flavored Markdown対応
      [remarkToc, { 
        heading: '目次',
        tight: true 
      }],
    ],
    rehypePlugins: [
      rehypeSlug,          // 見出しにIDを付与
      [rehypeAutolinkHeadings, {
        behavior: 'append',
        content: {
          type: 'text',
          value: ' 🔗'
        }
      }],
    ],
  },
});

3. カスタムRemarkプラグインの作成

独自の処理を追加する例:

// plugins/remark-reading-time.mjs
import getReadingTime from 'reading-time';
import { toString } from 'mdast-util-to-string';

export function remarkReadingTime() {
  return function (tree, { data }) {
    const textOnPage = toString(tree);
    const readingTime = getReadingTime(textOnPage);
    data.astro.frontmatter.minutesRead = Math.ceil(readingTime.minutes);
  };
}

設定への追加:

import { remarkReadingTime } from './plugins/remark-reading-time.mjs';

export default defineConfig({
  markdown: {
    remarkPlugins: [
      remarkReadingTime,
      // 他のプラグイン...
    ],
  },
});

高度な機能実装

1. シンタックスハイライト

// astro.config.mjs
export default defineConfig({
  markdown: {
    shikiConfig: {
      theme: 'github-dark',
      langs: ['javascript', 'typescript', 'python'],
      wrap: true,
    },
  },
});

2. 画像最適化

---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---

<Image 
  src={heroImage} 
  alt="Hero画像"
  width={800}
  height={400}
  format="webp"
/>

3. MDXサポート

npm install @astrojs/mdx
// astro.config.mjs
import mdx from '@astrojs/mdx';

export default defineConfig({
  integrations: [mdx()],
});

デプロイと自動化

GitHub Actionsを使用した自動デプロイ

# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]
    paths:
      - 'src/content/**/*.md'
      - 'src/**/*.astro'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      
      - run: npm ci
      - run: npm run build
      
      - uses: actions/upload-pages-artifact@v2
        with:
          path: ./dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v2

パフォーマンス最適化のフロー

ベストプラクティス

1. コンテンツの構造化

  • フロントマターでメタデータを統一管理
  • タグやカテゴリーによる分類
  • 日付形式の統一(ISO 8601推奨)

2. パフォーマンス向上施策

  • 画像の遅延読み込み
  • フォントの最適化
  • Critical CSSの抽出
  • プリフェッチの活用

3. SEO対策

---
// SEOコンポーネント
export interface Props {
  title: string;
  description: string;
  image?: string;
}

const { title, description, image = '/og-image.jpg' } = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
---

<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonicalURL} />

<!-- Open Graph -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<meta property="og:url" content={canonicalURL} />

トラブルシューティング

よくある問題と解決策

  1. ビルドエラー: フロントマターの形式を確認
  2. 画像が表示されない: 相対パスとpublicディレクトリの使い分け
  3. Remarkプラグインが動作しない: プラグインの順序と設定を確認

まとめ

Astroを使用することで、マークダウンファイルを配置するだけで高品質なWebサイトを構築できます。Remarkプラグインエコシステムを活用することで、目次生成、シンタックスハイライト、読了時間表示など、様々な機能を簡単に追加できます。

静的サイトジェネレーターとしてのAstroの強みは、開発者体験の良さと生成されるサイトのパフォーマンスの高さにあります。コンテンツ重視のWebサイトを構築する際は、ぜひAstroの採用を検討してください。

参照リンク

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?