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?

SvelteKitでformから記事を追加した後いい感じにフェードインさせる

Last updated at Posted at 2025-12-23

概要

SvelteKit2.27で追加されたRemote functionsformで記事を一件追加します。

追加が終わったら記事の一覧ページに遷移し、追加された記事をViewTransition APIでいい感じにフェードインさせます。

リポジトリ

デモ

  1. 記事の配列を格納する$stateを用意しておきます
  2. /formでフィールドにタイトルを入力すると記事のプレビューが表示されます
  3. フォームをsubmitし記事を追加すると/に遷移します
  4. /formから/に記事を投稿して遷移した時だけアニメーションします

おことわり

ViewTransition APIで遊んでみたかっただけの記事です。

ViewTransition API

SvelteKitでは+layout.svelteに以下のように指定することでViewTransition APIを使用できます。

<script lang="ts">
	import { onNavigate } from '$app/navigation';

	onNavigate((navigation) => {
		if (!document.startViewTransition) return;
			return new Promise((resolve) => {
				document.startViewTransition(async () => {
					resolve();
					await navigation.complete;
				});
			});
	});
</script>

アニメーションはdata-view-transition-name="post"を指定した記事に対して行います。

Remote functions form

createPost.enhanceformenhanceを実装します。

createPostから新規追加された記事のidとtitleをreturnすると、createPost.resultで受け取ることができます。
addPostで新規記事を$stateに追加し、goto/に遷移します。

<form
	{...createPost.enhance(async ({submit}) => {
		await submit();
		if (result) {
			addPost(result);
			goto('/');
		}
	})}
>

/formのプレビューと/の記事の一つ目には同じdata-view-transition-name="post"が付与されているのでいい感じにアニメーションでフェードインします。

おわり

ページ遷移前にあった要素がページ遷移後のページに向けて移動するのがおもしろいですね。

記事投稿ページをdialogなどで実装するとフロントエンドが余計な複雑さを帯びるのが嫌でページを分けることが多いのですが、体験としてはdialog的なフェードインアニメーションがあった方がいいように感じるので視覚的にdialogっぽく見せるけどページは別れている みたいな用途で使ったりもできるのかなと思っています。

とは言え対応ブラウザがまだまだ…といったところなので一旦ユーザーの使用するブラウザのバージョンが上がってくるのを待っています。

注意

enhancegotoしているので、JavaScriptが無効な状態では記事投稿あとそのページに留まります。

本来createPostでreturnせずredirectした方がいいです。

デモ環境ではDBを用意するのが面倒だったのであえて$stateを更新するように作っており、この関係でenhanceを使用しています。(注意!サーバーサイドで$stateを使用してはいけません)

DBなどからデータを引っ張ってくる場合は記事一覧を取得するgetPostsのような関数をRemote functionsqueryで作成しておき、createPostgetPostsを更新すると同じようにアニメーションします。

また、resultが存在するときはフォームを表示せず/へのリンクを表示するのもありだと思いますが、
現状Remote functionsresultがページ遷移で破棄されないバグがあるのでやむを得ず上記の実装を行っています。

resultが更新されないバグには少し困っていますが、これを呼び出しているページへのリンクにdata-sveltekit-reloadを指定することで無理やり解決しています。

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?