A SvelteKit example showing Comark with lazy components, ComarkAsync, and SSR.
+page.svelte
<script lang="ts">
  import { ComarkAsync } from '@comark/svelte/async'
  import type { PageData } from './$types'
  import { pascalCase } from '@comark/svelte/utils';

  let { data }: { data: PageData } = $props()

  const modules = import.meta.glob('../lib/components/comark/*.svelte')

  const componentsManifest = (name: string) => {
    return modules[`../lib/components/comark/${pascalCase(name)}.svelte`]?.()
  }

  function errorMessage(error: unknown) {
    return error instanceof Error ? error.message : String(error)
  }
</script>

<div class="page-grid">
  <article class="panel">
    <svelte:boundary>
      <ComarkAsync
        class="prose"
        markdown={data.markdown}
        {componentsManifest}
      />
      {#snippet failed(error)}
        <p class="boundary-state">Failed to render Comark: {errorMessage(error)}</p>
      {/snippet}
    </svelte:boundary>
  </article>

  <aside class="panel aside">
    <p class="eyebrow">What this proves</p>
    <p class="lead">
      This route keeps <code>LazyCard.svelte</code> behind a dynamic import and
      still renders it into the SvelteKit SSR HTML.
    </p>
    <ul class="status-list">
      <li><code>ComarkAsync</code> parses markdown during SSR.</li>
      <li><code>componentsManifest</code> returns a non-eager dynamic import.</li>
      <li><code>&lt;svelte:boundary&gt;</code> handles async errors without replacing SSR HTML.</li>
    </ul>
  </aside>
</div>
https://comark-sveltekit.vercel.app

This example demonstrates how to use Comark with SvelteKit and server-side rendering.

How it works

  • Lazy SSR route/ renders markdown with <ComarkAsync> and resolves custom components through an explicit dynamic import map.
  • Stable SSR route/stable parses markdown in +page.server.ts and renders the AST with <ComarkRenderer>.
  • Scoped Markdown components — components rendered from Comark live in src/lib/components/comark/, separate from normal app UI components.
  • Component manifest — the examples show when to return dynamic imports and when to use eager/static entries for synchronous SSR.

Run locally:

pnpm --filter comark-sveltekit dev