Schema în cod. Conținutul prin HTTP.

Definești colecțiile în TypeScript, le editezi în admin, le citești prin REST, GraphQL sau loaderul Astro. Găzduit în UE, sau pe propriile tale servere.

Adminul Osprey editând o pagină publicată chiar pe loc: pagina live în centru cu paisprezece câmpuri editabile conturate, lista câmpurilor în stânga, selectorul de limbă și butonul Publică în bară. Adminul Osprey editând o pagină publicată chiar pe loc: pagina live în centru cu paisprezece câmpuri editabile conturate, lista câmpurilor în stânga, selectorul de limbă și butonul Publică în bară.
Adminul, în timp ce editează o pagină live. O captură, nu un mockup. Adminul există în engleză și italiană, așa că aceste capturi sunt setul englez.

Patru lucruri pe care le poți verifica.

  • Schema Paisprezece tipuri de câmp Text, textarea, rich text, număr, boolean, dată și oră, slug, select, relație, media, grup, array, JSON, blocuri. Toate exportate de pachetul core.
  • Citirea publică Fără cheie, 404 implicit O colecție se citește fără cheie doar când regula ei de acces admite un apelant anonim. Orice altceva răspunde 404, niciodată 403.
  • Limbile Zece limbi de conținut Câmpuri localizate, o matrice de acoperire pe pagină și limbă, iar lipsurile într-un CSV.
  • Cheile Hash, arătate o singură dată Cheile API sunt stocate ca hash HMAC cu pepper. Vezi cheia la creare; adminul păstrează ultimele patru caractere.
Fiecare funcție, în detaliu →

De la un fișier TypeScript la o pagină pe web.

Derulează. Același conținut, la fiecare dintre cele patru opriri ale lui.

  1. 01 · Schemă

    Definești colecția în TypeScript.

    Slug, câmpuri, reguli de acces. Trăiește în repository-ul tău și trece prin review ca orice alt cod.

    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

    Adminul citește schema și desenează formularul.

    Câmpuri obligatorii, selectorul de limbă, corpul în rich text. Nimic nu se configurează de două ori.

  3. 03 · API

    Intrările publicate ies ca JSON.

    Un GET, fără cheie, cu SEO, canonical și hreflang deja îmbinate în fiecare intrare.

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

    Frontend-ul tău le randează.

    Loaderul Astro ia intrările la build. Blogul de mai jos e construit exact așa, din acest CMS.

    Deschide blogul 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',
      }),
    })

Adminul, în tema ta și în limba ta.

Luminos sau întunecat, engleză sau italiană. Fiecare captură de pe acest site urmează tema pe care o alegi în antet: este același admin, fotografiat de două ori.

Conținutul tău. Serverul tău. Azi.

Plan gratuit, fără card. Găzduit în UE, sau pe propriile tale mașini.