Sari la conținut

SDK

createClient, citiri tipizate, tipuri generate, previzualizare și verificarea webhook-urilor.

DocumentațieAPI

Meniul documentațieiSDK

@manifolio/sdk citește conținutul din Next.js, Astro, Cloudflare Workers sau orice server cu Node 18+. Nu are dependențe, dă tip fiecărei intrări și verifică webhook-urile.

Shell
npm i @manifolio/sdk

createClient

TypeScript
import { createClient } from "@manifolio/sdk";

export const cms = createClient({
  project: process.env.MANIFOLIO_PROJECT!,   // id-ul proiectului
  key: process.env.MANIFOLIO_KEY!,           // mf_live_ sau mf_test_
  locale: "ro",                              // limba implicită a cererilor
});
OpțiuneCe face
projectid-ul proiectului, din Developers → API keys → Connection
keyo cheie secretă; cheile publicabile mf_pk_ sunt refuzate
localelimba implicită; altfel, limba principală a proiectului
environmentproduction sau development; dacă e dat, trebuie să se potrivească cu cheia
previewcitește ciornele prin Preview API (cheia are nevoie de content:preview)
baseUrlimplicit https://api.manifolio.com
fetchpropriul fetch, de exemplu un service binding din Cloudflare
fetchOptionsse adaugă la fiecare cerere, de exemplu { next: { revalidate: 60 } } în Next.js

SDK-ul refuză să ruleze cu o cheie secretă în browser.

Citirea

TypeScript
await cms.entries("article", {
  locale: "ro",                        // cade pe limba principală, câmp cu câmp
  fields: ["title", "slug", "date"],
  sort: "-date",                       // published, updated sau un câmp; cu - descrescător
  filter: { series: "toamna", date: { gte: "2026-01-01" }, tags: ["cafea", "evenimente"] },
  populate: 2,                         // referințele devin intrări, pe două niveluri
});

await cms.page("article", { limit: 20, cursor });   // { entries, nextCursor }
await cms.entry("article", "primul-articol");       // după slug sau id, null dacă lipsește
await cms.singleton("site_settings");               // intrarea unui tip singleton
await cms.types();                                  // limbile și schema publică

entries urmează nextCursor pagină cu pagină până le are pe toate, sau până la max intrări. Un array în filter înseamnă in.

Fiecare intrare are _id, _type, _locale, _publishedAt și _updatedAt lângă câmpurile ei.

Erori

Cererile eșuate aruncă ManifolioError, cu status și code:

TypeScript
import { ManifolioError } from "@manifolio/sdk";

try {
  await cms.entries("article");
} catch (e) {
  if (e instanceof ManifolioError && e.code === "type_not_found") {
    // tipul a fost redenumit sau șters
  }
}

entry și singleton întorc null pentru o intrare care lipsește, în loc să arunce o eroare.

Conținut tipizat

Shell
npx manifolio types --out src/manifolio.d.ts

Comanda citește MANIFOLIO_PROJECT și MANIFOLIO_KEY (și din .env și .env.local) sau --project, --key și --base-url. Fișierul generat îți înregistrează tipurile în SDK: cms.entries("article") întoarce intrări Article, numele câmpurilor se completează singure în fields, filter și sort, iar o cheie de tip necunoscută e eroare de tip. O rulezi din nou după ce schimbi structura.

Previzualizare

TypeScript
export const preview = createClient({
  project: process.env.MANIFOLIO_PROJECT!,
  key: process.env.MANIFOLIO_PREVIEW_KEY!,   // o cheie cu content:preview
  preview: true,
});

const ciorna = await preview.entry("article", "primul-articol");
ciorna?._status;   // "draft", "published" sau "changed"

O pui în spatele modului de ciornă al framework-ului, ca doar editorii să vadă conținutul nepublicat.

Framework-uri

Next.js (App Router), cu o fereastră de reîmprospătare:

TypeScript
export const cms = createClient({
  project: process.env.MANIFOLIO_PROJECT!,
  key: process.env.MANIFOLIO_KEY!,
  fetchOptions: { next: { revalidate: 60 } },
});

Astro, citit în frontmatter-ul paginii (la build pentru paginile statice, la fiecare cerere cu un adaptor):

TypeScript
import { createClient } from "@manifolio/sdk";

const cms = createClient({ project: import.meta.env.MANIFOLIO_PROJECT, key: import.meta.env.MANIFOLIO_KEY });
const articole = await cms.entries("article", { sort: "-published" });

Cloudflare Workers, printr-un service binding:

TypeScript
const cms = createClient({ project: env.MANIFOLIO_PROJECT, key: env.MANIFOLIO_KEY, fetch: (req, init) => env.API.fetch(req, init) });

Verificarea webhook-urilor

TypeScript
import { parseWebhook, verifyWebhook } from "@manifolio/sdk";

const body = await req.text();   // corpul brut, exact cum a sosit
const event = await parseWebhook(process.env.MANIFOLIO_WEBHOOK_SECRET!, body, req.headers.get("manifolio-signature"));

parseWebhook aruncă ManifolioError(401, "invalid_signature") când semnătura nu se potrivește sau e mai veche de cinci minute. verifyWebhook întoarce în schimb true sau false. Detalii la Webhook-uri.