Svelte Headless CMS

How it works

Blog Get Started

How to use SvelteKit and Pullnote to build an editable website

A dynamic svelte folder called [...path] sends all traffic via 2 files. First is the server-side +layout.server.js which grabs from pullnote.

// /src/routes/+layout.server.js
// Server-side content retrieval for all content pages
// You can just use e.g. /blog by moving this and the [...path] folder into a /blog subdirectory
// Place your own pullnote key in /.env
import { PULLNOTE_KEY } from '$env/static/private';
import { PullnoteClient } from '@pullnote/client';

export async function load({ url }) {
  var path = url.pathname;
  if (path.startsWith("/.")) return; // Ignore paths that start with . e.g. .well-known/appspecific/com.chrome.devtools.json

  // Create the pullnote client with your own key
  const pn = new PullnoteClient(PULLNOTE_KEY);

  // Pullnote accepts any path (without the domain name)
  var note = await pn.get(path, 'html');
  // list gives any notes under the given path
  note.links = await pn.list(path);

  return note;
}

+page.svelte then picks up that data via page.data and renders the content returned.

<script>
  // /src/routes/[...path]/+page.svelte
  import { page } from '$app/state';
  import SubPages from '$components/SubPages.svelte';

  let note = $derived(page.data);
</script>

<div class="my-9">
  
  <div class="flex flex-col gap-5 md:w-2/3 mx-auto content">
    

    {#if note.imgUrl}
      <img src={note.imgUrl} alt={note.title} class="rounded-xl" />
    {/if}

    <!-- Pass the pullnote HTML through -->
    {@html note.content}

  </div>

</div>

A simple +layout.svelte with Header and Footer components lays everything out with app.css providing the tailwind formatting.

See the Pullnote documentation for more details.


Download the code for this blog from GitHub at https://github.com/webuildsociety/svelte-headless