Skip to content

@conloca/content-api

@conloca/content-api is the core content engine for Conloca CMS. It reads and writes VXJSON content files, maintains an in-memory index for fast lookups, handles optimistic concurrency via etags, and provides the FileSystemContentAPI class that all other packages depend on.

Overview

@conloca/content-api is the core engine powering Conloca CMS. It handles file-based content storage in VXJSON format, asset management, and provides Cloudflare Access validation helpers for Node.js integrations.

Most developers interact with this package indirectly through @conloca/astro-cms. Direct installation is needed when:

  • Importing auth providers for CMS configuration
  • Using the content API programmatically (scripts, tests, CI)
  • Building custom tooling around Conloca content

Installation

bun add @conloca/content-api

Entry Points

@conloca/content-api (browser-safe)

Types and interfaces safe for browser environments. No Node.js dependencies.

import type { ContentAPI, ContentEntry, ContentManifest } from '@conloca/content-api';
import { Blocks, Site, ErrorCodes } from '@conloca/content-api';
ExportKindPurpose
ContentAPItypeMain API interface for content operations
ContentEntrytypeFull content entry with all locales
ContentManifesttypeManifest entry (metadata without content body)
LocalizedEntrytypeSingle-locale content entry
SitesConfigtypeMulti-site configuration
BlocksclassBlock collection operations*
SiteclassSite-scoped content operations*
ErrorCodesconstStandard error codes (CONTENT_NOT_FOUND, STALE_WRITE, etc.)
ContentUtilsconstContent utility functions (object with pure helper methods)
AssetEntrytypeAsset metadata entry
FolderListingtypeFolder contents listing
FolderTreeNodetypeFolder tree structure

* Blocks and Site are exported from the browser-safe entry point for type-level use only (e.g., parameter and return types). Runtime instantiation of these classes requires the Node.js entry point (@conloca/content-api/node).

@conloca/content-api/node (Node.js only)

Node.js-specific implementations requiring filesystem access.

import {
  FileSystemContentAPI,
  InMemoryContentAPI,
  createContentAPIRouter,
  createContentMiddleware,
  createContentAPI,
  createContentWatchHandlers,
  ComponentRegistry,
  AssetManifest,
  AssetOperations,
  conlocaContent,
} from '@conloca/content-api/node';

Authentication Helpers

ExportPurpose
validateCFAccessRequest(request)Validate a Cloudflare Access JWT from the incoming request
extractCFAccessToken(request)Read the CF Access token from request headers or cookies
CFAccessResultResult type returned by validateCFAccessRequest()
CFAccessUserUser shape extracted from a validated Cloudflare Access token

Content API Implementations

ExportPurpose
FileSystemContentAPIProduction implementation backed by filesystem + VXJSON
InMemoryContentAPIIn-memory implementation for testing
createContentAPIRouter(api)Create Hono router with all content middleware routes
createContentMiddleware(api)Create content middleware for custom Hono apps
createContentAPI(options)Factory function that creates FileSystemContentAPI with content watcher
createContentWatchHandlers(api)File watcher for live content updates

Other Node.js Exports

ExportPurpose
ComponentRegistryComponent registration for Puck config
AssetManifestAsset manifest management
AssetOperationsAsset CRUD operations
conlocaContent(options)Vite plugin for content integration

@conloca/content-api/schemas

Zod schemas for content metadata validation.

import { pageMetaSchema, blockMetaSchema, pageEditableSchema, blockEditableSchema } from '@conloca/content-api/schemas';
ExportPurpose
pageMetaSchemaFull page metadata schema (with system fields)
pageEditableSchemaEditable page fields only (for CMS forms)
blockMetaSchemaFull block metadata schema (with system fields)
blockEditableSchemaEditable block fields only (for CMS forms)
dataMetaSchemaFull data entry metadata schema (with system fields)
dataEditableSchemaEditable data entry fields only (for CMS forms)

Current Authentication Support

Today, @conloca/content-api exposes low-level Cloudflare Access helpers only. In the standard Astro integration, you normally do not call these functions yourself. Instead, @conloca/astro-cms uses them automatically when these environment variables are present:

VariableDescription
CF_ACCESS_TEAM_NAMEZero Trust team name, used to resolve the JWKS URL
CF_ACCESS_AUDAccess application audience (aud) to validate JWT

When these variables are missing, validation is skipped so local development can run without Cloudflare Access.

Dev Branch Preview

The dev branch currently adds a fuller auth surface to @conloca/content-api/node, including:

ExportPurpose
apiKey()Bearer-token API key authentication
oauth()GitHub or Google OAuth with signed session cookies
noAuth()Explicit development-mode provider
AuthConfigprovider, roles, and resolveRole configuration
AuthProviderShared provider interface with validate() and optional logout

Treat that API as preview material until it lands on the branch you are deploying from.

Examples

Programmatic Content Access

import { createContentAPI } from '@conloca/content-api/node';

const api = await createContentAPI({ contentRoot: './content' });

// List pages for a site (listPages is a generator)
const pages = Array.from(api.getSite('default')!.listPages('en'));

// Get a specific block (synchronous)
const block = api.blocks.getByName('shared', 'header', 'en');

Testing with InMemoryContentAPI

import { InMemoryContentAPI, createContentAPIRouter } from '@conloca/content-api/node';

const api = new InMemoryContentAPI({
  sites: { default: { locales: ['en', 'de'], defaultLocale: 'en' } },
  globalLocales: ['en', 'de'],
});

const router = createContentAPIRouter(api);
const response = await router.fetch(new Request('http://test/default/pages'));