Wszystko, co robi, na jednej stronie.
Sprawdzone w kodzie, który to uruchamia, 2 września 2026. Nic tutaj nie jest planowane ani „wkrótce”.
Panel istnieje po angielsku i włosku, więc te zrzuty to zestaw angielski.
Schemat to formularz.
To, co piszesz po lewej, redaktorzy dostają po prawej.
fields.text()fields.textarea()fields.richText()fields.number()fields.boolean()fields.datetime()fields.slug()fields.select()fields.relation()fields.media()fields.group()fields.array()fields.json()fields.blocks()
- Flagi, nie ekrany
- required i localized to dwa booleany na polu.
- Slug z tytułu
- fields.slug({ from: 'title' }) wypełnia się sam; select niesie stałe opcje.
- Także z panelu
- Własne kolekcje tworzysz w panelu, a zapisują się w bazie danych.
Jedna treść, cztery sposoby czytania.
Wybierz ten, którym twój stack już mówi.
Publiczne wpisy nie wymagają klucza. Dokumenty back-office wymagają klucza API albo tokenu bearer.
curl 'https://cms.altovar.net/api/v1/collections/blog-post/entries?locale=en'
{ "data": [ { "id": "fdoc_16d9i3ef", "locale": "en",
"data": { "title": "EU-first content infrastructure", … },
"seo": { "metaTitle": …, "metaDescription": …, "robots": "index,follow" } } ],
"pagination": { "page": 1, "limit": 20, "total": 3, "totalPages": 1 } }
# The back-office route is the same shape, with a key:
curl -H 'x-api-key: sk_…' \
'https://cms.altovar.net/api/v1/collections/blog-post/documents?limit=10' Typowany klient z tą samą kopertą: data i pagination.
import { OspreyClient } from '@osprey/client'
const osprey = new OspreyClient({
baseUrl: 'https://cms.altovar.net',
tenantId: 'altovar',
})
const { data, pagination } = await osprey
.collection('blog-post')
.listEntries({ locale: 'en', limit: 10 }) Tylko zapytania, przez POST. GraphiQL dostępny w środowisku deweloperskim.
POST /api/v1/graphql
x-api-key: sk_…
query Posts($limit: Int) {
documents(collectionSlug: "blog-post", status: "published", limit: $limit) {
data { id status data }
pagination { total }
}
} Wpisy trafiają do content collections Astro podczas builda. Żadnego klucza na edge.
---
import { getCollection } from 'astro:content'
const posts = (await getCollection('blog'))
.filter((p) => p.data.locale === 'en')
.sort((a, b) => b.data.publishedAt.localeCompare(a.data.publishedAt))
---
{posts.map((p) => (
<article>
<a href={'/' + p.data.slug}>{p.data.title}</a>
<p>{p.data.excerpt}</p>
</article>
))} Publikujesz tu, pojawia się tam.
Szkice zostają prywatne. Opublikowany wpis dociera do publicznego endpointu w ciągu minuty, a webhook może przebudować stronę.
- Trzy statusy
- draft, published, archived. Strony dodają recenzję, akceptację i harmonogram.
- Podpisany webhook
- HMAC-SHA256 z treści w x-osprey-signature. Dziewięć zdarzeń, sekret zaszyfrowany w spoczynku.
- Nagłówki cache
- Publiczne odczyty niosą max-age=60 ze stale-while-revalidate, gotowe na dowolny cache z przodu.
Dziesięć języków, jedna macierz.
Każde lokalizowane pole, każdy język, policzone.
- Języki treści
- en, it, es, de, fr, nl, pl, sv, pt, ro, ustawiane per workspace.
- Panel
- Angielski i włoski, przełączane z górnego paska.
- Pokrycie
- Macierz dla każdej strony i języka, a brakujące teksty w pliku CSV.
- Dostarczanie
- Jeden parametr zapytania wybiera język; alternatywy hreflang podróżują z każdym wpisem.
Twoja domena, w czterech krokach.
Dziś przez API. Strona ustawień jest w drodze, i ta strona to mówi.
- Zgłoś Wyślij POST z hostem do endpointu domen. Czeka jako oczekująca.
- Udowodnij Dodaj rekord TXT _osprey-verify.<host> z otrzymanym tokenem.
- Zweryfikuj Wyślij POST ponownie z verify: true. Host przechodzi do workspace.
- Skieruj CNAME na platformę. Certyfikat jest wydawany przy pierwszym żądaniu.
POST /api/v1/admin/domains
Authorization: Bearer <jwt>
{ "host": "www.example.com" }
{ "status": "pending",
"verification": { "type": "TXT",
"name": "_osprey-verify.www.example.com",
"value": "osprey-verify=…" } } Własne domeny zależą od planu albo od dodatku hostingowego.
Kontrola, która pokazuje swoją pracę.
Każda linia poniżej to trasa i ekran, nie roadmapa.
- Role
- admin, editor, author, contributor, viewer
- Klucze API
- hashowane, pokazane raz, flaga tylko do odczytu, wygaśnięcie
- Dziennik audytu
- kto, co, kiedy i skąd, przy każdej zmianie stanu
- Rewizje
- historia stron z diffem i przywracaniem
- Kosz
- usunięte strony czekają; przywracasz je albo usuwasz na dobre
- Razem
- obecność i wspólna edycja stron, pole po polu
- Zgoda
- baner cookie i dziennik zgód z hashowanym IP
- Usunięcie i eksport
- jedno wywołanie anonimizuje osobę; eksport z panelu albo z CLI
- Logowanie
- OpenID Connect per workspace, albo lokalne hasło
- Limity żądań
- jeden kubełek na rodzinę tras, limity w nagłówkach odpowiedzi
Elementy dookoła.
Dwa opublikowane pakiety, CLI, serwer MCP i stack do self-hostingu.
- @osprey/client
- typowane SDK, renderer bloków React, menedżer zgód
- @osprey/astro
- loader treści, head SEO, synchronizacja tłumaczeń
- CLI
- setup, init, dev, build, generate-types, link, export
- Serwer MCP
- szesnaście narzędzi przez stdio, dla agenta AI, którego już używasz
- Self-host
- jeden plik compose i kreator pierwszego uruchomienia pod /setup
- Asystent AI
- tłumaczy braki, uzupełnia SEO, pisze alt; wyłączony, dopóki go nie włączysz
Twoja treść. Twój serwer. Dziś.
Darmowy plan, bez karty. Hostowany w UE, albo na twoich własnych maszynach.