静的サイトは、速度、セキュリティ、そしてシンプルさに優れていることから、近年ますます人気が高まっています。静的サイト作成用ツールやフレームワークは多数ありますが、中でも急速に人気を伸ばしているのがSvelteKitです。
今回はセットアップからKinstaの静的サイトホスティングでのデプロイ方法まで、SvelteKitを使用した静的サイトの作り方を詳しくご紹介していきます。
SvelteKitとは
SvelteKit、静的サイトを含むユーザーインターフェースを作成するための堅牢なウェブフレームワーク。パフォーマンス、シンプルさ、宣言的なアプローチでコンポーネントを構築可能です。
ルーティングやサーバーサイドレンダリングなどを実装することで、機能を拡張することもできます。
SvelteKitで静的サイトを構築する
これからご紹介する手順では、以下の条件を前提とします。
- HTML、CSS、JavaScriptの基礎知識
- Svelteの基礎知識
- Node.jsとnpmのインストール
それでは、早速手順を見ていきましょう。
- 以下を実行して新規プロジェクトを立ち上げます。
npm create svelte@latest my-app
my-app
ディレクトリにプロジェクトが作成され、TypeScriptなどの基本的なツールの設定が求められます。「Skeleton project」を選択し、my-app
をプロジェクト名に変更します。
- プロジェクトディレクトリに移動し、依存関係をインストール。
cd my-app
npm install
npm run dev
を実行して、localhost:5173
上のローカル開発サーバーを起動します。
SvelteKitのファイル構造
プロジェクトをコードエディターで開くと、以下のような構造になっています。コードを効率的に整理するため、この構造は把握しておきましょう。
/
|-- /src
|-- /lib
|-- /routes
|-- +page.svelte
|-- app.html
|-- /static
|-- svelte.config.js
- /src:プロジェクトの中核となり、様々なサブディレクトリとファイルが格納される。
- /lib:カスタムライブラリ、ユーティリティ、またはモジュールが格納される。アプリケーション全体で使用する再利用可能なコードを保管するのに適しています。
- /routes:アプリケーションの異なるページやビューの定義に重要。各ページは+page.svelteのような.svelteファイルで表され、この.svelteファイルには、各ページ固有のコンポーネント、ロジック、スタイルが含まれます。
- app.html:アプリケーションのエントリーポイントとして機能。ウェブページの主な構造が定義されます。
- /static:画像、フォント、アプリケーションで処理する必要のないファイルなどの静的アセットを保存。これらのアセットは、HTMLやSvelteコンポーネントで直接参照できます。
- svelte.config.js:SvelteKitプロジェクトの様々な側面をカスタマイズ可能。サーバーサイドレンダリングの設定、カスタムレイアウトの定義などに使用できます。
SvelteKitのルーティング
ルーティングシステムは、SvelteKitの目玉機能。ファイルシステムベースのルーティングにより、URLパスがsrc/routesディレクトリ内のファイルやフォルダで定義され、直感的かつ簡単に管理することができます。
SvelteKitでは、ルートに対応するファイル名は必ず「+page.svelte」でなければなりません。例えば、SvelteKitサイトのインデックスファイルはroutesフォルダにあり、名前は+page.svelteです。
このファイルに以下のコードを追加して、サイトのトップページを作成します。
<div class="home_hero">
<h1>insta StSHで静的サイトホスティングをお楽しみください</h1>
<p>高速、安全、信頼性に優れたホスティングソリューション</p>
<a href="https://kinsta.com/jp/static-site-hosting/">
<div class="btn">もっと詳しく</div>
</a>
</div>
<style>
.home_hero {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
}
.home_hero h1 {
font-size: 60px;
width: 70%;
}
.home_hero p {
color: #6e7076;
font-size: 20px;
}
.btn {
background-color: #5333ed;
padding: 20px 30px;
margin-top: 40px;
border-radius: 5px;
color: #fff;
}
@media (max-width: 700px) {
.home_hero h1 {
font-size: 40px;
}
.home_hero p {
font-size: 16px;
}
}
</style>
SvelteKitでネストされたルート、例えばlocalhost:5173/about
でアクセスできる会社概要ページを作成するには、routesフォルダ内にURLパスを表す名前のフォルダを作成し、フォルダ内にルート用にレンダリングされる+page.svelteファイルを作ります。
続いて、routes/about/+page.svelteに以下のコードを貼り付けます。
<div class="about_cont">
<h2>About</h2>
<div class="about_info">
<div class="about_text">
<p>
Kinstaで最大100件まで{' '}
<a> href="https://kinsta.com/jp/static-site-hosting/">
静的サイトを無料でホスティング
</a>{' '}
お好きなGitサービス(Bitbucket、GitHub、またはGitLab)に
コードをプッシュして、Kinstaにデプロイするだけ。
</p>
<p>
静的サイトホスティングの代わりに{' '}
<a> href="https://kinsta.com/jp/application-hosting/">
アプリケーションホスティング
</a>
でデプロイすることもできます。
柔軟なスケーリング、Dockerfileを使用したデプロイメントのカスタマイズ、
リアルタイムおよび過去のデータを網羅した包括的な分析など
堅牢な機能が多数揃っているため、ホスティングの柔軟性が高まります。
</p>
</div>
<iframe> width="560" height="315" src="https://www.youtube.com/embed/H7CNbsda8OA?si=40FGVlNvJ74_6hlj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen> </iframe>
</div>
</div>
<style>>
.about_cont h2 {
font-size: 40px;
margin-bottom: 20px;
}
.about_info {
display: flex;
width: 100%;
justify-content: space-between;
gap: 20px;
}
@media (max-width: 700px) {
.about_info {
flex-direction: column;
}
}
.about_text {
flex-basis: 50%;
}
.about_text p {
margin-bottom: 20px;
font-size: 18px;
}
.about_img {
flex-basis: 50%;
width: 200px;
border-radius: 10px;
}
@media (max-width: 700px) {
.about_info {
flex-direction: column;
}
.about_img {
width: 100%;
}
}
</style>
Svelteコンポーネントに追加されたスタイルは、スコープが制限されているため、他のコンポーネントに影響を与えることはありません。
SvelteKitは、標準的な<a>
要素を使用してページ間のナビゲーションを処理し、ナビゲーションプロセスを直感的に理解します。Reactで必要になる<Link>
のような追加コンポーネントをインポートする必要はありません。次のセクションでは、各ページに追加するナビゲーションコンポーネントを構築していきましょう。
現在のプロジェクトでは、ルート構造は次のようになっています。
|-- /src
|-- /routes
|-- /about
|-- +page.svelte
|-- +page.svelte
SvelteKitでコンポーネントを使用する
コンポーネントを作成してページにインポートすることで、コードをよりモジュール化することができます。例として、routesフォルダにNavbar.svelteコンポーネントを構築してみます。
<nav>
<a href="/">
<img src="/kinsta-logo.png" alt="" class="logo-img" />
</a>
<div class="nav-links">
<a href="/">ホーム</a>
<a href="/about">会社概要</a>
<a href="/posts">投稿</a>
</div>
</nav>
以下のように+page.svelteトップページにインポートします。
<script>>
import Navbar from './Navbar.svelte'
</script>
<Navbar />
<div class="home_hero">
<h1>Kinsta StSHで静的サイトホスティングをお楽しみください</h1>
<p>高速、安全、信頼性に優れたホスティングソリューション</p>
<a href="https://kinsta.com/jp/static-site-hosting">
<div> class="btn">もっと詳しく</div>
</a>
</div>
<style>
/* CSS styles */
</style>
Navbar
やFooter
など、複数のファイルにまたがって使用されるグローバルコンポーネントは、長いインポートパスを避けるためにsrc/libフォルダに作成してください。libフォルダ内にコンポーネントやモジュールを作成すると、$lib
インポートエイリアスを使用して全てのコンポーネントにインポートできるため便利です。
<script>
import Navbar from '$lib/Navbar.svelte'
</script>
スタンドアロンコンポーネントを使う場合、例えば、会社概要ページにのみ必要であれば、routes/aboutルート内で作成してページにインポートします。
libフォルダにFooter
コンポーネントを作成し、以下のコードを追加することも可能です。
<div class="footer">
<p>
Hosted with ❤️ by Kinsta's{' '}
<a> href="https://kinsta.com/jp/static-site-hosting">静的サイトホスティング</a>
.
</p>
</div>
それから、すべてのページにインポートしてください。
SvelteKitでレイアウトを使用する
多くのページにコンポーネントをインポートするのを避けるため、SvelteKitでは+layout.svelteファイルを使ってページのレイアウトを定義することができます。
各ページに適用するレイアウトの作成は簡単で、src/routes/+layout.svelteという名前のファイルを作成し、任意のマークアップ、スタイル、動作でカスタマイズしていきます。重要な要件として、ページのコンテンツを追加するために<slot/>
要素を含めてください。
例えば、Navbar
とFooter
コンポーネントをレイアウト内に統合することができます。
<script>
import Navbar from '$lib/Navbar.svelte';
import Footer from '$lib/Footer.svelte';
</script>
<div class="layout">
<Navbar />
<slot />
<Footer />
</div>
<slot>
要素を使って、各ページのコンテンツをレイアウトに挿入することができます。
また、特定のページに対して入れ子にすることも。例えば、/dashboard
ページがあり、/profile
や/settings
のようなページが入れ子になっている場合、特別なレイアウトを作成することができます。
|-- /dashboard
|-- /profile
|-- +page.svelte
|-- /settings
|-- +page.svelte
|-- +layout.svelte
SvelteKitのプログラマティックナビゲーション
SvelteKitには、プログラムナビゲーション用のgoto
関数があり、たとえばログインアクション後、/dashboard
ページに移動する場合は、以下のようになります。
<script>
import { goto } from '$app/navigation';
async function login() {
// ログイン操作の実行
goto('/dashboard');
}
</script>
SvelteKitのスタイリング
SvelteKitでは、従来のCSSによるスタイリングをサポートしています。<style>
タグを使ってSvelteコンポーネント内でスタイルを定義することもできれば、外部のスタイルシートをリンクすることも可能です。
お気づきのかもしれませんが、Navbar
とFooter
コンポーネントには特定のスタイルがありません。スタイルを変更するには、グローバルスタイルを適用するのがお勧めです。srcフォルダ内にCSSファイルを作成し、ルートレイアウトファイルにインポートしましょう。
わかりやすいよう、srcディレクトリ内にstylesフォルダを作成してすべてのスタイルを格納します。stylesフォルダ内にglobal.cssファイルを作成し、以下のコードを貼り付けます。
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #ddd;
font-family: 'Poppins',
sans-serif;
width: 1200px;
margin: 0 auto;
}
a {
text-decoration: none;
}
img {
width: 100%;
}
nav {
display: flex;
justify-content: space-between;
height: 200px;
align-items: center;
}
nav .logo-img {
width: 100px;
}
nav .nav-links a {
padding: 0 20px;
font-size: 18px;
}
@media (max-width:700px) {
body {
width: 100%;
padding: 0 20px;
}
nav .nav-links a {
padding: 0 18px;
}
}
.footer {
width: 100%;
text-align: center;
margin: 100px 0 20px;
}
このCSSファイルをレイアウトファイルにインポートすると、グローバルスタイルとなり、すべてのファイルで機能するように。
<script>>
import Navbar from '$lib/Navbar.svelte';
import Footer from '$lib/Footer.svelte';
import '../styles/global.css';
</script>
SvelteKitでデータを読み込む方法
SvelteKitを使用する場合は、レイアウトやページ、コンポーネントにデータを読み込む必要があります。データは外部API、データベース、またはローカルサーバから取得でき、管理にはページ用の+page.jsファイルとレイアウト用の+layout.jsファイルを使用します。
+page.svelteファイルは、load関数をエクスポートする兄弟ファイル+page.jsを持つことができます。この関数の戻り値は、data
propsを通してページで利用可能です。以下、JSON Placeholder APIから投稿一覧を取得するルートを作成してみます。
APIからデータを読み込むため、postsフォルダ内に+page.jsファイルを作成します。このファイルがload
関数をエクスポートします。
export const load = async () => {
const title = "Hello World";
return {
title,
};
};
load
関数はオブジェクトを返すことが期待されており、オブジェクトは+page.svelteファイルにpropsとして提供されます。title
の値は、data
propsで可能です。
<script>>
export let data;
const title = data.title;
</script>
<div class="blog_cont">
<h2>{title}</h2>
</div>
続いては、JSON Placeholder posts APIとのやり取りです。これにはJavaScript Fetch APIを使用しますが、SvelteKitには独自のfetch
関数があり、ページをレンダリングする前にAPIエンドポイントからデータを取得することができます。
export const load = async (loadEvent) => {
const { fetch } = loadEvent;
const response = await fetch(
'https://jsonplaceholder.typicode.com/posts?_limit=10'
);
const posts = await response.json();
return {
posts,
};
};
上のコードでは、loadEvent
からfetch
関数を抽出し、APIリクエストを行います。っています。レスポンスは投稿ページにpropsとして送信され、すべての投稿をループして表示します。
<script>
export let data;
const posts = data.posts;
</script>
<div class="blog_cont">
<h2>投稿</h2>
<div class="blog_grid">
{#each posts as post}
<a href={`/posts/${post.id}`} class="blog_card">
<h3>{post.title}</h3>
<p>
{post.body}
</p>
</a>
{/each}
<;/div>
<;/div>
<style>
.blog_cont h2 {
font-size: 40px;
margin-bottom: 20px;
}
.blog_grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}
@media (max-width: 700px) {
.blog_grid {
grid-template-columns: 1fr;
}
}
.blog_card {
background-color: #bfbfbf;
padding: 20px;
border-radius: 5px;
color: #000;
transition: all 0.5s ease-in-out;
}
.blog_card:hover {
background-color: #5333ed;
color: #fff;
}
.blog_card h3 {
margin-bottom: 15px;
}
.blog_card p {
margin-bottom: 15px;
}
</style>
この時点で、ファイルツリーは以下のようになっています。
|-- /src
|-- /lib
|-- Footer.svelte
|-- Navbar.svelte
|-- /routes
|-- /about
|-- +page.svelte
|-- /posts
|-- +page.js
|-- +page.svelte
|-- +page.svelte
|-- +layout.svelte
|-- /styles
|-- global.css
SvelteKitによる動的ルーティング
現在、投稿ページには10件の投稿が表示されるようになっています。各投稿ごとに個別のページを作成するには、動的ルーティングを設定するのがベストです。
これにはルートからスラッグ値を受け取り、それをパラメータとして投稿をクエリが必要ですが、SvelteKitでは、パラメータ名の角括弧([])のフォルダを作成します。手順は以下のとおりです。
- postsフォルダ内に[postid]フォルダを作成。[postid]は動的パラメータを表し、投稿IDやスラッグのような値を保持することができます。
- [postid]フォルダの中に以下2つのファイルを作成。
- +page.svelte:個々の投稿ページのレイアウトと構造を定義
- +page.js:個々の投稿に特有のデータ取得とロジックを処理
page.jsファイルでは、postid
パラメータをルートから取得し、特定の投稿をクエリするために使用します。
">export const load = async (loadEvent) => {
const { fetch, params } = loadEvent;
const { postid } = params;
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${postid}`
);
const post = await response.json();
return {
post,
};
};
その後、+page.svelteファイルのpropsとしてdata
にアクセスします。
<script>>
export let data;
const post = data.post;
</script>
<;div>
<;div class="blog_content">
<h3>{post.title}</h3>
<p>{post.body}</p>
</div>
</div>
<style>>
.blog_content h3 {
font-size: 40px;
margin-bottom: 20px;
text-align: center;
}
</style>
今回ご紹介したSvelteKitプロジェクトのソースコードの全貌はこちらをご覧ください。また、詳細はSvelteKitの公式ドキュメントで確認してみてください。
KinstaでSvelteKit静的サイトをデプロイする方法
Kinstaでは、任意のGitサービス(Bitbucket、GitHub、またはGitLab)から直接、最大100件まで静的サイトを無料でホスティングすることができます。
SvelteKitサイトを稼働する前に、デプロイメントのターゲットに合わせることが重要です。今回はKinstaの静的サイトホスティングを使用するため、SvelteKitを静的サイトジェネレーター(SSG)として設定します。
静的ファイルのコレクションとして事前にレンダリングされたサイトを取得する方法は以下のとおりです。
- 以下のコマンドを実行して、@sveltejs/adapter-staticをインストールします。
sh">npm i -D @sveltejs/adapter-static
- svelte.config.jsファイルの
adapter-auto
をfallback
から404.html
に置き換えます。
js">import adapter from '@sveltejs/adapter-static';
const config = {
kit: {
adapter: adapter({ fallback: '404.html' }),
},
};
export default config;
続いて、コードをお好きなGitサービスにプッシュしたら、以下の手順に従って、静的サイトをKinstaにデプロイします。
- MyKinstaにログイン、またはアカウントを作成
- GitサービスでKinstaを認証
- MyKinstaの左サイドバーから「静的サイト」を選択し「サイトを追加」をクリック
- デプロイしたいリポジトリとブランチを選択
- サイトに一意の名前を割り当てる
- ビルド設定に以下を追加
- ビルドコマンド:
npm run build
- Nodeのバージョン:
18.16.0
- 公開ディレクトリ:
build
- ビルドコマンド:
- 「サイトを作成」をクリック
以上で完了です。これで数秒以内にサイトがデプロイされ、サイトにアクセスするためのリンクが表示されます。必要に応じて、独自ドメインやSSL証明書を追加することも可能です。
また、静的サイトホスティングの代わりに、Kinstaのアプリケーションホスティングで静的サイトをデプロイすることもできます。柔軟なスケーリング、Dockerfileを使用したデプロイメントのカスタマイズ、リアルタイムおよび過去のデータを網羅した包括的な分析など、高度な機能が多数揃っています。
まとめ
開発環境のセットアップからデプロイまで、SvelteKitで静的サイトを構築する手順をご紹介しました。この記事を参考に、ぜひ静的サイトを作成してみてください。パフォーマンスとシンプルさの完璧な融合を実現するSvelteKisなら、多くのユーザーを惹きつける優れた静的サイトの構築が簡単です。
過去にSvelteKitを使用したことはありますか?以下のコメント欄でお聞かせください。
コメントを残す