NewtとAstro v4を利用してブログを作成する
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
): 4.11.3 - newt-client-js(
newt-client-js
): 3.3.3
概要
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
を選択) - TypeScriptを利用するか(ここでは
Yes
を選択) - TypeScriptの設定をどうするか(ここでは
Strict
を選択) - dependenciesをインストールするか(ここでは
Yes
を選択) - gitリポジトリを初期化するか?(ここでは
Yes
を選択)
yarnを利用した場合、以下のように表示されます。
$ yarn create astro
yarn create v1.22.22
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Installed "create-astro@4.8.0" with binaries:
- create-astro
[################################################] 48/48
astro 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
ts Do you plan to write TypeScript?
Yes
use How strict should TypeScript be?
Strict
deps Install dependencies?
Yes
git Initialize a new git repository?
Yes
✔ Project initialized!
■ Template copied
■ TypeScript customized
■ Dependencies installed
■ 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 37.53s.
作成したプロジェクトに移動して、開発サーバーを立ち上げます。
$ 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のプロジェクトを作成し、開発環境でコンテンツの取得・表示を行う方法を学習しました。
更に深く学習したい方は、以下のチュートリアルもおすすめです。
ホスティングを行いたい方
問い合わせフォームを作成したい方
その他にも様々なチュートリアルを用意しているので、ぜひ チュートリアル のページもご確認ください。