Integrations

SvelteKit Integration

Connect Blogree to your SvelteKit application using SvelteKit's server-side API routes. The webhook handler receives new posts and triggers page invalidation.

Step 1 — Install the Blogree SDK

npm install @blogree/js-sdk
# .env BLOGREE_API_KEY=bk_live_xxxxxxxxxxxx BLOGREE_API_URL=https://api.blogree.com BLOGREE_WEBHOOK_SECRET=whs_xxxxxxxxxxxx

Step 2 — Create the Webhook Handler

// src/routes/api/blogree/+server.ts import { json } from '@sveltejs/kit'; import { BLOGREE_WEBHOOK_SECRET } from '$env/static/private'; import { createHmac, timingSafeEqual } from 'crypto'; function verifySignature(rawBody: string, signature: string): boolean { const expected = 'sha256=' + createHmac('sha256', BLOGREE_WEBHOOK_SECRET) .update(rawBody).digest('hex'); try { return timingSafeEqual(Buffer.from(expected), Buffer.from(signature)); } catch { return false; } } export async function POST({ request }) { const rawBody = await request.text(); const signature = request.headers.get('x-blogree-signature') || ''; if (!verifySignature(rawBody, signature)) { return json({ error: 'Unauthorized' }, { status: 401 }); } const payload = JSON.parse(rawBody); const post = payload.post; // Store post — example with a simple JSON file store // In production, use your database (Prisma, Supabase, etc.) await storeBlogPost(post); // Confirm delivery to Blogree await fetch(`${process.env.BLOGREE_API_URL}/api/pull/confirm`, { method: 'POST', headers: { 'X-API-Key': process.env.BLOGREE_API_KEY || '', 'Content-Type': 'application/json' }, body: JSON.stringify({ post_id: post.id, site_id: post.site_id, status: 'delivered' }), }); return json({ success: true }, { status: 200 }); }

Step 3 — Fetch Posts in Pages

// src/routes/blog/+page.server.ts import { BLOGREE_API_KEY, BLOGREE_API_URL } from '$env/static/private'; export async function load({ fetch }) { const res = await fetch(`${BLOGREE_API_URL}/api/pull/posts`, { headers: { 'X-API-Key': BLOGREE_API_KEY }, }); const { posts } = await res.json(); return { posts }; } // src/routes/blog/+page.svelte <script> export let data; </script> <ul> {#each data.posts as post} <li><a href="/blog/{post.slug}">{post.title}</a></li> {/each} </ul>
// src/routes/blog/[slug]/+page.server.ts import { BLOGREE_API_KEY, BLOGREE_API_URL } from '$env/static/private'; import { error } from '@sveltejs/kit'; export async function load({ params, fetch }) { const res = await fetch(`${BLOGREE_API_URL}/api/pull/posts/${params.slug}`, { headers: { 'X-API-Key': BLOGREE_API_KEY }, }); if (res.status === 404) throw error(404, 'Post not found'); const post = await res.json(); return { post }; } // src/routes/blog/[slug]/+page.svelte <script> export let data; </script> <svelte:head> <title>{data.post.meta.title}</title> <meta name="description" content={data.post.meta.description} /> </svelte:head> <article> <h1>{data.post.title}</h1> {@html data.post.body.html} </article>

Step 4 — Set Webhook URL in Blogree

Your SvelteKit webhook URL is the route you created:

https://yourdomain.com/api/blogree

Paste this in the Blogree dashboard under Sites → your site → Settings → Webhook URL, then click Test Delivery.

Database Integration Example (Prisma)

For production, store posts in a database instead of the filesystem. Here's the webhook handler using Prisma:

// src/routes/api/blogree/+server.ts (with Prisma) import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); // Inside POST handler, after verification: const post = payload.post; await prisma.post.upsert({ where: { slug: post.slug }, update: { title: post.title, content: post.body.html, excerpt: post.excerpt, metaTitle: post.meta.title, metaDescription: post.meta.description, tags: post.tags, publishedAt: new Date(post.published_at), }, create: { slug: post.slug, title: post.title, content: post.body.html, excerpt: post.excerpt, metaTitle: post.meta.title, metaDescription: post.meta.description, tags: post.tags, publishedAt: new Date(post.published_at), }, });