2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【ひとりカレンダー】フロントエンド開発成長日記Advent Calendar 2022

Day 7

SvelteKit デモアプリからルーティングについて解説する

Last updated at Posted at 2022-12-06

はじめに

svelteではsvelte-routingを用いてルーティングを実装したことがありましたが、SvelteKitでは標準でルーティングが用意されています。
今回は公式デモを構築しつつ、ルーティングについてまとめていく。

SvelteKitデモアプリの構築

  1. SvelteKit構築

    $ npm create svelte@latest
    Need to install the following packages:
      create-svelte@2.0.0-next.198
    Ok to proceed? (y) y
    
    create-svelte version 2.0.0-next.198
    
    Welcome to SvelteKit!
    
    This is release candidate software; expect bugs and missing features.
    
    Problems? Open an issue on https://github.com/sveltejs/kit/issues if none exists already.
    
    ✔ Where should we create your project?
      (leave blank to use current directory) … 
    ✔ Which Svelte app template? › SvelteKit demo app
    ✔ Add type checking with TypeScript? › Yes, using TypeScript syntax
    ✔ Add ESLint for code linting? … No / Yes ›  No
    ✔ Add Prettier for code formatting? … No / Yes ›  No
    ✔ Add Playwright for browser testing? … No / Yes ›  No
    ✔ Add Vitest for unit testing? … No / Yes ›  No
    
    $ npm install
    
  2. localhost:8080で開くように調整する

    // vite.config.js
    
    import { sveltekit } from '@sveltejs/kit/vite';
    
    /** @type {import('vite').UserConfig} */
    const config = {
    	darkMode: 'class',
    	plugins: [sveltekit()],
    	server: {          // 追加
    		host: true,    // 追加
    		port: 8080     // 追加
    	}                  // 追加
    };
    
    export default config;
    

    8080以外のポートを開けたい場合はportの部分を調整する。

image.png

routesディレクトリについて

デモから読み取る

このデモアプリケーションは↓のような構造で構成されています。

簡単に説明すると、routes以下のディレクトリがそのままルーティングされます。このあたりはnuxt.jsとかとも似てますね!

image.png

どのようにページを表示しているのか見ていきます。

+page.svelte

そのルーティングのアプリのページを表しています。

ルートパス( / )では、routes/+page.svelte
アバウトパス( /about )では、routes/about/+page.svelte

がそれに該当します。

routes以下に作ったディレクトリ名に+ページするイメージですね!

+page.ts

+page.svelteが呼ばれる前に実行されます。

import { error } from '@sveltejs/kit';
 
/** @type {import('./$types').PageLoad} */
export function load() {
    return {
        profile: [{ hoge: 'hoge', fuga: 'fuga' }]
    };
}

↑のようにデータを返すことで、+page.svelteで使うことができます。

<script>
  /** @type {import('./$types').PageData} */
  export let data;

  console.log(data.profile); // [{ hoge: 'hoge', fuga: 'fuga' }]
</script>

+layout.svelte

全てのページで表示されるページです。
+page.svelte等の表示場所は<slot></slot>を使うことで表示させることができます。

ヘッダーやフッター、cssの読み込みなどを行うのに便利そうです。

例)

// +layout.svelte

<script>
	import Header from './Header.svelte';
	import Footer from './Footer.svelte';
	import './styles.css';
</script>

<div class="app">
	<Header />
    <slot><slot/>  // +page.svelte
	<Footer />
</div>

+layout.ts

+layout.svelteが呼ばれる前に実行されます。
使い方は+page.tsと同じです。

デモで使われていないもの

[パラメータ]

/user/11や、store/tokyotokyoの値をパラメータとするようなルーティングを実装するときは

routes/user/[id]や、routes/store/[place]のようにディレクトリを作成し、その下に+page.svelteを作成する。

例) about/:id
image.png

+page.tsでは、次のようにしてパラメータを取得することができる

// +page.ts
import { error } from '@sveltejs/kit';
 
/** @type {import('./$types').PageLoad} */
export function load({ params }) {
  if (params.id === '1') {
    return {
      title: 'Hello 1号!',
      content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
    };
  }
  
  // id: 1以外は404エラー等...
  throw error(404, 'Not found');
}

そして先ほどと同じやり方で+page.svelteに値を渡し、表示させることができる

// +page.svelte

<script>
  /** @type {import('./$types').PageData} */
  export let data;
</script>

<h1>{data.title}</h1>
<div>{@html data.content}</div>

localhost:8080/about/1
image.png

server.ts

データベースから値を取得したり、環境変数にアクセスするような、
サーバーサイドで実行したい処理を実行する場合にはserver.tsを使う

+page.tsならば、+page.server.ts
+layout.tsならば+layout.server.tsを使う。

// +page.server.ts
import { error } from '@sveltejs/kit';
import { getData } from './common'
 
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
  const post = await getData(params);
 
  if (post) {
    return post;
  }
 
  throw error(404, 'Not found');
}

+error.svelte

ページロード中にエラーが発生した場合に表示させるページ。
$app/storeというモジュールにpageというのものが用意されており、
組み合わせて使うことで、良い感じのエラーページを表示させることができる。

<script>
  import { page } from '$app/stores';
</script>

<h1>{$page.status}</h1>
<h1>{$page.error.message}</h1>

image.png

$types

これまでの例で/** @type {import('./$types').PageData} */が度々登場してましたが、
+page.svelte+layout.svelteexport let data;の前の行にこのアノテーションを付けると、その型はload関数の戻り値ということをTypeScriptに伝えることができます。

TypeScriptを使う人は正しく型をつけるためにも積極的につけていきましょう

次回

次回はgoto等、$app/navigationについて解説していきます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?