SvelteKitの基本を Svelte Tutorialで学ぼう
2022年12月15日に、SvelteKitが正式リリースされました。SvelteKitは、ReactのNext.jsやVue.jsのNuxt等と同様に、SvelteというJavaScriptライブラリを利用したフレームワークです。
複数のページで構成されるWebサイトを制作したり、データベースと連携したアプリを開発したりでき、Next.jsやNuxtに比べるとシンプルで作りやすい印象があります。
ここでは、Svelteを学習できる「Svelte Tutorial」のSvelteKitのセクションを進めながら、説明が英語なので日本語で補足をしていきましょう。
Svelteチュートリアルを起動しよう
Svelteチュートリアルは、Svelteのドキュメントからアクセスできます。
最初はSvelte自身のチュートリアルが展開されるので、SvelteKitのチュートリアルは次のページから始まります。
すると、左側に説明が、右側にエディター(上部)とブラウザー(下部)に展開されます。上部のエディターのファイルを変更すると、すぐに下のWebブラウザで確認できます。

例えば今、<h1>
要素があるので内容を書き換えると、リアルタイムに書き換わることが確認できます。

Svelteを体験しよう
SvelteKitを利用して生成されたページには、Svelteを利用する事ができます。Svelteでは、{ ... }
という記述を埋め込むと、変数の内容を等をリアルタイムに反映できます。まずは、次のように変数を宣言しましょう。Svelteでは、ファイルの上部に<script>
タグを埋め込めます。
<script>
let name = 'ともすた'
</script>
<h1>Welcome to tomosta</h1>
...
そしたら、本文内に次のように埋め込んでみましょう。
...
<h1>Welcome to { name }</h1>
変数の内容を変更すれば、リアルタイムに書き換わります。

ファイルの構成を確認しよう
SvelteKitはインストールすると、次のようなフォルダーやファイルが自動で生成されます。
- src/app.html
このファイルが実際にWebブラウザに表示されます<head>
要素を変えたい場合などはこのファイルを変更します - src/routes
各ページのファイルが格納されます - static
画像ファイルなどのリソースファイルなどを格納します - svelte.config.js
SvelteKitの設定ファイルです
この他、Node.jsの設定を行う「package.json」と、Viteというビルドツールの設定ファイルである「vite.config.js」が設置されていますが、これらについてはここでは省略します。「Node.js」や「Vite」などを学習しましょう。
ページを増やそう
左側の画面下にある、次ページへのリンクを何度かクリックして「Pages」というページまで移動しましょう。図のように、「home」と「about」というナビゲーションがあるページが表示されます。

しかし、現状では「about」をクリックしてもページが見つかりません。そこで、このアドレスにページを追加しましょう。
SvelteKitは、src/routes
フォルダーの中に特定の名前でフォルダーやファイルを作成すると、自動的にアドレスが生成されるしくみです。例えば、/about
というアドレスを作りたい場合は、/src/
フォルダーの中にabout
という名前のフォルダーを作成します。

そしたら、このフォルダーの中に+page.svelte
という名前のファイルを作成しましょう。ファイル名の先頭が「+」になっていたり、拡張子が.svelte
となっていますが、このファイル名で固定になっています。

これでファイルを作れば、すぐにアクセスができるようになります。後はこのファイルに内容を作っていけば、ページを増やすことができます。
レイアウトファイルを使おう
次ページにアクセスしましょう。
サイト内で使う共通のパーツなどの場合は、個別に作成するよりは共通パーツにした方が良いでしょう。このような時は、レイアウトファイルを利用できます。
src/routes
フォルダーに+layout.svelte
ファイルを作成しましょう。すると、/
や/about
が真っ白のページに変わりますが、すでにレイアウトファイルが採用されるようになっています。
各ページの内容を反映するには<slot />
という特別なタグを使います。
<slot />
このタグの前後には、共通のパーツを追加することができます。例えばここでは、src/routes/+page.svelte
ファイルに書かれているナビゲーションを設置してみましょう。<nav>
要素全体を切り取って、+layout.svelte
に貼り付けておきましょう。
<nav>
<a href="/">home</a>
<a href="/about">about</a>
</nav>
<slot />
パラメータを指定できるようにしよう
次ページにアクセスしましょう。
こうして、ページを増やしていく事はできますが、例えばブログのしくみを作ろうとした場合、各記事の内容はページとしては存在せずに、別のヘッドレスCMSやデータベースからデータを取得する事がほとんどです。
そのため、/blog/one
とか/blog/two
など、さまざまなアドレスを指定したときにも対応できるようにしましょう。これには、パラメータを受け取れるようにします。/src/routes/blog
フォルダーに、[slug]
というフォルダーを作成しましょう。

このフォルダーの中に、これまでと同様に+page.svelte
ファイルを作成してページ内容を作成しましょう。これで、/blog/one
などのアドレスが指定されたときに、このファイルが表示されるようになります。

JSONファイルと連携しよう
次ページにアクセスしましょう。
では、ブログの記事を外部のデータから取得しましょう。ここでは、JSONデータから取得します。ブログ記事はsrc/routes/blog/data.js
ファイルに準備されています。これを読み込んで、一覧画面を作成してみましょう。
まずは、これを読み込むためのプログラムを作成します。これには/src/routes/blog/+page.server.js
というファイル名で作成しましょう。

次のように書き込みます。
import { posts } from './data.js';
export function load() {
return {
summaries: posts.map((post) => ({
slug: post.slug,
title: post.title
}))
};
}
すると、同じ場所にある+page.svelte
ファイルからdata
として受け取ることができるようになります。/src/routes/blog/+page.svelte
ファイルを次のように変更しましょう。
<script>
export let data;
</script>
<h1>blog</h1>
<ul>
{#each data.summaries as { slug, title }}
<li><a href="/blog/{slug}">{title}</a></li>
{/each}
</ul>
各個別のページも同じように作成します。/src/routes/blog/[slug]
フォルダーに+page.server.js
ファイルを作成します。
import { posts } from '../data.js';
export function load({ params }) {
const post = posts.find((post) => post.slug === params.slug);
return {
post
};
}
ここではfind
メソッドを使って、URLで指定されているパラメーター(slug)と一致するデータだけを取得しています。
後は、/src/routes/blog/[slug]/+page.svelte
は次のようになります。
<script>
export let data;
</script>
<h1>blog post</h1>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
本文を表示している{@html ...}
というのは、データの中にHTMLのタグがあった場合に、そのまま内容を表示するというプレースホルダーです。これを使う場合、データ内の安全性がSvelteでは保障されなくなるため、注意をして利用しましょう。必要に応じて、手作業でエスケープ処理などをする必要があります。

不正なパラメーターが指定されたときにページが見つからない処理をしよう
現状、アドレスを書き換えて不正な内容などに変更すると、JSONのデータが取得できないため「Internal Error」が発生してしまいます。しかし、実際にはページの削除などもあるため、一般的なページが見つからない場合のエラー処理をしていきましょう。これには/src/routes/blog/[slug]/+page.server.js
に次のように記述して、404エラーコードを返却します。
export function load({ params }) {
const post = posts.find((post) => post.slug === params.slug);
if (!post) throw error(404); // 追加
return {
post
};
}

共通して利用するデータをロードしよう
各ページで利用したいデータは、先の通り+page.server.js
というファイルを準備しますが、もし一覧でも個別のページでも共通して利用したいデータがある場合は、+layout.server.js
というファイルが利用できます。
まずは、/src/routes/blog/+page.server.js
を/src/routes/blog/+layout.server.js
に名前を変えましょう。これで、他のファイルからも参照ができるようになります。
そしたら、/src/routes/blog/[slug]/+layout.svelte
に次のように追加します。
<script>
export let data;
</script>
<div class="layout">
<main>
<slot />
</main>
<aside>
<h2>More posts</h2>
<ul>
{#each data.summaries as { slug, title }}
<li>
<a href="/blog/{slug}">{title}</a>
</li>
{/each}
</ul>
</aside>
</div>
これで、各ページに最新のエントリーが表示されるようになります。

スタイルシートを調整しよう
Svelteでは、スタイルシートも.svelte
ファイルに書き込み事ができます。一番下に追加しましょう。
...
<style>
@media (min-width: 640px) {
.layout {
display: grid;
gap: 2em;
grid-template-columns: 1fr 16em;
}
}
</style>
これで、サイドエリアに移動しました。

<以下、執筆中>