Skip to content
Docs

SvelteKit

@citedseo/svelte gives your load functions the feed and your pages their head tags. Two routes with server load functions.

Hand this to your coding agent

Read https://developer.citedseo.ai/llms-full.txt.
My CitedSEO site ID is <YOUR_SITE_ID>.
Install @citedseo/svelte. Add /blog and /blog/[slug] routes with server load functions and the article's JSON-LD in svelte:head in this SvelteKit app, reading my articles with that package.
The feed needs no key. Use only the functions and addresses that file lists.
Terminal window
npm install @citedseo/svelte
  • .env
  • Directorysrc
    • Directoryroutes
      • Directoryblog
        • +page.server.ts
        • +page.svelte the index
        • Directory[slug]
          • +page.server.ts
          • +page.svelte one article
      • Directoryapi
        • Directorycitedseo
          • +server.ts the webhook
  1. Set your site ID.

    .env
    CITEDSEO_SITE_ID=YOUR_SITE_ID
  2. Add the index.

    src/routes/blog/+page.server.ts
    import { fetchArticles } from '@citedseo/svelte';
    import { CITEDSEO_SITE_ID } from '$env/static/private';
    import type { PageServerLoad } from './$types';
    export const load: PageServerLoad = async ({ fetch }) => {
    const articles = await fetchArticles({ siteId: CITEDSEO_SITE_ID, fetch });
    return {
    articles: articles.map(({ id, slug, title, description }) => ({ id, slug, title, description })),
    };
    };
    src/routes/blog/+page.svelte
    <script lang="ts">
    let { data } = $props();
    </script>
    <ul>
    {#each data.articles as article (article.id)}
    <li>
    <a href={`/blog/${article.slug}`}>{article.title}</a>
    <p>{article.description}</p>
    </li>
    {/each}
    </ul>
  3. Add the article page. articleHead gives the title, description, canonical address, Open Graph tags and the JSON-LD script tag.

    src/routes/blog/[slug]/+page.server.ts
    import { articleHead, fetchArticle } from '@citedseo/svelte';
    import { error } from '@sveltejs/kit';
    import { CITEDSEO_SITE_ID } from '$env/static/private';
    import type { PageServerLoad } from './$types';
    export const load: PageServerLoad = async ({ params, fetch }) => {
    const article = await fetchArticle({ siteId: CITEDSEO_SITE_ID, slug: params.slug, fetch });
    if (!article) error(404, 'Article not found');
    return { article, head: articleHead(article) };
    };
    src/routes/blog/[slug]/+page.svelte
    <script lang="ts">
    let { data } = $props();
    const { article, head } = $derived(data);
    </script>
    <svelte:head>
    <title>{head.title}</title>
    <meta name="description" content={head.description} />
    <link rel="canonical" href={head.canonical} />
    {#each head.meta as tag}
    <meta {...tag} />
    {/each}
    {#if head.jsonLdTag}
    {@html head.jsonLdTag}
    {/if}
    </svelte:head>
    <article>
    <h1>{article.title}</h1>
    {#if article.cover}
    <img src={article.cover.src} alt={article.cover.alt} />
    {/if}
    {@html article.html}
    </article>

To build the blog as static pages, add export const prerender = true; to both +page.server.ts files, and rebuild when a webhook arrives.

On a server, each page view reads the manifest and one small file, both cached by the network, so a new article shows within a minute. See Caching and limits.

Either way, webhookHandler checks the signature of a post for you:

src/routes/api/citedseo/+server.ts
import { webhookHandler } from '@citedseo/svelte';
import { CITEDSEO_WEBHOOK_SECRET } from '$env/static/private';
import type { RequestHandler } from './$types';
const handle = webhookHandler({
secret: CITEDSEO_WEBHOOK_SECRET,
onPost: async (post) => {
// Start a build, clear your cache, or store post.data.
},
});
export const POST: RequestHandler = ({ request }) => handle(request);

See Update the moment you publish.

Each article’s url is where CitedSEO expects it to live, and its structured data and canonical address say so. If your blog isn’t at /blog, set the site’s blog path in the app’s settings to match your route. See SEO for your article pages.