Lo schema nel codice. Il contenuto via HTTP.

Definisci le collection in TypeScript, le modifichi nell'admin, le leggi via REST, GraphQL o il loader Astro. Ospitato nell'UE, o sui tuoi server.

L'admin di Osprey mentre modifica una pagina pubblicata sul posto: la pagina live al centro con quattordici campi modificabili evidenziati, l'elenco dei campi a sinistra, il selettore di lingua e il pulsante Pubblica nella barra. L'admin di Osprey mentre modifica una pagina pubblicata sul posto: la pagina live al centro con quattordici campi modificabili evidenziati, l'elenco dei campi a sinistra, il selettore di lingua e il pulsante Pubblica nella barra.
L'admin, mentre modifica una pagina live. Uno screenshot, non un mockup.

Quattro cose che puoi verificare.

  • Lo schema Quattordici tipi di campo Testo, textarea, rich text, numero, booleano, data e ora, slug, select, relazione, media, gruppo, array, JSON, blocchi. Tutti esportati dal package core.
  • La lettura pubblica Senza chiave, 404 di default Una collection si legge senza chiave solo se la sua regola di accesso ammette un chiamante anonimo. Tutto il resto risponde 404, mai 403.
  • Le lingue Dieci lingue di contenuto Campi localizzati, una matrice di copertura per pagina e lingua, e i buchi in un CSV.
  • Le chiavi Hash, mostrate una volta Le chiavi API sono salvate come hash HMAC con pepper. La vedi alla creazione; l'admin conserva le ultime quattro cifre.
Ogni funzione, nel dettaglio →

Da un file TypeScript a una pagina sul web.

Scorri. Lo stesso contenuto, in ciascuna delle sue quattro tappe.

  1. 01 · Schema

    Definisci la collection in TypeScript.

    Slug, campi, regole di accesso. Vive nel tuo repository e passa dalla review come qualsiasi altro codice.

    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

    L'admin legge lo schema e disegna il form.

    Campi obbligatori, selettore di lingua, corpo in rich text. Niente si configura due volte.

  3. 03 · API

    Le voci pubblicate escono in JSON.

    Una GET, senza chiave, con SEO, canonical e hreflang già uniti in ogni voce.

    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 · Sito

    Il tuo frontend le renderizza.

    Il loader Astro scarica le voci al build. Il blog qui sotto è costruito esattamente così, da questo CMS.

    Apri il blog live →
    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',
      }),
    })

L'admin, nel tuo tema e nella tua lingua.

Chiaro o scuro, inglese o italiano. Ogni cattura di questo sito segue il tema che scegli nell'intestazione: è lo stesso admin, fotografato due volte.

Il tuo contenuto. Il tuo server. Oggi.

Piano gratuito, senza carta. Ospitato nell'UE, o sulle tue macchine.