Skip to content

@trokky/studio

@trokky/studio is the React-based admin interface for Trokky. It provides a complete content management UI with document editing, media library, and customization options.

Terminal window
npm install @trokky/studio

Studio is automatically served when enabled in configuration:

import { TrokkyExpress } from '@trokky/express';
const trokky = await TrokkyExpress.create({
schemas,
storage: { /* ... */ },
studio: {
enabled: true,
},
});
trokky.mount(app);
// Studio available at /studio
  • Auto-generated forms from schemas
  • Rich text editing
  • Media field integration
  • Reference browsing
  • Draft/publish workflow
  • Revision history
  • Drag-and-drop uploads
  • Image preview and variants
  • Metadata editing
  • Search and filtering
  • Bulk operations
  • Customizable sidebar
  • Document type grouping
  • Quick search
  • Breadcrumb navigation
  • Dark mode support
  • Responsive design
  • Keyboard shortcuts
  • Auto-save
  • Optimistic updates
studio: {
enabled: true,
basePath: '/studio', // URL path (default: /studio)
}
studio: {
branding: {
title: 'My CMS',
logo: '/logo.svg',
favicon: '/favicon.ico',
colors: {
primary: '#3b82f6',
},
},
}
studio: {
structure: [
{
type: 'group',
title: 'Content',
items: [
{ type: 'list', schemaType: 'post', title: 'Posts' },
{ type: 'list', schemaType: 'page', title: 'Pages' },
],
},
{ type: 'divider' },
{
type: 'singleton',
schemaType: 'siteSettings',
title: 'Settings',
},
],
}
studio: {
features: {
mediaLibrary: true,
darkMode: true,
search: true,
revisionHistory: true,
},
}

Display documents of a schema type:

{
type: 'list',
schemaType: 'post',
title: 'Blog Posts',
icon: 'document',
filter: { status: 'published' },
defaultOrdering: { field: '_createdAt', direction: 'desc' },
}

Single document type (settings, etc.):

{
type: 'singleton',
schemaType: 'siteSettings',
title: 'Site Settings',
icon: 'cog',
}

Collapsible group of items:

{
type: 'group',
title: 'Blog',
icon: 'folder',
items: [
{ type: 'list', schemaType: 'post' },
{ type: 'list', schemaType: 'category' },
],
}

Visual separator:

{
type: 'divider',
}

External or custom link:

{
type: 'link',
title: 'View Site',
url: 'https://example.com',
icon: 'external',
}

For development with hot reload:

Terminal window
# In your project
npm run studio:dev

This starts Vite dev server on port 5173.

Configure CORS for development:

server: {
cors: {
origin: 'http://localhost:5173',
credentials: true,
},
}
Terminal window
npm run studio:build

Outputs optimized static files to studio-build/ directory.

studio: {
branding: {
customCss: `
.studio-sidebar {
background: linear-gradient(180deg, #1a1a2e, #16213e);
}
.studio-header {
border-bottom: 2px solid #3b82f6;
}
`,
},
}

Add custom actions to documents:

studio: {
documentActions: [
{
label: 'Publish',
icon: 'check',
action: async (doc, { client }) => {
await client.documents.update(doc._type, doc._id, {
status: 'published',
publishedAt: new Date().toISOString(),
});
},
visible: (doc) => doc.status === 'draft',
},
],
}

Dashboard widgets:

studio: {
dashboard: {
widgets: [
{
type: 'recentDocuments',
title: 'Recent Posts',
schemaType: 'post',
limit: 5,
},
{
type: 'documentCount',
schemaTypes: ['post', 'page'],
},
],
},
}

Organize fields in the editor:

// In schema definition
{
name: 'post',
groups: [
{ name: 'content', title: 'Content' },
{ name: 'meta', title: 'Metadata', collapsed: true },
],
fields: [
{ name: 'title', type: 'string', group: 'content' },
{ name: 'publishedAt', type: 'datetime', group: 'meta' },
],
}

Show/hide fields dynamically:

{
name: 'externalUrl',
type: 'string',
hidden: ({ document }) => document.linkType !== 'external',
}
{
name: 'slug',
type: 'slug',
description: 'URL-friendly identifier. Auto-generated from title.',
}
studio: {
preview: {
enabled: true,
url: (doc) => `https://preview.example.com/${doc._type}/${doc.slug}`,
},
}

Show live preview alongside editor:

studio: {
preview: {
position: 'right',
width: '50%',
refreshOnChange: true,
},
}
studio: {
access: {
schemas: {
siteSettings: ['admin'],
post: ['admin', 'editor', 'writer'],
},
},
}
studio: {
features: {
bulkActions: ['admin', 'editor'],
revisionHistory: ['admin'],
},
}
ShortcutAction
Cmd/Ctrl + SSave document
Cmd/Ctrl + KOpen search
Cmd/Ctrl + /Toggle sidebar
EscapeClose modal/panel
  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Enable debug mode:

studio: {
debug: {
showFieldNames: true,
logApiCalls: true,
},
}

Browser console commands:

// Set log level
window.TrokkyLogger.setLevel('debug');
// Get current config
window.TROKKY_CONFIG;