NewtとAstroを利用してブログを作成する
Table of contents
- 記事内で使用している主なソフトウェアのバージョン
- 概要
- 1. Astroのセットアップ
- 2. Newtのセットアップ
- 2-1. Appを追加する
- 2-2. スペースUID・App UID・モデルUIDを確認する
- 2-3. Newt CDN API Tokenを作成する
- 3. リクエストの準備
- 3-1. 環境変数の設定
- 3-2. newt-client-jsのインストール
- 3-3. APIクライアントの作成
- 4. 一覧ページの作成
- 4-1. 言語の設定とディスクリプションの設定をする
- 4-2. 投稿の型を定義する
- 4-3. 投稿一覧の取得メソッドを作成する
- 4-4. 投稿一覧を表示する
- 5. 詳細ページの作成
- 5-1. 動的ルーティングを設定する
- 5-2. 投稿詳細を表示する
- 次のステップ
このチュートリアルでは、Newtと Astro を利用して、ブログを作成する手順を紹介します。
具体的には、Newtで管理しているコンテンツの一覧ページと詳細ページを作る手順を紹介します。
記事内で使用している主なソフトウェアのバージョン
- Astro(
astro
): 3.0.8 - newt-client-js(
newt-client-js
): 3.2.6
概要
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
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@4.0.1" with binaries:
- create-astro
╭─────╮ Houston:
│ ◠ ◡ ◠ Initiating launch sequence...
╰─────╯
astro v3.0.8 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 ./astro-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 98.58s.
作成したプロジェクトに移動して、開発サーバーを立ち上げます。
$ cd astro-blog
$ yarn dev
http://localhost:4321/
にアクセスして、以下のような画面が表示されることを確認します。
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で作成したトークンの値を定義します。以下を、実際の値で置き換えて定義してください。
1NEWT_SPACE_UID=sample-for-docs
2NEWT_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
を指定しましょう。
1import { createClient } from 'newt-client-js'
2
3export const newtClient = createClient({
4 spaceUid: import.meta.env.NEWT_SPACE_UID,
5 token: import.meta.env.NEWT_CDN_API_TOKEN,
6 apiType: 'cdn',
7})
これで、NewtにAPIリクエストを送るための準備ができました。
4. 一覧ページの作成
4-1. 言語の設定とディスクリプションの設定をする
src/layouts/Layout.astro
を修正します。
言語の設定では、lang 属性を修正します。ここでは日本語 ja
を指定します。
また、引数として description
を渡すと、メタディスクリプションに設定されるようにします。
※ 背景色が黒だと少し見づらいため、htmlの background
のスタイルを削除しています。
---
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="description" content="Astro description" />
<meta name="description" content={description} />
<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>
</head>
<body>
<slot />
</body>
</html>
(省略)
html {
font-family: system-ui, sans-serif;
background: #13151A;
background-size: 224px;
}
(省略)
4-2. 投稿の型を定義する
はじめに、投稿の型 Article
を定義しておきます。
このチュートリアルでは、title
・slug
・body
のみを使うため、以下のように定義しておきます。
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
のみに制限します。
1---
2import Layout from '../layouts/Layout.astro'
3import { newtClient } from '../lib/newt'
4import type { Article } from '../lib/newt'
5
6const { items: articles } = await newtClient.getContents<Article>({
7 appUid: 'blog',
8 modelUid: 'article',
9 query: {
10 select: ['title', 'slug', 'body'],
11 },
12})
13---
14
15<Layout title="Newt・Astroブログ" description="NewtとAstroを利用したブログです">
16 <main></main>
17</Layout>
4-4. 投稿一覧を表示する
次に、投稿一覧を表示します。src/pages/index.astro
は以下のようになります。
1---
2import Layout from '../layouts/Layout.astro'
3import { newtClient } from '../lib/newt'
4import type { Article } from '../lib/newt'
5
6const { items: articles } = await newtClient.getContents<Article>({
7 appUid: 'blog',
8 modelUid: 'article',
9 query: {
10 select: ['title', 'slug', 'body'],
11 },
12})
13---
14
15<Layout title="Newt・Astroブログ" description="NewtとAstroを利用したブログです">
16 <main>
17 <ul>
18 {
19 articles.map((article) => {
20 return (
21 <li>
22 <a href={`/articles/${article.slug}`}>{article.title}</a>
23 </li>
24 )
25 })
26 }
27 </ul>
28 </main>
29</Layout>
ここでは詳細ページへのリンクとして、HTML標準の <a>
要素を利用しています。
詳細については、Astroの ページ間のリンク をご確認ください。
http://localhost:4321/
にアクセスして、以下のように投稿一覧が表示されれば成功です。
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と同じです。
1---
2import Layout from '../../layouts/Layout.astro'
3import { newtClient } from '../../lib/newt'
4import type { Article } from '../../lib/newt'
5
6export const getStaticPaths = async () => {
7 const { items: articles } = await newtClient.getContents<Article>({
8 appUid: 'blog',
9 modelUid: 'article',
10 query: {
11 select: ['title', 'slug', 'body'],
12 },
13 })
14 return articles.map((article) => ({
15 params: { slug: article.slug },
16 }))
17}
18---
19
20<Layout title="投稿詳細ページ" description="投稿詳細ページです">
21 <main></main>
22</Layout>
5-2. 投稿詳細を表示する
次に、投稿詳細を表示します。
ここでは getStaticPaths
の props を利用して、投稿データを渡しています。
src/pages/articles/[slug].astro
は以下のようになります。
1---
2import Layout from '../../layouts/Layout.astro'
3import { newtClient } from '../../lib/newt'
4import type { Article } from '../../lib/newt'
5
6export const getStaticPaths = async () => {
7 const { items: articles } = await newtClient.getContents<Article>({
8 appUid: 'blog',
9 modelUid: 'article',
10 query: {
11 select: ['title', 'slug', 'body'],
12 },
13 })
14 return articles.map((article) => ({
15 params: { slug: article.slug },
16 props: { article },
17 }))
18}
19
20const { article } = Astro.props
21---
22
23<Layout title={article.title} description="投稿詳細ページです">
24 <main>
25 <h2>{article.title}</h2>
26 <article set:html={article.body} />
27 </main>
28</Layout>
※ bodyの表示で利用されている set:html はXSSの危険性があるため、利用には注意が必要です。ここでは、Newtで管理している投稿情報を表示するものであり、不特定多数のユーザーが入力できるものを表示するわけではないため、安全なものとして利用しています。
これで、投稿詳細についての設定も完了です。
http://localhost:4321/articles/article-3
にアクセスして、以下のように投稿詳細が表示されれば成功です。
次のステップ
このチュートリアルを行うことで、Astroのプロジェクトを作成し、開発環境でコンテンツの取得・表示を行う方法を学習しました。
更に深く学習したい方は、以下のチュートリアルもおすすめです。
ホスティングを行いたい方
- GitHubのリポジトリとVercelを接続して、ホスティングする
- GitHubのリポジトリとNetlifyを接続して、ホスティングする
- GitHubのリポジトリとCloudflare Pagesを接続して、ホスティングする
問い合わせフォームを作成したい方
その他にも様々なチュートリアルを用意しているので、ぜひ チュートリアル のページもご確認ください。