Content JSON
Blobify writes content as JSON documents in your bucket.
Each entry can have:
- one mutable
draft.json - one
published.jsonsnapshot containing the currently published locales
Draft document
Draft content is used by the dashboard and editors.
jsoncode
{
"id": "art_123",
"model": "article",
"created": "2026-03-01T10:00:00.000Z",
"publishedLocales": ["en"],
"published": {
"en": "2026-03-02T09:00:00.000Z"
},
"firstPublished": "2026-03-02T09:00:00.000Z",
"lastPublished": "2026-03-02T09:00:00.000Z",
"fields": {
"title": { "en": "Hello world" },
"slug": "hello-world",
"excerpt": { "en": "Short summary" },
"coverImage": { "type": "asset", "assetId": "img_456" },
"author": { "type": "reference", "id": "author_1", "model": "author" }
}
}Published document
Published content is what your website or app reads.
It keeps only the locales that have actually been published.
jsoncode
{
"id": "art_123",
"model": "article",
"created": "2026-03-01T10:00:00.000Z",
"publishedLocales": ["en"],
"published": {
"en": "2026-03-02T09:00:00.000Z"
},
"firstPublished": "2026-03-02T09:00:00.000Z",
"lastPublished": "2026-03-02T09:00:00.000Z",
"fields": {
"title": { "en": "Hello world" },
"slug": "hello-world",
"excerpt": { "en": "Short summary" },
"coverImage": { "type": "asset", "assetId": "img_456" }
}
}Localized fields
Localized fields are stored as locale maps:
jsoncode
{
"title": {
"en": "Welcome",
"is": "Velkomin"
}
}Non-localized fields are stored once:
jsoncode
{
"slug": "welcome"
}References
Content references are stored as semantic references, not fully expanded documents:
jsoncode
{
"author": {
"type": "reference",
"id": "author_1",
"model": "author"
}
}Asset fields follow the same idea:
jsoncode
{
"coverImage": {
"type": "asset",
"assetId": "img_456"
}
}Clients resolve these through summaries or asset metadata when rendering.
Rich text shape
Rich text is stored as an AST.
jsoncode
{
"content": {
"en": {
"type": "root",
"children": [
{
"type": "paragraph",
"children": [
{ "type": "text", "value": "Hello world" }
]
},
{
"type": "contentRef",
"ref": {
"type": "reference",
"id": "art_999",
"model": "article"
},
"children": [{ "type": "text", "value": "Read next" }]
}
]
}
}
}Embedded blocks live inside the AST as block nodes:
jsoncode
{
"type": "block",
"block": {
"type": "callout-block",
"id": "blk_1",
"heading": { "en": "Important" },
"body": { "en": "This is a callout." }
}
}Why this shape matters
This keeps Blobify predictable:
- the dashboard edits one draft document
- websites read one published document
- references stay stable even if URLs change
- generated clients can resolve content consistently