Das Schema im Code. Der Inhalt über HTTP.

Definiere Collections in TypeScript, bearbeite sie im Admin, lies sie per REST, GraphQL oder dem Astro-Loader. Gehostet in der EU, oder auf deinen eigenen Servern.

Der Osprey-Admin beim Bearbeiten einer veröffentlichten Seite direkt auf der Seite: die Live-Seite in der Mitte mit vierzehn markierten editierbaren Feldern, die Feldliste links, der Sprachwähler und der Button Veröffentlichen in der Leiste. Der Osprey-Admin beim Bearbeiten einer veröffentlichten Seite direkt auf der Seite: die Live-Seite in der Mitte mit vierzehn markierten editierbaren Feldern, die Feldliste links, der Sprachwähler und der Button Veröffentlichen in der Leiste.
Der Admin, beim Bearbeiten einer Live-Seite. Ein Screenshot, kein Mockup. Der Admin gibt es auf Englisch und Italienisch, deshalb sind diese Aufnahmen der englische Satz.

Vier Dinge, die du prüfen kannst.

  • Das Schema Vierzehn Feldtypen Text, Textarea, Rich Text, Zahl, Boolean, Datum und Zeit, Slug, Select, Relation, Media, Gruppe, Array, JSON, Blöcke. Alle vom Core-Paket exportiert.
  • Der öffentliche Lesezugriff Ohne Schlüssel, 404 als Standard Eine Collection ist nur dann ohne Schlüssel lesbar, wenn ihre Zugriffsregel anonyme Aufrufer zulässt. Alles andere antwortet mit 404, nie mit 403.
  • Die Sprachen Zehn Inhaltssprachen Lokalisierte Felder, eine Abdeckungsmatrix pro Seite und Sprache, und die Lücken als CSV.
  • Die Schlüssel Gehasht, einmal gezeigt API-Schlüssel werden als HMAC-Hash mit Pepper gespeichert. Du siehst den Schlüssel beim Erstellen; der Admin behält die letzten vier Zeichen.
Jede Funktion im Detail →

Von einer TypeScript-Datei zu einer Seite im Web.

Scrolle. Derselbe Inhalt, an jeder seiner vier Stationen.

  1. 01 · Schema

    Du definierst die Collection in TypeScript.

    Slug, Felder, Zugriffsregeln. Sie lebt in deinem Repository und geht durch das Review wie jeder andere Code.

    content/blog-post.tsTS
    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(),
      },
    })
  2. 02 · Admin

    Der Admin liest das Schema und zeichnet das Formular.

    Pflichtfelder, der Sprachwähler, der Rich-Text-Body. Nichts wird zweimal konfiguriert.

  3. 03 · API

    Veröffentlichte Einträge kommen als JSON heraus.

    Ein GET, ohne Schlüssel, mit SEO, Canonical und hreflang bereits in jedem Eintrag zusammengeführt.

    entriesHTTP
    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 } }
  4. 04 · Website

    Dein Frontend rendert sie.

    Der Astro-Loader holt die Einträge beim Build. Der Blog unten ist genau so gebaut, aus diesem CMS.

    Den Live-Blog öffnen →
    src/content.config.tsASTRO
    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',
      }),
    })

Der Admin, in deinem Thema und deiner Sprache.

Hell oder dunkel, Englisch oder Italienisch. Jede Aufnahme auf dieser Seite folgt dem Thema, das du oben wählst: derselbe Admin, zweimal fotografiert.

Dein Inhalt. Dein Server. Heute.

Kostenloser Plan, keine Karte. Gehostet in der EU, oder auf deinen eigenen Maschinen.