Le schéma dans le code. Le contenu par HTTP.
Définis tes collections en TypeScript, modifie-les dans l'admin, lis-les via REST, GraphQL ou le loader Astro. Hébergé dans l'UE, ou sur tes propres serveurs.
Quatre choses que tu peux vérifier.
- Le schéma Quatorze types de champ Texte, textarea, texte riche, nombre, booléen, date et heure, slug, select, relation, média, groupe, tableau, JSON, blocs. Tous exportés par le paquet core.
- La lecture publique Sans clé, 404 par défaut Une collection se lit sans clé seulement si sa règle d'accès admet un appelant anonyme. Tout le reste répond 404, jamais 403.
- Les langues Dix langues de contenu Champs localisés, une matrice de couverture par page et par langue, et les manques en CSV.
- Les clés Hachées, montrées une fois Les clés API sont stockées sous forme de hachage HMAC avec pepper. Tu vois la clé à la création ; l'admin garde les quatre derniers caractères.
D'un fichier TypeScript à une page sur le web.
Fais défiler. Le même contenu, à chacune de ses quatre étapes.
- 01 · Schéma
Tu définis la collection en TypeScript.
Slug, champs, règles d'accès. Elle vit dans ton dépôt et passe en revue comme n'importe quel autre code.
import { defineCollection, fields } from '@osprey/core' export const blogPost = defineCollection({ slug: 'blog-post', access: { read: () => true }, fields: { slug: fields.slug({ from: 'title' }), locale: fields.text({ required: true }), title: fields.text({ required: true }), excerpt: fields.textarea(), body: fields.richText({ required: true }), publishedAt: fields.datetime(), }, }) - 02 · Admin
L'admin lit le schéma et dessine le formulaire.
Champs obligatoires, sélecteur de langue, corps en texte riche. Rien n'est configuré deux fois.
- 03 · API
Les entrées publiées sortent en JSON.
Un GET, sans clé, avec SEO, canonical et hreflang déjà fusionnés dans chaque entrée.
GET /api/v1/collections/blog-post/entries?locale=en Host: cms.altovar.net 200 OK { "data": [ { "id": "fdoc_16d9i3ef", "data": { "title": "EU-first content infrastructure", … }, "seo": { "metaTitle": "EU-first content infrastructure", … }, "canonical": "https://…/en/eu-first-content-infrastructure", "alternates": { "en": …, "x-default": … } } ], "pagination": { "page": 1, "limit": 20, "total": 3 } } - 04 · Site
Ton frontend les affiche.
Le loader Astro récupère les entrées au build. Le blog ci-dessous est construit exactement ainsi, depuis ce CMS.
Ouvrir le blog en direct →import { defineCollection } from 'astro:content' import { ospreyLoader } from '@osprey/astro' const blog = defineCollection({ loader: ospreyLoader({ collection: 'blog-post', baseUrl: 'https://cms.altovar.net', tenantId: 'altovar', }), })
Ton contenu. Ton serveur. Aujourd'hui.
Offre gratuite, sans carte. Hébergé dans l'UE, ou sur tes propres machines.