NewtとSvelteKitを利用してブログを作成する
Table of contents
- 記事内で使用している主なソフトウェアのバージョン
- 概要
- 1. SvelteKitのセットアップ
- 2. Newtのセットアップ
- 2-1. Appを追加する
- 2-2. スペースUID・App UID・モデルUIDを確認する
- 2-3. Newt CDN API Tokenを作成する
- 3. リクエストの準備
- 3-1. 環境変数の設定
- 3-2. 型情報の生成
- 3-3. newt-client-jsのインストール
- 3-4. APIクライアントの作成
- 4. 一覧ページの作成
- 4-1. 言語の設定をする
- 4-2. 投稿の型を定義する
- 4-3. 投稿一覧を取得する
- 4-4. 投稿一覧を表示する
- 5. 詳細ページの作成
- 5-1. 投稿詳細を取得する
- 5-2. 投稿詳細を表示する
- 6. アダプターの設定
- 次のステップ
このチュートリアルでは、Newtと SvelteKit を利用して、ブログを作成する手順を紹介します。
具体的には、Newtで管理しているコンテンツの一覧ページと詳細ページを作る手順を紹介します。
記事内で使用している主なソフトウェアのバージョン
- SvelteKit(
@sveltejs/kit
): 2.5.1 - newt-client-js(
newt-cliet-js
): 3.3.0
概要
SvelteKitでプロジェクトを作成し、Newtのコンテンツ情報を取得できるようにします。
コンテンツの一覧ページ(パス: /
)と詳細ページ(パス: /articles/:slug
。slugがarticle-1の場合は /articles/article-1
)を作成し、ローカル環境で表示を行うまでを説明します。
また、ここではビルド時にHTMLを生成する、静的サイト生成(Static Site Generation)の方法を紹介します。
1. SvelteKitのセットアップ
はじめに、SvelteKitのセットアップを行います。create-svelte を利用することで、簡単にSvelteKitのプロジェクトを作成できます。
以下のコマンドを入力します。
npm create svelte@latest
コマンドを入力すると、以下の質問を聞かれるので、お好きな設定を選びましょう。
- どこにプロジェクトを作成するか(ここでは
./sveltekit-blog
としました) - どのappテンプレートを利用するか(ここでは
Skeleton project
を選択) - TypeScriptの型チェックを追加するか(ここでは
Yes, using TypeScript syntax
を選択) - 追加オプションの選択(ここでは
Add ESLint for code linting
とAdd Prettier for code formatting
を選択)
以下のように表示されます。
$ npm create svelte@latest
Need to install the following packages:
create-svelte@6.0.9
Ok to proceed? (y)
create-svelte version 6.0.9
┌ Welcome to SvelteKit!
│
◇ Where should we create your project?
│ ./sveltekit-blog
│
◇ Which Svelte app template?
│ Skeleton project
│
◇ Add type checking with TypeScript?
│ Yes, using TypeScript syntax
│
◇ Select additional options (use arrow keys/space bar)
│ Add ESLint for code linting, Add Prettier for code formatting
│
└ Your project is ready!
✔ Typescript
Inside Svelte components, use <script lang="ts">
✔ ESLint
https://github.com/sveltejs/eslint-plugin-svelte
✔ Prettier
https://prettier.io/docs/en/options.html
https://github.com/sveltejs/prettier-plugin-svelte#options
作成したプロジェクトに移動して、開発サーバーを立ち上げます。
$ cd sveltekit-blog
$ yarn install
$ yarn dev
http://localhost:5173/
にアクセスして、以下のような画面が表示されることを確認します。
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. 環境変数の設定
SvelteKitの環境変数は、プロジェクトディレクトリの .env
ファイルから読み込めます。
ここでは、.env
ファイルを作成し、2-2で確認したスペースUID、2-3で作成したトークンの値を定義します。以下を、実際の値で置き換えて定義してください。
1NEWT_SPACE_UID=sample-for-docs
2NEWT_CDN_API_TOKEN=xxxxxxxxxxxxxxx
上記のように定義しておくと、以下のような形で利用できます。
import { NEWT_SPACE_UID, NEWT_CDN_API_TOKEN } from '$env/static/private'
ここで使われている $env/static/private ですが、この static
は、これらの環境変数がビルド時に解決され、静的に置き換えられることを示しています。
クライアントサイドに公開しても安全な環境変数の場合、$env/static/public も利用できます。
またビルド時ではなく、実行時に環境変数の値を読みこむ必要がある場合、$env/dynamic/private や $env/dynamic/public も利用できます。
3-2. 型情報の生成
3-1で定義した環境変数ですが、このままでは型情報が生成されておらず、以下のようなエラーが出てしまいます。
Module '"$env/static/private"' has no exported member 'NEWT_SPACE_UID'.
型情報を生成するためには、以下のどちらかを行う必要があります。
- package.jsonの
scripts
で定義されているdev
コマンドの実行(vite dev
の実行) - package.jsonの
scripts
で定義されているcheck
コマンドの実行(svelte-kit sync
の実行)
環境変数以外にも、このあと $lib
の型などを生成する必要があるので、ここでは dev
コマンドを実行したまま、以下の作業を進めていきます。
npm run dev
# or
yarn dev
3-3. newt-client-jsのインストール
次に newt-client-js をインストールします。
npm install newt-client-js
# or
yarn add newt-client-js
3-4. APIクライアントの作成
CDN APIを利用するためのクライアントを作成します。ここではサーバーサイドでのみ読み込めれば良いので、src/lib/server
ディレクトリを作成し、その中に newt.ts
というファイルを作成します。
※ サーバー専用のモジュールについて、詳細はSvelteKitの Server-only modules のドキュメントをご確認ください。
spaceUid
と token
のところには3-1で設定した環境変数を入力します。
ここではCDN APIを利用するので、apiType
には cdn
を指定しましょう。
1import { createClient } from 'newt-client-js'
2import { NEWT_SPACE_UID, NEWT_CDN_API_TOKEN } from '$env/static/private'
3
4export const newtClient = createClient({
5 spaceUid: NEWT_SPACE_UID,
6 token: NEWT_CDN_API_TOKEN,
7 apiType: 'cdn'
8})
これで、NewtにAPIリクエストを送るための準備ができました。
4. 一覧ページの作成
4-1. 言語の設定をする
src/app.html
にある lang 属性を修正します。ここでは日本語 ja
を指定します。
<!DOCTYPE html>
<html lang="en">
<html lang="ja">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
4-2. 投稿の型を定義する
はじめに、投稿の型 Article
を定義しておきます。
このチュートリアルでは、_id
・title
・slug
・body
のみを使うため、以下のように定義しておきます。
import { createClient } from 'newt-client-js'
import { NEWT_SPACE_UID, NEWT_CDN_API_TOKEN } from '$env/static/private'
export interface Article {
_id: string
title: string
slug: string
body: string
}
export const newtClient = createClient({
spaceUid: NEWT_SPACE_UID,
token: NEWT_CDN_API_TOKEN,
apiType: 'cdn'
})
4-3. 投稿一覧を取得する
SvelteKitはファイルシステムベースのルーティングを採用しており、src/routes
配下のディレクトリによって、ルートが定義されます。
例えば、以下のようにルートが作成されます。
src/routes/blog
→/blog
※ ルーティングの詳細については、SvelteKitの ルーティング のドキュメントをご確認ください。
ここではトップページ(パス: /
)で投稿一覧を表示したいので、src/routes
のディレクトリ内にファイルを作成します。
ルートディレクトリの中には、1つ以上のルートファイルを格納します。ルートファイルには +
という接頭辞が付いているので、それで見分けることができます。
SvelteKitのページでは、レンダリングの前にデータを読み込む場合、+page.ts
または +page.server.ts
で load
関数をエクスポートします。ここでは load
関数をサーバー上でのみ実行したいので +page.server.ts
を作成します。
データの取得について、詳細はSvelteKitの Loading data のドキュメントをご確認ください。
以下のように記載します。
1import { newtClient } from '$lib/server/newt'
2import type { Article } from '$lib/server/newt'
3import type { PageServerLoad } from './$types'
4
5export const load: PageServerLoad = async () => {
6 const { items: articles } = await newtClient.getContents<Article>({
7 appUid: 'blog',
8 modelUid: 'article',
9 query: {
10 select: ['_id', 'title', 'slug', 'body']
11 }
12 })
13 return {
14 articles
15 }
16}
※ Cannot find module '$lib/server/newt' or its corresponding type declarations.
のエラーが発生した場合は、3-2でやったように、再び dev
コマンドまたは check
コマンドを実行してください。
npm run dev
# or
yarn dev
load
関数では、投稿一覧を取得するために、SDKが提供している getContents メソッドを利用します。getContentsはNewtのコンテンツ一覧を取得するためのメソッドです。getContentsのパラメータに Article
の型を渡すことで、返却される items
の型として Article[]
が指定されます。
また、selectパラメータを利用して、取得するフィールドを _id
・title
・slug
・body
のみに制限します。
4-4. 投稿一覧を表示する
次に、投稿一覧を表示します。
src/routes/+page.svelte
ファイルを修正します。
+page.svelte
では load
関数の戻り値を data
プロパティを介して使用できます。
ここでは4-3で取得した articles
をもとに、eachブロック を利用して、投稿一覧を表示します。
タイトルとディスクリプションは titleとmeta に記載があるように <svelte:head>
の内側に記載します。
1<script lang="ts">
2 import type { PageData } from './$types'
3 export let data: PageData
4</script>
5
6<svelte:head>
7 <title>Newt・SvelteKitブログ</title>
8 <meta name="description" content="NewtとSvelteKitを利用したブログです" />
9</svelte:head>
10
11<main>
12 <ul>
13 {#each data.articles as article (article._id)}
14 <li>
15 <a href={`articles/${article.slug}`}>{article.title}</a>
16 </li>
17 {/each}
18 </ul>
19</main>
ここでは詳細ページへのリンクとして、HTML標準の <a>
要素を利用しています。
詳細については、SvelteKitの Link options をご確認ください。
http://localhost:5173/
にアクセスして、以下のように投稿一覧が表示されれば成功です。
5. 詳細ページの作成
5-1. 投稿詳細を取得する
SvelteKitでは src/routes/blog/[slug]
のようにしてディレクトリ名に角括弧を使うことで動的なルートを作成します。
※ ルーティングの詳細については、SvelteKitの ルーティング のドキュメントをご確認ください。
ここでは、/articles/:slug
(/articles/article-1
など)のパスで投稿の詳細を表示したいので、src/routes/articles/[slug]
のディレクトリを作成します。
+page.server.ts
を作成し、load
関数を定義します。
1import { newtClient } from '$lib/server/newt'
2import type { Article } from '$lib/server/newt'
3import type { PageServerLoad } from './$types'
4
5export const load: PageServerLoad = async ({ params }) => {
6 const article = await newtClient.getFirstContent<Article>({
7 appUid: 'blog',
8 modelUid: 'article',
9 query: {
10 slug: params.slug,
11 select: ['_id', 'title', 'slug', 'body']
12 }
13 })
14 return {
15 article
16 }
17}
投稿詳細を取得するメソッドとして、SDKが提供している getFirstContent を利用しています。このメソッドはクエリに該当するコンテンツのうち、最初の1件を返却するメソッドです。指定したスラッグのコンテンツを取得したい場合は、このメソッドを利用します。
5-2. 投稿詳細を表示する
5-1で取得した article
を利用して、投稿詳細を表示します。
1<script lang="ts">
2 import type { PageData } from './$types'
3 export let data: PageData
4</script>
5
6<svelte:head>
7 <title>{data.article?.title}</title>
8 <meta name="description" content="投稿詳細ページです" />
9</svelte:head>
10
11<main>
12 <h1>{data.article?.title}</h1>
13 <div>{@html data.article?.body}</div>
14</main>
※ bodyの表示で利用されている @html はXSSの危険性があるため、利用には注意が必要です。ここでは、Newtで管理している投稿情報を表示するものであり、不特定多数のユーザーが入力できるものを表示するわけではないため、安全なものとして利用しています。
これで、投稿詳細についての設定も完了です。
http://localhost:5173/articles/article-3
にアクセスして、以下のように投稿詳細が表示されれば成功です。
6. アダプターの設定
静的サイト生成(Static Site Generation)するためのアダプター設定を行います。
はじめに @sveltejs/adapter-static
をインストールします。
npm install -D @sveltejs/adapter-static
# or
yarn add -D @sveltejs/adapter-static
次に、svelte.config.js
の adapter
を以下のように設定します。
各オプションの詳細はSvelteKitの Static site generation のドキュメントをご確認ください。
import adapter from '@sveltejs/adapter-auto'
import adapter from '@sveltejs/adapter-static'
import { vitePreprocess } from '@sveltejs/kit/vite'
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null,
precompress: false,
strict: true
})
}
}
export default config
また、デプロイ先がVercelの場合は、ゼロコンフィグサポート があります。
以下のように adapter
のオプションを省略すると、adapter-static
が最適な設定を提供できるようになります。
1import adapter from '@sveltejs/adapter-static'
2import { vitePreprocess } from '@sveltejs/kit/vite'
3
4/** @type {import('@sveltejs/kit').Config} */
5const config = {
6 // Consult https://kit.svelte.dev/docs/integrations#preprocessors
7 // for more information about preprocessors
8 preprocess: vitePreprocess(),
9
10 kit: {
11 // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
12 // If your environment is not supported or you settled on a specific environment, switch out the adapter.
13 // See https://kit.svelte.dev/docs/adapters for more information about adapters.
14 adapter: adapter()
15 }
16}
17
18export default config
最後に prerender
オプションを最上位のレイアウトに追加します。
src/routes/+layout.ts
を作成し、以下の内容を記載します。
1export const prerender = true
これでサイト全体を、静的なファイルのコレクションとしてプリレンダリングできるようになりました。
次のステップ
このチュートリアルを行うことで、SvelteKitのプロジェクトを作成し、開発環境でコンテンツの取得・表示を行う方法を学習しました。
更に深く学習したい方は、以下のチュートリアルもおすすめです。
ホスティングを行いたい方
問い合わせフォームを作成したい方
その他にも様々なチュートリアルを用意しているので、ぜひ チュートリアル のページもご確認ください。