@pixelacker/editable
v0.1.0
Published
Framework-agnostic client for the Pixelacker content API
Readme
@pixelacker/editable
Framework-agnostic client for the Pixelacker content API. Connects frontend applications to the pixelacker-backend content management system.
Installation
npm install @pixelacker/editablePublished to GitHub Packages. Requires
.npmrcwith@pixelacker:registry=https://npm.pkg.github.com
Quick Start
Core Client
import { createEditableClient } from '@pixelacker/editable';
const client = createEditableClient({
apiUrl: 'https://api.example.com',
tenantKey: 'your-tenant-api-key',
});
// Fetch all content
const all = await client.getAll();
// Fetch a group (one API call)
const home = await client.getGroup('home');
console.log(home.hero_title);
// Fetch a single value
const title = await client.get('home.hero_title', 'Default Title');React / Next.js
import { EditableProvider, useEditable, useEditableGroup } from '@pixelacker/editable/react';
function App() {
return (
<EditableProvider
apiUrl={process.env.NEXT_PUBLIC_PIXELACKER_API!}
tenantKey={process.env.NEXT_PUBLIC_PIXELACKER_KEY!}
>
<HomePage />
</EditableProvider>
);
}
function Hero() {
const title = useEditable('home.hero_title', 'Default Title');
const image = useEditable('home.hero_image', '/placeholder.jpg');
return (
<section>
<h1>{title}</h1>
<img src={image} alt="" />
</section>
);
}
function HomePage() {
const content = useEditableGroup('home');
return <h1>{content.hero_title}</h1>;
}Server Components (Next.js App Router)
import { getEditable, getEditableGroup } from '@pixelacker/editable/react/server';
export default async function Page() {
const content = await getEditableGroup('home');
return <h1>{content.hero_title}</h1>;
}Configuration
createEditableClient(config)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| apiUrl | string | required | Backend API base URL |
| tenantKey | string | required | Tenant API key |
| cache | boolean | true | Enable in-memory cache |
| cacheTTL | number | 300 | Cache TTL in seconds |
| fallbackToDefaults | boolean | true | Use editable.json defaults when API is unreachable |
| manifestPath | string | './editable.json' | Path to editable.json for fallback defaults |
API Reference
Core Client
client.getAll()- Fetch all content asRecord<string, string>client.getGroup(group)- Fetch content for a group (keys stripped of prefix)client.get(key, defaultValue?)- Fetch a single valueclient.syncManifest(path)- Sync editable.json to the backendclient.clearCache()- Clear the in-memory cache
React Hooks
<EditableProvider>- Context provider, initializes the clientuseEditable(key, defaultValue)- Fetch a single value (returns default immediately)useEditableGroup(group)- Fetch all fields in a groupuseEditableClient()- Access the client instance directly
Server Functions
getEditable(key, defaultValue?, config?)- Fetch a single valuegetEditableGroup(group, config?)- Fetch a groupgetEditableAll(config?)- Fetch all content
editable.json
Define your content fields in editable.json:
{
"$schema": "./node_modules/@pixelacker/editable/editable.schema.json",
"fields": [
{
"key": "home.hero_title",
"type": "text",
"default": "Welcome to Our Company",
"label": "Hero Title"
},
{
"key": "home.hero_image",
"type": "image",
"default": "/images/placeholder-hero.jpg",
"label": "Hero Background Image"
}
]
}Field Types
| Type | Description |
|------|-------------|
| text | Single-line text |
| textarea | Multi-line text |
| richtext | HTML content |
| image | Image URL |
| link | URL |
Key Format
Keys follow the group.field_name pattern: lowercase letters, numbers,
and underscores only. The group prefix is stripped in group-level fetches.
CLI
# Sync manifest to backend
npx pixelacker-editable sync
# With explicit options
npx pixelacker-editable sync --manifest ./editable.json --api-url https://api.example.com --tenant-key abc123
# Validate manifest without syncing
npx pixelacker-editable validate
# Generate TypeScript types from manifest
npx pixelacker-editable types --output ./src/editable.d.tsConfiguration Sources (priority order)
- CLI flags (
--api-url,--tenant-key,--manifest) - Environment variables (
PIXELACKER_API_URL,PIXELACKER_TENANT_KEY) .pixelackerrcfile:
{
"apiUrl": "https://api.example.com",
"tenantKey": "abc123",
"manifestPath": "./editable.json"
}Type Generation
Running npx pixelacker-editable types generates a .d.ts file with
EditableContent and EditableGroups interfaces for full IDE autocomplete.
Error Handling
The client throws typed errors:
AuthenticationError- Invalid or missing API key (401/403)RateLimitError- Rate limit exceeded (429)ValidationError- Invalid request data (422)NotFoundError- Content or group not found (404)NetworkError- Connection failureManifestError- Invalid editable.json
When fallbackToDefaults is enabled (default), NetworkError is caught
silently and defaults from editable.json are returned instead. The site
never breaks because the API is down.
License
UNLICENSED - Private package.
