Skip to main content

Link options

SvelteKit では、アプリのルート(routes)間の移動に、(フレームワーク固有の <Link> コンポーネントではなく) <a> 要素を使用します。ユーザーが、href がアプリのものであるリンク (外部サイトではないリンク) をクリックする場合、SvelteKit はそのコードをインポートし、データを取得するために必要な load 関数を呼び出して、新しいページに移動します。

data-sveltekit-* 属性でリンクの挙動をカスタマイズすることができます。これらは <a> 自身やその親要素に適用することができます。

これらのオプションは、method="GET" を持つ <form> 要素にも適用されます。

data-sveltekit-preload-data

ユーザーがリンクをクリックしたことをブラウザが検知するより前に、(デスクトップでは) マウスがリンクをホバーしたことや、touchstartmousedown がトリガーされることを検知することができます。どちらの場合も、click イベントが発生することを経験に基づいて推測することができます。

SvelteKit はこの情報を使ってインポートするコードやそのページのデータの取得をいち早く開始することができ、数百ミリ秒を稼ぐことができます。これが、ユーザーインターフェースが遅延していると感じるか、それともきびきび動いていると感じるかの差になります。

この動作は data-sveltekit-preload-data 属性によってコントロールすることができ、2つの値のうちどちらかを設定することができます:

  • "hover" は、マウスがリンクの上にきたときにプリロードを開始します。モバイルでは、touchstart でプリロードが開始されます
  • "tap" は、touchstartmousedown イベントが検知されるとすぐにプリロードが開始されます

デフォルトのプロジェクテンプレートには、src/app.html<body> 要素に data-sveltekit-preload-data="hover" が適用されており、デフォルトで全てのリンクがホバー時にプリロードされます:

<body data-sveltekit-preload-data="hover">
	<div style="display: contents">%sveltekit.body%</div>
</body>

時には、ユーザーがリンクをホバーしたときに load を呼ぶのは望ましくないことがあるでしょう。誤検出の可能性もありますし (必ずしもホバーに続いてクリックが発生するわけではない)、データの更新が非常に早い場合はデータが古くなってしまうこともあります。

これらの場合には、値に "tap" を指定します。こうすると SvelteKit は、ユーザーがリンクをタップまたはクリックしたときのみ、load を呼び出すようになります:

<a data-sveltekit-preload-data="tap" href="/stonks">
	Get current stonk values
</a>

プログラムで $app/navigationpreloadData を実行することもできます。

ユーザーがデータ使用量の削減を選択している場合、つまり navigator.connection.saveDatatrue になっている場合は、データは決してプリロードされません。

data-sveltekit-preload-code

リンク先の データ をプリロードしたくない場所であっても、コード をプリロードするのは有益なこともあります。data-sveltekit-preload-code 属性は data-sveltekit-preload-data と同様に動作しますが、4つの値から選択できる点が異なります。’先行度’('eagerness’) の降順で並べると:

  • "eager" は、すぐにリンクをプリロードします
  • "viewport" は、リンクがビューポートに入るとすぐにプリロードします
  • "hover" - コードだけがプリロードされることを除き、上記(data-sveltekit-preload-data"hover")と同じです
  • "tap" - コードだけがプリロードされることを除き、上記(data-sveltekit-preload-data"tap")と同じです

viewporteager は、ナビゲーション直後の DOM に存在するリンクにのみ適用されることにご注意ください。リンクが後から追加された場合 (例えば {#if ...} ブロックの中)、hovertap によってトリガーされるまでプリロードされません。DOM の変更を積極的に観察することによって生じてしまうパフォーマンス劣化を避けるためです。

コードのプリロードはデータのプリロードの前提条件であるため、この属性は、存在するどの data-sveltekit-preload-data 属性よりも先行度が高い値(more eager value)を指定した場合にのみ、効果を発揮します。

data-sveltekit-preload-data と同様、ユーザーがデータ使用量の削減を選択している場合、この属性も無視されます。

data-sveltekit-reload

時には、SvelteKit にリンクを処理させないで、ブラウザに処理をさせる必要があります。data-sveltekit-reload 属性をリンクに追加すると…

<a data-sveltekit-reload href="/path">Path</a>

…リンクがクリックされたときにフルページナビゲーションが発生します。

rel="external" 属性があるリンクも同様に扱われます。加えて、プリレンダリング中 は無視されます。

data-sveltekit-replacestate

ナビゲーションするときにブラウザのセッション履歴(session history)に新しいエントリを作成したくない場合があります。リンクに data-sveltekit-replacestate 属性を追加すると…

<a data-sveltekit-replacestate href="/path">Path</a>

…リンクがクリックされたときに、pushState で新しいエントリを作成する代わりに現在の history エントリを置き換えます。

data-sveltekit-keepfocus

ナビゲーションの後にフォーカスをリセットしたくない場合があります。例えば、ユーザーが入力している途中で送信をするような検索フォームがあり、テキストの input にフォーカスを維持したい場合です。data-sveltekit-keepfocus 属性を追加すると…

<form data-sveltekit-keepfocus>
	<input type="text" name="query">
</form>

…ナビゲーション後も現在フォーカスされている要素にフォーカスが維持されるようになります。通常、リンクにこの属性を使用するのは避けてください、フォーカスされる要素が (その前にフォーカスされていた要素ではなく) <a> タグになってしまい、スクリーンリーダーなどの支援技術を使用するユーザーはナビゲーションの後にフォーカスが移動することを期待することが多いです。また、この属性はナビゲーションの後にもまだ存在する要素にのみ使用する必要があります。もしその要素が消えてしまうと、ユーザーのフォーカスは失われてしまい、支援技術ユーザーにとって混乱した体験となってしまいます。

data-sveltekit-noscroll

内部のリンクに移動するとき、SvelteKit はブラウザのデフォルトのナビゲーションの挙動を模倣します: ユーザーがページの左上に来るように、スクロールポジションを 0,0 に変更します (リンクに #hash が含まれている場合は、ID が一致する要素までスクロールします)。

特定のケースでは、この挙動を無効化したいことがあるでしょう。data-sveltekit-noscroll 属性をリンクに追加すると…

<a href="path" data-sveltekit-noscroll>Path</a>

…リンクがクリックされたあとのスクロールを中止します。

Disabling options

これらのオプションが有効になっている要素の中でこれらのオプションを無効にするには、"false" 値を使用します:

<div data-sveltekit-preload-data>
	<!-- these links will be preloaded -->
	<a href="/a">a</a>
	<a href="/b">b</a>
	<a href="/c">c</a>

	<div data-sveltekit-preload-data="false">
		<!-- these links will NOT be preloaded -->
		<a href="/d">d</a>
		<a href="/e">e</a>
		<a href="/f">f</a>
	</div>
</div>

条件によって要素に属性を適用する場合は、このようにします:

<div data-sveltekit-preload-data={condition ? 'hover' : false}>

Edit this page on GitHub

previous next