つまり、名前付きスロットを`.astro`なコンポーネントで使うとき、
--- import Layout from "..."; --- <Layout> <h2 slot="after-header">After header</h2> <h2>Default slot</h2> <h2 slot="after-footer">After footer</h2> </Layout>
これが想定通りに動作するのは、`Layout`コンポーネントも`.astro`のときだけ、という話。
たとえば`Layout`コンポーネントが`.svelte`だったりすると、名前付きスロットに渡したコンポーネントが表示されないのです。(それどころか、名前なしスロットの部分まで表示されなかったりする)
ちなみに、Astroのバージョンは`1.0.0-beta.17`のときの話です
仕様らしい
🐛 BUG: Named Slots are not forwarded to Svelte Components · Issue #2238 · withastro/astro · GitHub
コンパイラの仕様なら仕方ないか・・とは思いつつ。
まとめると、
Where | Layout | Works? |
---|---|---|
.astro | .astro | Yes |
.astro | .svelte/.vue | No |
.svelte | .svelte | Yes |
.vue | .vue | Yes |
ってこと。
もちろん`.svelte`の中では、他のタイプのコンポーネントは読み込めない。
名前付きではないただのスロットなら使えるし、他のタイプ同士を混ぜ込むことすらできる。
https://docs.astro.build/en/core-concepts/framework-components/#nesting-framework-components
ワークアラウンド
幸い自分のケースは軽傷で、こんな風なコンポーネントを`.svelte`で作ってた。
<div class="layout"> <div> <slot name="main" /> </div> <div> <slot name="sub" /> </div> </div> <style> .layout { display: grid; grid-template-columns: 1fr 300px; gap: 16px; } </style>
というように、2カラムにしたいだけだった。
なので、名前付き`slot`を使わずに、単一の`slot`だけでもなんとかなった。
<div class="layout"> <slot /> </div> <style> .layout { display: grid; grid-template-columns: 1fr 300px; gap: 16px; } </style>
使う側はこう。
<Layout> <Main /> <Sub /> </Layout>
ただし、`Main`も`Sub`も単一の要素を返すという暗黙の前提が生まれてしまうけど・・・。