|
Hi guys. I have this component: <script lang="ts">
type AppShellProps = {
children: Snippet;
header: Snippet;
};
const { children, header }: AppShellProps = $props();
</script>
<Sidebar.Provider style="--sidebar-width: 374px;">
<AppSidebar />
<Sidebar.Inset class="relative gap-y-4 pt-2 md:p-2">
<Card class="sticky top-0 overflow-hidden rounded-none md:rounded-lg">
<header class="bg-background flex shrink-0 items-center gap-2 border-b p-2 px-4">
<!-- Dynamic Header Content Goes Here -->
{@render header()}
</header>
</Card>
<Card class="flex-1 rounded-none md:rounded-lg">
<ScrollArea class="flex h-[calc(100svh-(--spacing(4))-64px)] flex-1 flex-col gap-4 md:p-4">
{@render children()}
</ScrollArea>
</Card>
</Sidebar.Inset>
</Sidebar.Provider>And it's used in <script lang="ts">
let { children } = $props();
</script>
<ParaglideJS {i18n}>
<AppShell>
{#snippet header()}
<p>header content</p>
{/snippet}
{@render children?.()}
</AppShell>
</ParaglideJS>I have pages that use the same layout but with different header content. I thought maybe I can use a store for header snippet, so I tried it: import { getContext, setContext, type Snippet } from "svelte";
class HeaderSnippetStore {
#headerSnippet = $state<Snippet>();
get headerSnippet() {
return this.#headerSnippet;
}
setHeaderSnippet(snippet: Snippet) {
this.#headerSnippet = snippet;
}
}
const HEADER_SNIPPET_STORE_KEY = Symbol("header-snippet-store-key");
export function setHeaderSnippetStore() {
return setContext(HEADER_SNIPPET_STORE_KEY, new HeaderSnippetStore());
}
export function getHeaderSnippetStore() {
return getContext<ReturnType<typeof setHeaderSnippetStore>>(HEADER_SNIPPET_STORE_KEY);
}<-- +layout.svelte -->
<script lang="ts">
import { getHeaderSnippetStore, setHeaderSnippetStore } from './_stores/header-snippet.svelte';
let { children } = $props();
setHeaderSnippetStore();
const headerSnippetStore = getHeaderSnippetStore();
</script>
<ParaglideJS {i18n}>
<AppShell header={headerSnippetStore.headerSnippet}>
{@render children?.()}
</AppShell>
</ParaglideJS><-- first-page/+page.svelte -->
<script>
import { getHeaderSnippetStore } from './_stores/header-snippet.svelte';
const headerSnippetStore = getHeaderSnippetStore();
headerSnippetStore.setHeaderSnippet(header);
</script>
{#snippet header()}
<p>my header</p>
{/snippet}<-- second-page/+page.svelte -->
<script>
import { getHeaderSnippetStore } from './_stores/header-snippet.svelte';
const headerSnippetStore = getHeaderSnippetStore();
headerSnippetStore.setHeaderSnippet(header);
</script>
{#snippet header()}
<p>another header for the second page</p>
{/snippet}And it kinda works but the header becomes a client-side only component, it is not present in the html document I receive from the server. Are there other ways to implement dynamic header? Ideally I want header to be presented in the html on initial page load. |
Answered by
brunnerh
Mar 8, 2025
Replies: 1 comment 10 replies
Answer selected by
bnn1
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is a workaround, see comment here.