Documentation
Trois façons de lire le contenu, et une référence générée à partir des routes elles-mêmes : elle ne peut donc pas décrire un point de terminaison qui n'existe pas.
Démarrages rapides
fetch, tout simplement
Pas de SDK, pas d'étape de compilation. Voilà toute l'intégration pour une liste de billets.
const response = await fetch(
"https://api.schemahaus.com/v1/content/blog-post?locale=ka&limit=10",
{ headers: { authorization: `Bearer ${process.env.SCHEMAHAUS_TOKEN}` } },
);
const { data, meta } = await response.json();
// data is only what is PUBLISHED in Georgian. Nothing is substituted
// unless you ask: add &fallback=chain, and check item.localeFallback.Next.js
Le SDK et un webhook de revalidation : quand un rédacteur clique sur Publier, la page est reconstruite sans attendre l'expiration d'un cache.
// app/[locale]/blog/[slug]/page.tsx
import { createClient } from "@schemahaus/client";
const cms = createClient({
token: process.env.SCHEMAHAUS_TOKEN,
site: process.env.SCHEMAHAUS_SITE,
});
export default async function Post({ params }) {
const { locale, slug } = await params;
const post = await cms.document("blog-post", slug, { locale });
if (!post) notFound();
return <article dangerouslySetInnerHTML={{ __html: post.data.body }} />;
}
// Publishing fires a webhook. Point a nextjs_revalidate webhook at your
// deploy and the page rebuilds itself when an editor presses publish.Jekyll, à la compilation
Pour un site statique sans aucun environnement d'exécution : récupérez le contenu pendant la compilation et écrivez les fichiers attendus par le générateur.
# _plugins/schemahaus.rb — runs at build time, writes _posts/
require "net/http"
require "json"
site = ENV.fetch("SCHEMAHAUS_SITE")
token = ENV.fetch("SCHEMAHAUS_TOKEN")
uri = URI("https://api.schemahaus.com/v1/content/blog-post?locale=en")
request = Net::HTTP::Get.new(uri)
request["authorization"] = "Bearer #{token}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
JSON.parse(response.body)["data"].each do |post|
File.write("_posts/#{post["publishedAt"][0, 10]}-#{post["slug"]}.md",
"---\ntitle: #{post["data"]["title"].inspect}\n---\n" +
post["data"]["body"])
endRéférence de l'API
Lue dans l'arborescence des routes à la compilation. Un point de terminaison apparaît ici quand le fichier existe et disparaît quand il est supprimé : cette page ne peut donc pas documenter ce qui n'existe pas.
Diffusion
Le contenu publié, lu avec un jeton de diffusion. Vous pouvez le placer sans risque dans l'environnement d'un site consommateur : il peut lire, et rien d'autre.
GET/api/v1/authorsThe site's authors, with their per-language biographies.
GET/api/v1/content/{apiId}Published documents of one content type. Filter, sort, paginate by `page` or by cursor (`?cursor=` to start, then each page's `meta.nextCursor`); `?locale=` is strict unless `fallback` says otherwise.
GET/api/v1/content/{apiId}/{identifier}One published document, by slug or by document id.
GET/api/v1/media/{id}One media asset's metadata and variant URLs.
POST/api/v1/preview/verifyExchange a preview token for the draft it was minted for. Needs a delivery token with draft access.
GET/api/v1/siteThe site's settings and its content languages.
GET/api/v1/site/typesThe content types on the site, with their fields. Addressed by apiId; no internal ids are returned.
Gestion
Les écritures, liées à l'adhésion d'un membre : une clé ne peut jamais faire plus que la personne qui l'a créée. C'est ce qu'utilisent les scripts d'importation.
GETPOST/api/v1/manage/authorsList or create authors.
PATCHDELETE/api/v1/manage/authors/{id}Edit or remove one author.
POST/api/v1/manage/documentsCreate a document in one language.
PATCHDELETE/api/v1/manage/documents/{id}Edit one language version, or soft-delete the whole document. Editing takes the revision you last read.
POST/api/v1/manage/documents/{id}/localesStart a translation of a document.
POST/api/v1/manage/documents/{id}/transitionMove one language version through the workflow, including publishing it.
GET/api/v1/manage/documents/lookupFind a document by slug, drafts included — how an import decides whether it has already brought a post across.
POST/api/v1/manage/mediaReserve an upload and get a presigned PUT for object storage.
POST/api/v1/manage/media/{id}/completeConfirm the bytes arrived. Idempotent, so a retried import does not count the storage twice.
GET/api/v1/manage/typesContent types WITH their internal ids, which every write below needs.
Compatibilité Strapi
La forme des requêtes Strapi sur le même contenu publié, pour qu'un site existant puisse migrer avant d'être réécrit.
GET/api/strapi/api/{plural}The Strapi compatibility layer: Strapi's query shape over the same published content, so an existing site can move before it is rewritten.
Quatre règles à connaître avant de commencer
- La diffusion est stricte par défaut
- `?locale=ka` ne renvoie que ce qui est publié en géorgien. Un contenu manquant reste visiblement manquant au lieu de devenir silencieusement de l'anglais. Ajoutez `fallback=default` ou `fallback=chain` pour activer le repli, et vérifiez `localeFallback` sur chaque élément pour voir ce qui a été substitué.
- L'API sert les données publiées, jamais les brouillons
- Un document en cours de modification continue de servir sa dernière version publiée jusqu'à la prochaine publication. Si une modification n'apparaît pas, c'est qu'elle n'a pas été publiée : c'est voulu.
- Les clés des médias ne changent jamais
- Remplacer une image crée une nouvelle ressource avec une nouvelle URL. L'ancienne continue de fonctionner, car les caches périphériques et les sites déjà compilés pointent encore vers elle.
- Chaque langue est publiée séparément
- Publier l'anglais ne publie pas l'allemand. Un document n'a pas d'état de publication unique : chaque version linguistique a le sien.