@filo-cms/sdk
v0.3.2
Published
SDK for sites consuming Filo CMS: typed API client (any framework or plain JS), section renderers for Vue and React, resolveSections() for Svelte/Angular, live-preview bridge.
Readme
@filo-cms/sdk
Typed client SDK for sites consuming a Filo CMS instance: delivery-API client, section renderers and a live-preview bridge.
Works in any JavaScript environment — the core is plain fetch with zero dependencies, shipped as ESM and CommonJS with full TypeScript types.
| Environment | Import | Section rendering |
|---|---|---|
| Nuxt / Vue | @filo-cms/sdk + @filo-cms/sdk/vue | <FiloSections> component |
| React / Next.js | @filo-cms/sdk + @filo-cms/sdk/react | <FiloSections> component |
| Svelte / Angular / Solid | @filo-cms/sdk | resolveSections() helper |
| Node / vanilla JS | @filo-cms/sdk (import or require) | — |
Install
npm install @filo-cms/sdkFetching content
import { createFiloClient } from "@filo-cms/sdk";
const cms = createFiloClient({
baseUrl: "https://cms.example.com",
apiKey: process.env.FILO_API_KEY, // only needed for drafts (?preview=true)
});
const { items, total } = await cms.entries.list("post", {
limit: 10,
sort: "publishedAt:desc", // entry columns or data fields
filter: { featured: true, price: { gte: 100 } }, // eq/ne/lt/lte/gt/gte/contains/in/notIn
search: "nuxt", // slug + content search
locale: "en",
});
const post = await cms.entries.bySlug("post", "hello-world");
const page = await cms.pages.bySlug("home");
const url = cms.mediaUrl(post.data.coverImage);
const ok = await cms.health(); // { status, db, version }Errors throw a typed FiloError with status and path.
Tip:
GET https://your-instance/api/v1returns a machine-readable index of every endpoint available on that instance.
Rendering page sections
Register your own components per section type — the CMS supplies data only, you keep full control of markup:
<!-- Vue -->
<script setup>
import { FiloSections } from "@filo-cms/sdk/vue";
</script>
<template>
<FiloSections :sections="page.sections" :registry="{ hero: Hero, 'rich-text': RichText }" />
</template>// React
import { FiloSections } from "@filo-cms/sdk/react";
<FiloSections sections={page.sections} registry={{ hero: Hero, "rich-text": RichText }} /><!-- Svelte (resolveSections is framework-agnostic) -->
<script>
import { resolveSections } from "@filo-cms/sdk";
const registry = { hero: Hero, "rich-text": RichText };
</script>
{#each resolveSections(page.sections, registry) as s (s.props.sectionId)}
<svelte:component this={s.component} {...s.props} />
{/each}Live preview
Let editors see drafts rendered by your site inside the CMS entry editor, updating as they type. Configure the preview URL in the CMS (Settings → Live preview), then in your preview route:
// Vue (from @filo-cms/sdk/vue) or React (from @filo-cms/sdk/react):
const live = useFiloPreviewEntry(entry, { allowedOrigins: ["https://cms.example.com"] });
// outside the CMS iframe `live` stays === entry; inside it becomes the streamed draft
// Any framework — raw bridge:
import { connectPreviewBridge } from "@filo-cms/sdk";
const stop = connectPreviewBridge(
{ onEntry: ({ contentType, entry }) => render(entry) },
{ allowedOrigins: ["https://cms.example.com"] },
);Always pass allowedOrigins in production — the bridge ignores messages from any other origin.
Links
- Filo CMS repository & documentation
@filo-cms/cms— the CMS itself- License: MIT
