- チュートリアル
- フレームワーク
NewtとAstroを利用してブログを作成する
このチュートリアルでは、Newtと Astro を利用して、ブログを作成する手順を紹介します。
具体的には、Newtで管理しているコンテンツの一覧ページと詳細ページを作る手順を紹介します。
記事内で使用している主なソフトウェアのバージョン
- Astro(
astro
): 2.3.0 - newt-client-js(
newt-client-js
): 3.2.4
概要
Astroでプロジェクトを作成し、Newtのコンテンツ情報を取得できるようにします。
コンテンツの一覧ページ(パス: /
)と詳細ページ(パス: /articles/:slug
。slugがarticle-1の場合は /articles/article-1
)を作成し、ローカル環境で表示を行うまでを説明します。
また、ここではビルド時にHTMLを生成する、静的生成(Static Generation)の方法を紹介します。
1. Astroのセットアップ
はじめに、Astroのセットアップを行います。create-astro を利用することで、簡単にAstroのプロジェクトを作成できます。
以下のどれかのコマンドを入力します。
npm create astro@latest
# or
pnpm create astro@latest
# or
yarn create astro
コマンドを入力すると、以下の質問を聞かれるので、お好きな設定を選びましょう。
- どこにプロジェクトを作成するか(ここでは
./astro-blog
と入力) - プロジェクトをどのように始めるか(ここでは
Include sample files
を選択) - dependenciesをインストールするか(ここでは
Yes
を選択) - TypeScriptを利用するか(ここでは
Yes
を選択) - TypeScriptの設定をどうするか(ここでは
Strict
を選択) - gitリポジトリを初期化するか?(ここでは
Yes
を選択)
yarnを利用した場合、以下のように表示されます。
$ yarn create astro 14:15:31
yarn create v1.22.19
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Installed "create-astro@3.1.3" with binaries:
- create-astro
╭─────╮ Houston:
│ ◠ ◡ ◠ Let's create a new project!
╰─────╯
astro v2.3.0 Launch sequence initiated.
dir Where should we create your new project?
./astro-blog
tmpl How would you like to start your new project?
Include sample files
✔ Template copied
deps Install dependencies?
Yes
✔ Dependencies installed
ts Do you plan to write TypeScript?
Yes
use How strict should TypeScript be?
Strict
✔ TypeScript customized
git Initialize a new git repository?
Yes
✔ Git initialized
next Liftoff confirmed. Explore your project!
Enter your project directory using cd ./astro2.3.0-blog
Run yarn dev to start the dev server. CTRL+C to stop.
Add frameworks like react or tailwind using astro add.
Stuck? Join us at https://astro.build/chat
╭─────╮ Houston:
│ ◠ ◡ ◠ Good luck out there, astronaut! 🚀
╰─────╯
✨ Done in 69.45s.
作成したプロジェクトに移動して、開発サーバーを立ち上げます。
$ cd astro-blog
$ yarn dev
http://localhost:3000/
にアクセスして、以下のような画面が表示されることを確認します。
2. Newtのセットアップ
次にNewtにコンテンツとAPIトークンを用意し、コンテンツの取得を行うための準備を行います。
2-1. Appを追加する
「Appを追加」をクリックして「テンプレートから追加」を選択します。
表示されるテンプレートの中から「Blog」を選択して、「このテンプレートを追加」をクリックします。
テンプレートが追加されると、「投稿データ」「カテゴリデータ」「著者データ」が追加されます。
2-2. スペースUID・App UID・モデルUIDを確認する
スペースUIDは「スペース設定」から確認できます。
上記の例だと、スペースUIDは sample-for-docs
となります。
この値は3-1で環境変数として定義します。
また「Blog」テンプレートを追加した場合、App UIDは blog
、「投稿データ」モデルUIDは article
となります。
これらの値は、4-3や5-1で投稿情報を取得する際に利用します。
2-3. Newt CDN API Tokenを作成する
続いて、APIリクエストに必要なトークンを発行します。
スペース設定 > APIキー のページからNewt CDN API Tokenを作成します。
名前と取得対象を決めて「作成」を押します。
ここで作成したトークンの値は3-1で環境変数として定義します。
3. リクエストの準備
Newtの SDK を利用することで、NewtのAPIをより簡単に利用できます。
ここではSDKを利用して、NewtのAPIクライアントを作成します。
3-1. 環境変数の設定
Astroの環境変数は、プロジェクトディレクトリの .env
ファイルから読み込めます。詳細はAstroの 環境変数 のドキュメントをご確認ください。
ここでは、.env
ファイルを作成し、2-2で確認したスペースUID、2-3で作成したトークンの値を定義します。以下を、実際の値で置き換えて定義してください。
NEWT_SPACE_UID=sample-for-docs
NEWT_CDN_API_TOKEN=xxxxxxxxxxxxxxx
上記のように定義しておくと、import.meta.env.NEWT_SPACE_UID
や import.meta.env.NEWT_CDN_API_TOKEN
として利用できるようになります。
また、src/env.d.ts
で ImportMetaEnv
を以下のように設定することで、環境変数の自動補完が効くようになります。
/// <reference types="astro/client" />
+ interface ImportMetaEnv {
+ readonly NEWT_SPACE_UID: string
+ readonly NEWT_CDN_API_TOKEN: string
+ }
3-2. newt-client-jsのインストール
次に newt-client-js をインストールします。
npm install newt-client-js
# or
yarn add newt-client-js
3-3. APIクライアントの作成
CDN APIを利用するためのクライアントを作成します。
spaceUid
と token
のところには3-1で設定した環境変数を入力します。
ここではCDN APIを利用するので、apiType
には cdn
を指定しましょう。
// src/lib/newt.ts
import { createClient } from 'newt-client-js'
export const newtClient = createClient({
spaceUid: import.meta.env.NEWT_SPACE_UID,
token: import.meta.env.NEWT_CDN_API_TOKEN,
apiType: 'cdn',
})
これで、NewtにAPIリクエストを送るための準備ができました。
4. 一覧ページの作成
4-1. 言語の設定とディスクリプションの設定をする
src/layouts/Layout.astro
を修正します。
言語の設定では、lang 属性を修正します。ここでは日本語 ja
を指定します。
また、引数として description
を渡すと、メタディスクリプションとして設定されるようにします。
---
export interface Props {
title: string
+ description: string
}
- const { title } = Astro.props
+ const { title, description } = Astro.props
---
<!DOCTYPE html>
- <html lang="en">
+ <html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
+ <meta name="description" content={description} />
</head>
<body>
<slot />
</body>
</html>
4-2. 投稿の型を定義する
はじめに、投稿の型 Article
を定義しておきます。
このチュートリアルでは、title
・slug
・body
のみを使うため、以下のように定義しておきます。
// src/lib/newt.ts
import { createClient } from 'newt-client-js'
+ export interface Article {
+ title: string
+ slug: string
+ body: string
+ }
export const newtClient = createClient({
spaceUid: import.meta.env.NEWT_SPACE_UID,
token: import.meta.env.NEWT_CDN_API_TOKEN,
apiType: 'cdn',
})
4-3. 投稿一覧の取得メソッドを作成する
Astroはファイルベースルーティングを採用しており、src/pages
ディレクトリの配下にファイルを作成すると、自動的にルートとして利用できるようになります。
例えば、以下のようにルーティングされます。
src/pages/blog/index.astro
→/blog
src/pages/blog/first-post.astro
→/blog/first-post
※ ルーティングの詳細については、Astroの 静的ルーティング のドキュメントをご確認ください。
ここではトップページ(パス: /
)で投稿一覧を表示したいので、src/pages/index.astro
のファイルを修正します。
投稿一覧を取得するために、SDKが提供している getContents メソッドを利用します。getContentsはNewtのコンテンツ一覧を取得するためのメソッドです。getContentsのパラメータに Article
の型を渡すことで、返却される items
の型として Article[]
が指定されます。
また、selectパラメータを利用して、取得するフィールドを title
・slug
・body
のみに制限します。
// src/pages/index.astro
---
import Layout from '../layouts/Layout.astro'
import { newtClient } from '../lib/newt'
import type { Article } from '../lib/newt'
const { items: articles } = await newtClient.getContents<Article>({
appUid: 'blog',
modelUid: 'article',
query: {
select: ['title', 'slug', 'body'],
},
})
---
<Layout title="Newt・Astroブログ" description="NewtとAstroを利用したブログです">
<main></main>
</Layout>
4-4. 投稿一覧を表示する
次に、投稿一覧を表示します。src/pages/index.astro
は以下のようになります。
// src/pages/index.astro
---
import Layout from '../layouts/Layout.astro'
import { newtClient } from '../lib/newt'
import type { Article } from '../lib/newt'
const { items: articles } = await newtClient.getContents<Article>({
appUid: 'blog',
modelUid: 'article',
query: {
select: ['title', 'slug', 'body'],
},
})
---
<Layout title="Newt・Astroブログ" description="NewtとAstroを利用したブログです">
<main>
<ul>
{
articles.map((article) => {
return (
<li>
<a href={`/articles/${article.slug}`}>{article.title}</a>
</li>
)
})
}
</ul>
</main>
</Layout>
ここでは詳細ページへのリンクとして、HTML標準の <a>
要素を利用しています。
詳細については、Astroの ページ間のリンク をご確認ください。
http://localhost:3000/
にアクセスして、以下のように投稿一覧が表示されれば成功です。
5. 詳細ページの作成
5-1. 動的ルーティングを設定する
Astroで 動的ルーティング を設定するためには、以下の2つが必要です。
src/pages/blog/[slug].astro
やsrc/pages/[username]/settings.astro
のように、角括弧を使って動的なパラメータを識別することgetStaticPaths()
関数をエクスポートして、Astroでプリレンダリングされるパスを正確に指定すること
まず、ここでは /articles/:slug
(/articles/article-1
など)のパスで投稿の詳細を表示したいので、src/pages/articles/[slug].astro
のファイルを作成します。
次に getStaticPaths() 関数を作成します。この関数の params キーによって、どのパスがプリレンダリングされるか決まります。
ここでは全投稿のスラッグを定義するため、以下のように params
を指定します。
投稿一覧を取得する部分は4-3と同じです。
// src/pages/articles/[slug].astro
---
import Layout from '../../layouts/Layout.astro'
import { newtClient } from '../../lib/newt'
import type { Article } from '../../lib/newt'
export const getStaticPaths = async () => {
const { items: articles } = await newtClient.getContents<Article>({
appUid: 'blog',
modelUid: 'article',
query: {
select: ['title', 'slug', 'body'],
},
})
return articles.map((article) => ({
params: { slug: article.slug },
}))
}
---
<Layout title="投稿詳細ページ" description="投稿詳細ページです">
<main></main>
</Layout>
5-2. 投稿詳細を表示する
次に、投稿詳細を表示します。
ここでは getStaticPaths
の props を利用して、投稿データを渡しています。
src/pages/articles/[slug].astro
は以下のようになります。
// src/pages/articles/[slug].astro
---
import Layout from '../../layouts/Layout.astro'
import { newtClient } from '../../lib/newt'
import type { Article } from '../../lib/newt'
export const getStaticPaths = async () => {
const { items: articles } = await newtClient.getContents<Article>({
appUid: 'blog',
modelUid: 'article',
query: {
select: ['title', 'slug', 'body'],
},
})
return articles.map((article) => ({
params: { slug: article.slug },
props: { article },
}))
}
const { article } = Astro.props
---
<Layout title={article.title} description="投稿詳細ページです">
<main>
<h2>{article.title}</h2>
<article set:html={article.body} />
</main>
</Layout>
※ bodyの表示で利用されている set:html はXSSの危険性があるため、利用には注意が必要です。ここでは、Newtで管理している投稿情報を表示するものであり、不特定多数のユーザーが入力できるものを表示するわけではないため、安全なものとして利用しています。
これで、投稿詳細についての設定も完了です。
http://localhost:3000/articles/article-3
にアクセスして、以下のように投稿詳細が表示されれば成功です。
次のステップ
このチュートリアルを行うことで、Astroのプロジェクトを作成し、開発環境でコンテンツの取得・表示を行う方法を学習しました。
更に深く学習したい方は、以下のチュートリアルもおすすめです。
ホスティングを行いたい方
- GitHubのリポジトリとVercelを接続して、ホスティングする
- GitHubのリポジトリとNetlifyを接続して、ホスティングする
- GitHubのリポジトリとCloudflare Pagesを接続して、ホスティングする
問い合わせフォームを作成したい方
その他にも様々なチュートリアルを用意しているので、ぜひ チュートリアル のページもご確認ください。