Schemat i kod. Innehållet över HTTP.

Definiera collections i TypeScript, redigera dem i adminen, läs dem via REST, GraphQL eller Astro-loadern. Driftat i EU, eller på dina egna servrar.

Osprey-adminen som redigerar en publicerad sida på plats: den skarpa sidan i mitten med fjorton markerade redigerbara fält, fältlistan till vänster, språkväljaren och knappen Publicera i verktygsfältet. Osprey-adminen som redigerar en publicerad sida på plats: den skarpa sidan i mitten med fjorton markerade redigerbara fält, fältlistan till vänster, språkväljaren och knappen Publicera i verktygsfältet.
Adminen, mitt i redigeringen av en skarp sida. En skärmdump, ingen mockup. Adminen finns på engelska och italienska, så de här bilderna är den engelska uppsättningen.

Fyra saker du kan kontrollera.

  • Schemat Fjorton fälttyper Text, textarea, rich text, tal, boolean, datum och tid, slug, select, relation, media, grupp, array, JSON, block. Alla exporterade av core-paketet.
  • Den publika läsningen Utan nyckel, 404 som standard En collection kan läsas utan nyckel bara när dess åtkomstregel släpper in en anonym anropare. Allt annat svarar 404, aldrig 403.
  • Språken Tio innehållsspråk Lokaliserade fält, en täckningsmatris per sida och språk, och luckorna som CSV.
  • Nycklarna Hashade, visade en gång API-nycklar lagras som HMAC-hash med pepper. Du ser nyckeln när den skapas; adminen behåller de sista fyra tecknen.
Varje funktion, i detalj →

Från en TypeScript-fil till en sida på webben.

Skrolla. Samma innehåll, vid vart och ett av sina fyra stopp.

  1. 01 · Schema

    Du definierar collectionen i TypeScript.

    Slug, fält, åtkomstregler. Den bor i ditt repo och går genom granskning som all annan kod.

    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

    Adminen läser schemat och ritar formuläret.

    Obligatoriska fält, språkväljaren, brödtexten i rich text. Inget ställs in två gånger.

  3. 03 · API

    Publicerade poster kommer ut som JSON.

    En GET, utan nyckel, med SEO, canonical och hreflang redan sammanslagna i varje post.

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

    Din frontend renderar dem.

    Astro-loadern hämtar posterna vid bygget. Bloggen nedan är byggd precis så, från det här CMS:et.

    Öppna den skarpa bloggen →
    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',
      }),
    })

Adminen, i ditt tema och ditt språk.

Ljust eller mörkt, engelska eller italienska. Varje bild på den här sajten följer temat du väljer i sidhuvudet: det är samma admin, fotograferad två gånger.

Ditt innehåll. Din server. I dag.

Gratisplan, inget kort. Driftat i EU, eller på dina egna maskiner.