Svelte Git CMS
- It uses Github issues as a CMS
- All issues and labels are only pulled once when your website is visited first time after being deployed.
- Anytime you create or update a issue or label it get's synced using github webhook
- All subsequent visits to your website uses the data stored in server side store
-
Install the package in your sveltekit app
npm i -D svelte-git-cms
-
Create src/hooks.js
with following content
import { synced } from 'svelte-git-cms';
import { sync } from 'svelte-git-cms';
import { get } from 'svelte/store';
export async function handle({ event, resolve }) {
if (!get(synced)) { await sync() }
const response = await resolve(event);
return response;
}
-
Create an webhook route for github, so github can inform your app when issues or labels change.
a) Create webhook endpoint src/routes/api/git-webhook/+server.js
import { handleWebhook } from 'svelte-git-cms';
export async function POST({ request }) {
return handleWebhook(request)
}
b) Go to your github repo Settings > Webhooks > Add webhook
and create a new webhook with following config:
- Payload URL
https://YOUR_PRODUCTION_DOMAIN/api/git-webhook
- Content type
application/json
- Events Select
Issues
and Labels
-
Create +page.server.js
in the route you want to show the posts / labels.
a) src/routes/+page.server.js
import { labels, posts } from 'svelte-git-cms';
import { get } from 'svelte/store';
export async function load({ params }) {
return {
posts: get(posts),
labels: get(labels)
}
}
b) src/routes/+page.svelte
<script>
export let data;
</script>
<ul>
{#each Object.keys(data.labels) as label}
<li>{label}</li>
{/each}
</ul>
{#if Object.keys(data.posts).length}
<ul>
{#each Object.entries(data.posts) as [slug, post]}
<li>
/{slug}
{post.title}
{post.body}
</li>
{/each}
</ul>
{:else}
No posts
{/if}
Notes
- If everything is setup correctly any new issue you create with label
+page
will be instantly available on your webiste. (can be customized by setting env GITHUB_LABEL_PUBLISHED
)
- You can also attach more labels on the issue which will be available as
tags
property in the post
object. (label set in GITHUB_LABEL_PUBLISHED
won't be available in tags, as this label is used tpo determine which issue should appear as post on the website)
- All labels must have a prefix
+
example +Idea
, +Personal
etc, prefix will be removed when converted to post tags.
- If you do not like the
+
prefix you can change it by setting environmanet variable GITHUB_LABEL_PREFIX
to any other character or leave it empty for no prefix.
Tips
Here are some tips I use on my projects using svelte-git-cms
to improve the experience using some external lib which are not included in the package to keep at minimum and package size slow.
-
Add a Medium like reading time estimater
a) Install the library
npm i -D reading-time-estimator
b) Change the part a
of Step 4
above as following:
import { labels, posts } from 'svelte-git-cms';
import { get } from 'svelte/store';
import { readingTime } from 'reading-time-estimator'
export async function load({ params }) {
let posts = get(posts)
Object.keys(posts).map(key => {
posts[key].readingTime = readingTime(posts[key].body).text
})
return {
posts,
labels: get(labels)
}
}
Inspiration
The idea of using github as CMS is inspired from swyxkit