### Install datocms-react-ui and datocms-plugin-sdk
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Install the necessary packages using npm.
```bash
npm install datocms-react-ui datocms-plugin-sdk
```
--------------------------------
### Install datocms-plugin-sdk with npm
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/README.md
Use this command to install the DatoCMS Plugin SDK using npm.
```sh
npm install datocms-plugin-sdk
```
--------------------------------
### Install datocms-plugin-sdk with yarn
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/README.md
Use this command to install the DatoCMS Plugin SDK using yarn.
```sh
yarn add datocms-plugin-sdk
```
--------------------------------
### Component Documentation with JSDoc Example
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
Components use JSDoc with the `@example` tag to provide interactive examples. These examples reference `Canvas` and `Section` components for demonstrating usage within a DatoCMS plugin context.
```typescript
/**
* @example Button types
*
* ```js
*
* ```
*/
```
--------------------------------
### CMS Example of Context-Merged Invocation
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
An example from the CMS perspective demonstrating how to call `callMethodMergingBootCtx` with regular arguments, additional context properties, and methods to proxy.
```typescript
// In CMS code
const result = await pluginConnection.callMethodMergingBootCtx(
'executeFieldDropdownAction',
['my-action-id'], // Regular arguments
{
// Additional context properties
field: currentField,
actionId: 'my-action-id',
},
['setFieldValue', 'scrollToField'], // Additional methods to proxy
'call-123', // Unique call ID for method proxying
);
```
--------------------------------
### Build Command Example
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
This command initiates the build process for the DatoCMS SDK, involving manifest generation and TypeScript compilation for CommonJS and ESM formats.
```bash
npm run build
# Runs: generateManifest.ts → tsc (CJS) → tsc (ESM)
```
--------------------------------
### Example: Render Asset Browser UI
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
An example of implementing the renderAssetSource hook to display an 'AssetBrowser' component. This snippet shows how to use the provided context to create an upload after a user selects an asset.
```typescript
connect({
renderAssetSource(id, ctx) {
ReactDOM.render(
{
const file = await fetch(url).then(r => r.blob());
await ctx.createUpload(file);
}}
/>,
document.getElementById('root')
);
}
});
```
--------------------------------
### DropdownActionGroup Usage Example
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Demonstrates how to create a DropdownActionGroup object. This example shows a 'Publishing' group with two actions: 'Publish Now' and 'Schedule Publishing'.
```typescript
const group: DropdownActionGroup = {
label: 'Publishing',
icon: 'share',
rank: 50,
actions: [
{
id: 'publish',
label: 'Publish Now',
icon: 'paper-plane',
parameters: {}
},
{
id: 'schedule',
label: 'Schedule Publishing',
icon: 'calendar',
parameters: {}
}
]
};
```
--------------------------------
### Complete connect Configuration with All Hooks
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
This example shows a complete configuration of the connect function, including all available hooks for comprehensive plugin development. It demonstrates initialization, configuration screen rendering, field extension, modal rendering, and dropdown actions.
```typescript
// Minimal configuration with only required hooks
connect({
renderConfigScreen(ctx) {
ctx.notice('Configuration screen loaded');
}
});
// Complete configuration with all hooks
connect({
onBoot(ctx) {
// Initialization
},
renderConfigScreen(ctx) {
// Config UI
},
renderFieldExtension(id, ctx) {
// Field rendering
},
renderModal(id, ctx) {
// Modal rendering
},
fieldDropdownActions() {
// Return dropdown actions
},
// ... all other hooks
});
```
--------------------------------
### DropdownAction Usage Example
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Demonstrates how to create a DropdownAction object. Ensure all required properties like 'id', 'label', and 'icon' are provided.
```typescript
const action: DropdownAction = {
id: 'delete-draft',
label: 'Delete Draft',
icon: 'trash',
parameters: { confirm: true },
disabled: false,
alert: true,
rank: 100,
closeMenuOnClick: true
};
```
--------------------------------
### Sidebar Panel Usage Example
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Demonstrates how to define a custom sidebar panel with its ID, label, and placement configuration.
```typescript
export type ItemFormSidebarPanel = {
id: string;
label: string;
placement: ItemFormSidebarPanelPlacement;
};
const panel: ItemFormSidebarPanel = {
id: 'custom-info',
label: 'Custom Information',
placement: ['after', 'info']
};
```
--------------------------------
### Building a Plugin Configuration Screen
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Provides an example of a React-based configuration screen for a DatoCMS plugin. It shows how to manage state for API key input and update plugin parameters using context methods.
```typescript
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { Canvas, TextField, Button, Section } from 'datocms-react-ui';
function ConfigScreen({ ctx }) {
const params = ctx.plugin.parameters || {};
const [apiKey, setApiKey] = useState(params.apiKey || '');
const [saving, setSaving] = useState(false);
const handleSave = async () => {
setSaving(true);
try {
await ctx.updatePluginParameters({ apiKey });
await ctx.notice('Saved!');
} finally {
setSaving(false);
}
};
return (
);
}
connect({
renderConfigScreen(ctx) {
ReactDOM.render(
,
document.getElementById('root')
);
}
});
```
--------------------------------
### PostCSS Configuration Example
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
The PostCSS configuration defines different modes for the build pipeline, such as 'prebuild' for generating CSS module mappings and 'production' for the full styling pipeline.
```javascript
// packages/react-ui/postcss.config.js
// ...
// 'prebuild' mode: Only runs postcss-modules to generate JSON mappings
// 'production' mode: Runs full pipeline (import, calc, nested, cssnano)
// ...
```
--------------------------------
### Custom SVG Icon Example
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Shows how to define a custom icon using an SVG object, including its viewBox and children path data.
```typescript
const icon: Icon = {
type: 'svg',
viewBox: '0 0 24 24',
children: ''
};
```
--------------------------------
### Example: Register Unsplash Asset Source
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
An example of implementing the assetSources hook to register a custom asset source named 'Unsplash'. This snippet shows how to define the source's ID, name, and description.
```typescript
connect({
assetSources(ctx) {
return [
{
id: 'unsplash',
name: 'Unsplash',
description: 'Browse free stock photos'
}
];
}
});
```
--------------------------------
### Guard Usage Pattern for Plugin Configuration
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Example demonstrating how to use guard functions to validate plugin configuration parameters, specifically checking if 'actions' is a valid array of dropdown actions or groups.
```typescript
function myHook(ctx: Ctx): Array {
const config = ctx.plugin.parameters;
if (!isRecord(config)) {
return [];
}
const actions = config.actions;
if (!isDropdownActionOrGroupArray(actions)) {
return [];
}
return actions;
}
```
--------------------------------
### Custom Install-in-Place Script
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
This script facilitates rapid iteration during development by replacing the installed package's dist files in a plugin project without re-publishing to npm. Ensure the `INSTALL_PATH` environment variable is set correctly.
```bash
npm run build && rm -rf $INSTALL_PATH/node_modules/datocms-react-ui/dist && cp -rf dist styles.css types.json $INSTALL_PATH/node_modules/datocms-react-ui
```
```bash
INSTALL_PATH=/path/to/plugin-project npm run install-in-place
```
--------------------------------
### FontAwesome Icon String Example
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Illustrates using a string to represent common FontAwesome icons for actions like delete, edit, or copy.
```typescript
const icon: Icon = 'address-book';
```
```typescript
const icon: Icon = 'trash';
```
```typescript
const icon: Icon = 'pencil';
```
--------------------------------
### CSS Module Import Example
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
When using CSS modules, import styles using the `.css.json` extension. The generated JSON file contains hashed class names and should not be edited manually.
```typescript
import styles from './styles.module.css.json'
```
--------------------------------
### CSS Modules JSON Mapping Example
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
This JSON file is generated by PostCSS and maps human-readable class names to hashed, scoped class names used in the application.
```json
{
"button": "_button_474wk_1",
"disabled": "_disabled_474wk_30",
"buttonType-muted": "_buttonType-muted_474wk_34"
}
```
--------------------------------
### manualFieldExtensions Hook
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
Defines custom field editors that users can manually install on fields.
```APIDOC
## manualFieldExtensions Hook
### Description
Defines custom field editors that users can manually install on fields.
### Method
`manualFieldExtensions`
### Parameters
#### Context
- **ctx** (Ctx) - The base context object, which does not support resizing.
### Returns
- **Array** - An array of field extension definitions.
### ManualFieldExtension Object
- **id** (string) - Required - A unique identifier for the field extension.
- **name** (string) - Required - The display name of the field extension.
- **type** ('editor' | 'addon') - Required - The type of the field extension, either 'editor' or 'addon'.
- **asSidebarPanel** (boolean | { startOpen: boolean }) - Optional - Configuration for displaying the extension as a sidebar panel.
### Example
```typescript
connect({
manualFieldExtensions(ctx) {
return [
{
id: 'myEditor',
name: 'My Custom Editor',
type: 'editor',
description: 'A custom field editor'
},
{
id: 'myAddon',
name: 'My Addon',
type: 'addon',
description: 'An additional field component'
}
];
}
});
```
```
--------------------------------
### Theme Variable Transformation Example
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
Theme values from the DatoCMS plugin SDK context are transformed into CSS custom properties, allowing components to adapt to different themes dynamically.
```typescript
// Input: ctx.theme.accentColor = "rgb(255, 94, 73)"
// Output CSS:
{
'--accent-color': 'rgb(255, 94, 73)',
'--accent-color-rgb-components': '255, 94, 73'
}
```
--------------------------------
### Example Usage of Item Form Methods
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-frame-context.md
Demonstrates how to access and use item form manipulation methods within a plugin's renderFieldExtension. This includes checking form dirty state, toggling field visibility, setting field values, scrolling to fields, and converting form values to an item entity.
```typescript
import { connect } from 'datocms-plugin-sdk';
import React from 'react';
connect({
renderFieldExtension(id, ctx) {
// Access item form methods
if (ctx.isFormDirty) {
console.log('Form has unsaved changes');
}
// Toggle field visibility
ctx.toggleField('otherField', false);
// Update form state
ctx.setFieldValue('title', 'New Value');
// Scroll to a field
ctx.scrollToField('description', ctx.locale);
// Convert form values to item
const item = await ctx.formValuesToItem(ctx.formValues);
// Check blocks analysis
const { usage } = ctx.blocksAnalysis;
console.log(`Total blocks: ${usage.total}`);
}
});
```
--------------------------------
### Start Automatic Iframe Resizing
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/utilities-and-guards.md
Enables automatic height adjustment for iframes. It calls updateHeight immediately and sets up observers to monitor DOM mutations and resize events for continuous height adjustments.
```typescript
connect({
renderConfigScreen(ctx) {
ctx.startAutoResizer();
// Height now auto-adjusts
}
});
```
--------------------------------
### Initialize Plugin Structure
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Sets up the plugin's entry point and connects to the DatoCMS SDK. Imports necessary modules for connection and UI styling.
```typescript
// index.ts or main.ts
import { connect } from 'datocms-plugin-sdk';
import 'datocms-react-ui/styles.css';
connect({
renderConfigScreen(ctx) {
// Render configuration form
},
onBoot(ctx) {
// Initialize plugin
}
});
```
--------------------------------
### isDropdownActionOrGroupArray Usage Example
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/shared-types.md
Shows how to use the isDropdownActionOrGroupArray type guard to validate an array of items. The example checks if the 'items' array is a valid mix of actions and groups before proceeding.
```typescript
const items = [/* ... */];
if (isDropdownActionOrGroupArray(items)) {
// items is validated
}
```
--------------------------------
### Accessing Project and User Information on Boot
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Retrieve project details (name, environment, primary status), user information (email, permissions), and theme settings upon plugin boot.
```typescript
connect({
onBoot(ctx) {
// Project info
console.log('Project:', ctx.site.name);
console.log('Environment:', ctx.environment);
console.log('Is primary:', ctx.isEnvironmentPrimary);
// User info
console.log('User:', ctx.currentUser.email);
console.log('Permissions:', ctx.currentRole.meta.final_permissions);
// Can access user token if granted permission
if (ctx.currentUserAccessToken) {
// Make API calls as the user
}
// Theme/styling
console.log('Color scheme:', ctx.colorScheme);
console.log('Theme colors:', ctx.cssDesignTokens);
}
});
```
--------------------------------
### Example: Capitalize Item Title Before Upsert
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
An example demonstrating how to use the onBeforeItemUpsert hook to ensure the 'title' field of an item is always capitalized before it is saved. This hook modifies the item in place.
```typescript
connect({
async onBeforeItemUpsert(item, ctx) {
// Ensure title is capitalized
if (item.title) {
item.title = item.title.charAt(0).toUpperCase() + item.title.slice(1);
}
return item;
}
});
```
--------------------------------
### connect()
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
Initializes the DatoCMS plugin by establishing communication with the host frame and configuring hooks and callbacks.
```APIDOC
## connect()
### Description
Initializes the DatoCMS plugin, establishing bi-directional communication with the DatoCMS host frame and configuring all plugin hooks and lifecycle callbacks.
### Signature
```typescript
export async function connect(
rawConfiguration: Partial = {},
): Promise
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **rawConfiguration** (`Partial`) - Optional - Configuration object containing hook implementations and callbacks. Defaults to `{}`.
### FullConnectParameters Type
The `FullConnectParameters` type is a union of all available hook types, including but not limited to `AssetSourcesHook`, `BuildItemPresentationInfoHook`, `ContentAreaSidebarItemsHook`, and many others.
```
--------------------------------
### DatoCMS Plugin SDK Main Entry Point
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/README.md
The primary function to connect to the DatoCMS plugin environment is `connect()`. It requires a configuration object.
```typescript
import { connect } from 'datocms-plugin-sdk';
connect({
// Your plugin configuration here
});
```
--------------------------------
### onBoot Hook
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
Called once when the plugin loads. This hook is used for initialization tasks.
```APIDOC
## onBoot Hook
### Description
Called once when the plugin loads. Used for initialization tasks.
### Method
`onBoot`
### Parameters
#### Context
- **ctx** (ImposedSizePluginFrameCtx<'onBoot'>) - The context object for the onBoot hook, which does not support resizing.
### Example
```typescript
connect({
onBoot(ctx) {
console.log('Plugin booted for project:', ctx.site.id);
ctx.notice('Plugin initialized');
}
});
```
```
--------------------------------
### Action Hook: executeFieldDropdownAction
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Handles user interactions with field dropdown actions. This example demonstrates transforming field content when the 'transform' action is executed.
```typescript
connect({
async executeFieldDropdownAction(actionId, ctx) {
if (actionId === 'transform') {
const current = ctx.formValues[ctx.fieldPath];
await ctx.setFieldValue(ctx.fieldPath, transform(current));
}
}
});
```
--------------------------------
### connect()
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
Establishes a connection to the parent DatoCMS frame and initializes configured hooks. It handles cross-origin communication, applies color schemes, and triggers lifecycle events like onBoot.
```APIDOC
## connect()
### Description
Establishes a connection to the parent DatoCMS frame using the `penpal` library for secure cross-origin communication. It bootstraps all configured hooks, applies the current color scheme, and initializes lifecycle events such as `onBoot`.
### Method
`connect(configuration)`
### Parameters
#### configuration
- **renderConfigScreen** (function) - Optional - A function to render the plugin configuration screen.
- **onBoot** (function) - Optional - A function to perform initialization tasks when the plugin boots.
- **renderFieldExtension** (function) - Optional - A function to render a field extension.
- **renderModal** (function) - Optional - A function to render a custom modal.
### Request Example
```typescript
import { connect } from 'datocms-plugin-sdk';
connect({
renderConfigScreen(ctx) {
// Render the plugin configuration screen
ReactDOM.render(
,
document.getElementById('root')
);
},
onBoot(ctx) {
// Perform initialization tasks
console.log('Plugin booted for project:', ctx.site.id);
},
renderFieldExtension(fieldExtensionId, ctx) {
// Render a field extension
ReactDOM.render(
,
document.getElementById('root')
);
},
renderModal(id, ctx) {
// Render a custom modal
ReactDOM.render(
,
document.getElementById('root')
);
},
});
```
### Return Type
`Promise` - The function completes asynchronously after establishing the plugin connection and initializing all configured hooks.
```
--------------------------------
### Minimal connect Configuration
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
Use this minimal configuration when only the configuration screen hook is needed. It initializes the plugin with the essential `renderConfigScreen` hook.
```typescript
connect({
renderConfigScreen(ctx) {
ctx.notice('Configuration screen loaded');
}
});
```
--------------------------------
### FieldGroup for Grouping Form Fields
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Illustrates grouping related form fields using the FieldGroup component. This example nests two TextField components. Ensure 'datocms-react-ui' is imported.
```typescript
import { FieldGroup } from 'datocms-react-ui';
```
--------------------------------
### connect() Function - Plugin Entry Point
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/MANIFEST.txt
The connect() function is the main entry point for initializing a DatoCMS plugin. It handles hook registration, plugin initialization, and supports color scheme integration.
```APIDOC
## connect()
### Description
This function serves as the primary entry point for your DatoCMS plugin. It is responsible for registering all necessary hooks and initializing the plugin's environment, including support for the DatoCMS color scheme.
### Method
Function Call
### Endpoint
N/A (Client-side SDK function)
### Parameters
#### connect() Parameters
- **parameters** (FullConnectParameters) - Required - An object containing all parameters required for plugin initialization, including hook registrations and configuration.
### Request Example
```javascript
import { connect } from 'datocms-plugin-sdk';
connect({
// ... plugin configuration and hook registrations
});
```
### Response
This function does not return a value directly but initializes the plugin and its hooks.
```
--------------------------------
### Build Command
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/CLAUDE.md
Executes the full build pipeline, including cleaning the dist directory, generating CSS module JSON files, compiling TypeScript, generating TypeDoc JSON, and creating the global CSS bundle.
```bash
npm run build
```
--------------------------------
### Directly Expose Non-Render Hooks as Penpal Methods
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
Exposes non-render hooks directly as Penpal methods for CMS invocation. Filters out keys starting with 'render' to identify these hooks.
```typescript
methods: {
// Directly expose non-render hooks
...Object.entries(configuration).filter(
([key]) => !key.startsWith('render')
),
}
```
--------------------------------
### Cache Loaded Data with useState
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Improve performance by caching loaded data. This example demonstrates caching field data for an item type, avoiding repeated calls to load the same data.
```typescript
const [cachedFields, setCachedFields] = useState(null);
if (!cachedFields) {
const fields = await ctx.loadItemTypeFields(typeId);
setCachedFields(fields);
}
```
--------------------------------
### startAutoResizer
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/utilities-and-guards.md
Enables automatic height adjustment for the iframe. It calls `updateHeight` initially and sets up observers to monitor DOM changes and window resizes.
```APIDOC
## startAutoResizer
### Description
Enables automatic height adjustment when content changes. It immediately calls `updateHeight` and sets up `ResizeObserver` and `MutationObserver` to track changes.
### Method
```typescript
startAutoResizer: () => void
```
### Parameters
None
### Request Example
```typescript
connect({
renderConfigScreen(ctx) {
ctx.startAutoResizer();
// Height now auto-adjusts
}
});
```
### Response
None
```
--------------------------------
### DatoCMS Plugin SDK Connection and Configuration Screen Rendering
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/context-and-types.md
Connects to the DatoCMS SDK and defines the logic for rendering the configuration screen. It demonstrates accessing context properties like site name, user email, and color scheme, as well as using context methods to load users, display notifications, open dialogs, and update plugin parameters.
```typescript
import { connect } from 'datocms-plugin-sdk';
connect({
async renderConfigScreen(ctx) {
// Access context properties
console.log('Project:', ctx.site.name);
console.log('User:', ctx.currentUser.email);
console.log('Color scheme:', ctx.colorScheme);
// Use context methods
await ctx.loadUsers();
const allUsers = ctx.users;
// Show notifications
await ctx.notice('Configuration loaded');
// Open dialogs
const item = await ctx.createNewItem('model_id');
const uploads = await ctx.selectUpload({ multiple: true });
// Update configuration
if (ctx.currentRole.meta.final_permissions.can_edit_schema) {
await ctx.updatePluginParameters({ setting: 'value' });
}
}
});
```
--------------------------------
### Define Manual Field Extensions
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
The manualFieldExtensions hook allows you to define custom field editors and addons that users can manually install on fields. It returns an array of field extension definitions.
```typescript
export type ManualFieldExtensionsHook = {
manualFieldExtensions: (ctx: Ctx) => ManualFieldExtension[];
};
export type ManualFieldExtension = {
id: string;
name: string;
type: 'editor' | 'addon';
asSidebarPanel?: boolean | { startOpen: boolean };
// ... additional properties
};
connect({
manualFieldExtensions(ctx) {
return [
{
id: 'myEditor',
name: 'My Custom Editor',
type: 'editor',
description: 'A custom field editor'
},
{
id: 'myAddon',
name: 'My Addon',
type: 'addon',
description: 'An additional field component'
}
];
}
});
```
--------------------------------
### Lazy Load Dialogs and Fetch Data Conditionally
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Improve performance by using lazy loading for dialogs and fetching details only when necessary. This example shows fetching item details only if an item is selected.
```typescript
const item = await ctx.selectItem('model_id');
// Only fetch details if user selected something
if (item) {
const details = await fetchDetails(item.id);
}
```
--------------------------------
### File Layout for a New Component
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/react-ui/PORTING.md
Standard directory structure for a new component in react-ui, including implementation, styles, and export points.
```bash
src/MyComponent/
index.tsx // implementation, named export(s)
styles.module.css // scoped styles
```
--------------------------------
### Initialize Plugin with onBoot Hook
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/hooks-reference.md
The onBoot hook is called once when the plugin loads. Use it for initialization tasks. It receives a context object for interacting with the plugin frame.
```typescript
export type OnBootHook = {
onBoot: (ctx: ImposedSizePluginFrameCtx<'onBoot'>) => void;
};
connect({
onBoot(ctx) {
console.log('Plugin booted for project:', ctx.site.id);
ctx.notice('Plugin initialized');
}
});
```
--------------------------------
### Lifecycle Hook: onBoot
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
This hook is called once when the plugin loads, allowing for initialization logic. It receives the context object for accessing site information.
```typescript
connect({
onBoot(ctx) {
// Called once when plugin loads
console.log('Plugin initialized for:', ctx.site.name);
}
});
```
--------------------------------
### Field Extension Rendering Logic
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
This React component illustrates how a field extension can interact with the DatoCMS context to display and update a field's value. It uses `ctx.formValues` to get the current value and `ctx.setFieldValue` to update it.
```typescript
function ColorPicker({ ctx }) {
const currentValue = ctx.formValues[ctx.fieldPath];
return (
);
}
```
--------------------------------
### Connect Plugin to DatoCMS SDK
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
Use the `connect` function as the entry point for your plugin. Register hook implementations like declaration, render, and event hooks to extend DatoCMS functionality.
```typescript
import { connect } from 'datocms-plugin-sdk';
connect({
// Declaration hook: returns configuration
itemFormSidebarPanels(ctx) {
return [
{ id: 'metrics', label: 'Metrics' }
];
},
// Render hook: renders UI in iframe
renderItemFormSidebarPanel(sidebarPanelId, ctx) {
ReactDOM.render(, document.getElementById('root'));
},
// Event hook: reacts to lifecycle events
onBeforeItemUpsert(item, ctx) {
// Validate or transform the item before saving
return item;
},
});
```
--------------------------------
### DatoCMS Plugins SDK File Structure
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/INDEX.md
Illustrates the directory layout for the datocms-plugin-sdk and datocms-react-ui packages within the project.
```tree
plugins-sdk/
├── packages/
│ ├── sdk/ # datocms-plugin-sdk package
│ │ ├── src/
│ │ │ ├── connect.ts # Main entry point
│ │ │ ├── ctx/ # Context type definitions
│ │ │ ├── hooks/ # Hook definitions (60 files)
│ │ │ ├── shared.ts # Shared types
│ │ │ ├── guardUtils.ts # Type guards
│ │ │ └── utils.ts # Utilities
│ │ └── package.json
│ └── react-ui/ # datocms-react-ui package
│ ├── src/
│ │ ├── index.ts # Main export
│ │ ├── Canvas/ # Root component
│ │ ├── Button/ # Button component
│ │ ├── *Field/ # Form field components
│ │ └── ...
│ └── package.json
└── README.md
```
--------------------------------
### Navigation Methods
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/context-and-types.md
Method for navigating within the DatoCMS backend.
```APIDOC
## `navigateTo`
### Description
Navigates to another URL internal to the DatoCMS backend.
### Signature
`(path: string) => Promise`
### Parameters
#### Request Body
- **path** (string) - Required - The internal URL path to navigate to.
```
--------------------------------
### Connect Plugin with Multiple Hooks
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
Use this snippet to connect your plugin and define handlers for configuration screens, onBoot lifecycle, field extensions, and modals. Ensure you have ReactDOM available for rendering.
```typescript
import { connect } from 'datocms-plugin-sdk';
connect({
renderConfigScreen(ctx) {
// Render the plugin configuration screen
ReactDOM.render(
,
document.getElementById('root')
);
},
onBoot(ctx) {
// Perform initialization tasks
console.log('Plugin booted for project:', ctx.site.id);
},
renderFieldExtension(fieldExtensionId, ctx) {
// Render a field extension
ReactDOM.render(
,
document.getElementById('root')
);
},
renderModal(id, ctx) {
// Render a custom modal
ReactDOM.render(
,
document.getElementById('root')
);
},
});
```
--------------------------------
### Create a Dropdown Menu
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Implement a dropdown menu with options using the Dropdown component and its sub-components like Menu, Option, and OptionAction.
```typescript
import { Dropdown } from 'datocms-react-ui';
EditDelete
```
--------------------------------
### Modal and Confirmation Methods
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/context-and-types.md
Methods for opening custom modals and confirmation dialogs.
```APIDOC
## `openModal`
### Description
Opens a custom modal and returns the value passed to the modal's resolve function.
### Signature
`(modal: Modal) => Promise`
### Parameters
#### Request Body
- **modal** (Modal) - Required - The modal configuration object.
```
```APIDOC
## `openConfirm`
### Description
Opens a UI-consistent confirmation dialog and returns the selected choice value.
### Signature
`(options: ConfirmOptions) => Promise`
### Parameters
#### Request Body
- **options** (ConfirmOptions) - Required - The confirmation dialog options.
```
--------------------------------
### SelectInput Component Usage
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Demonstrates how to use the SelectInput component for single selection with search capabilities. Ensure 'datocms-react-ui' is imported.
```typescript
import { SelectInput } from 'datocms-react-ui';
setSelectedId(option.value)}
options={[
{ label: 'Option 1', value: 'opt1' },
{ label: 'Option 2', value: 'opt2' }
]}
/>
```
--------------------------------
### connect Function Configuration
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
The `connect` function is used to configure your DatoCMS plugin. You can provide various hooks to customize its behavior, such as `renderConfigScreen`, `onBoot`, `renderFieldExtension`, and `renderModal`. The function also automatically handles color scheme support.
```APIDOC
## connect
### Description
The `connect` function is the primary method for initializing and configuring your DatoCMS plugin. It accepts a configuration object that allows you to define various hooks for different plugin functionalities, including initialization, rendering configuration screens, field extensions, and modals. It also manages color scheme support for your plugin.
### Usage
```typescript
import { connect } from '@datocms/plugins-sdk';
connect({
// Optional hooks for plugin functionality
onBoot(ctx) {
// Initialization logic
},
renderConfigScreen(ctx) {
// Render the configuration screen UI
},
renderFieldExtension(id, ctx) {
// Render custom UI for field extensions
},
renderModal(id, ctx) {
// Render custom UI for modals
},
fieldDropdownActions() {
// Define actions for the field dropdown menu
},
// ... other available hooks
});
```
### Color Scheme Support
The `connect` function automatically applies color scheme support to your plugin. This is achieved in two ways:
1. **HTML attribute**: Sets the `data-color-scheme` attribute on the document element, allowing you to style your plugin using CSS selectors like `[data-color-scheme="dark"] { ... }`.
2. **CSS property**: Sets the `color-scheme` CSS property, which helps in the proper rendering of native form controls and scrollbars.
The current color scheme ('light' or 'dark') is also available in the context object as `ctx.colorScheme`.
### Parameters
- **configuration object** (object) - Required - An object containing various hooks to configure the plugin.
- **onBoot** (function) - Optional - Called when the plugin boots up. Receives the `Ctx` object.
- **renderConfigScreen** (function) - Optional - Called when the configuration screen needs to be rendered. Receives the `Ctx` object.
- **renderFieldExtension** (function) - Optional - Called when a field extension needs to be rendered. Receives the field `id` and the `Ctx` object.
- **renderModal** (function) - Optional - Called when a modal needs to be rendered. Receives the modal `id` and the `Ctx` object.
- **fieldDropdownActions** (function) - Optional - Returns an array of actions to be displayed in the field dropdown menu.
- **ctx** (Ctx) - Base context object passed to most hooks, providing access to plugin utilities and information.
- **colorScheme** (string) - Available in the `Ctx` object, indicates the current color scheme ('light' or 'dark').
### Related
- `FullConnectParameters`: Type for all available configuration hooks.
- `Ctx`: Base context object passed to all hooks.
```
--------------------------------
### Complete Plugin Configuration Screen
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
This snippet shows a full React component for a DatoCMS plugin's configuration screen. It uses various UI components like TextField, SwitchField, and Button to manage plugin settings. Use this as a template for creating your own plugin configuration interfaces.
```typescript
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'datocms-plugin-sdk';
import {
Canvas,
Section,
TextField,
SwitchField,
Button,
ButtonGroup,
Spinner
} from 'datocms-react-ui';
import 'datocms-react-ui/styles.css';
function ConfigScreen({ ctx }) {
const [title, setTitle] = useState(ctx.plugin.parameters?.title || '');
const [featured, setFeatured] = useState(ctx.plugin.parameters?.featured || false);
const [saving, setSaving] = useState(false);
const handleSave = async () => {
setSaving(true);
try {
await ctx.updatePluginParameters({ title, featured });
await ctx.notice('Settings saved!');
} catch (error) {
await ctx.alert('Error saving settings');
} finally {
setSaving(false);
}
};
return (
);
}
connect({
renderConfigScreen(ctx) {
ReactDOM.render(
,
document.getElementById('root')
);
}
});
```
--------------------------------
### Open Standard Dialogs for User Interaction
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Utilize the `renderModal` hook to integrate with DatoCMS's standard dialogs, such as record selection. The `ctx.selectItem` method can be used within `renderConfigScreen` to allow users to pick items.
```typescript
connect({
async renderModal(id, ctx) {
if (id === 'selectRecord') {
ReactDOM.render(
{
await ctx.resolve(itemId);
}}
onCancel={() => ctx.resolve(null)}
/>,
document.getElementById('root')
);
}
}
});
connect({
renderConfigScreen(ctx) {
const handleSelectRecord = async () => {
const item = await ctx.selectItem('model_id');
if (item) {
await ctx.notice(`Selected: ${item.id}`);
}
};
// ...
}
});
```
--------------------------------
### Loading Additional Data with SDK
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Load various project entities like model fields, fieldsets, users, or fields using specific `ctx.load*` methods.
```typescript
// Load all fields for a model
const fields = await ctx.loadItemTypeFields('model_id');
// Load all fieldsets for a model
const fieldsets = await ctx.loadItemTypeFieldsets('model_id');
// Load all users
const users = await ctx.loadUsers();
// Load all fields using this plugin
const fields = await ctx.loadFieldsUsingPlugin();
```
--------------------------------
### connect() Function Signature
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/connect.md
The signature for the connect() function, which is the primary method for initializing a DatoCMS plugin. It accepts an optional configuration object and returns a Promise.
```typescript
export async function connect(
rawConfiguration: Partial = {},
): Promise
```
--------------------------------
### Initialize Canvas Wrapper
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Use the Canvas component at the root of your plugin UI to provide theme context and enable auto-resizing. It injects CSS design tokens and manages the auto-resizer lifecycle.
```typescript
import { Canvas } from 'datocms-react-ui';
```
--------------------------------
### Plugin Declaration and Rendering Hooks
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
This code snippet demonstrates how to connect a plugin to the DatoCMS SDK, declaring manual field extensions and defining the rendering logic for a specific field extension.
```typescript
// my-plugin/src/index.ts
import { connect } from 'datocms-plugin-sdk';
connect({
// Declaration hook: tell CMS about the field extension
manualFieldExtensions(ctx) {
return [
{
id: 'colorPicker',
name: 'Color Picker',
type: 'editor',
fieldTypes: ['string'],
},
];
},
// Render hook: render the field extension UI
renderFieldExtension(fieldExtensionId, ctx) {
if (fieldExtensionId === 'colorPicker') {
ReactDOM.render(, document.getElementById('root'));
}
},
});
```
--------------------------------
### DatoCMS React UI UI Components
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/README.md
The `datocms-react-ui` library offers a set of pre-built React components for creating plugin interfaces.
```typescript
import { Canvas, Button, TextField } from 'datocms-react-ui';
function MyComponent() {
return (
<>
>
);
}
```
--------------------------------
### Import datocms-react-ui Styles
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Always import the component styles at the top of your entry file to ensure proper theming and styling.
```typescript
import 'datocms-react-ui/styles.css';
```
--------------------------------
### Plugin Configuration Methods
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/context-and-types.md
Methods for updating plugin parameters and field appearance settings.
```APIDOC
## `updatePluginParameters`
### Description
Updates the plugin parameters. Requires `can_edit_schema` permission.
### Signature
`(params: Record) => Promise`
### Parameters
#### Request Body
- **params** (Record) - Required - An object containing the plugin parameters to update.
```
```APIDOC
## `updateFieldAppearance`
### Description
Performs changes to field appearance: install/remove/update manual field extensions or addon parameters. Requires `can_edit_schema` permission.
### Signature
`(fieldId: string, changes: FieldAppearanceChange[]) => Promise`
### Parameters
#### Path Parameters
- **fieldId** (string) - Required - The ID of the field to update appearance for.
#### Request Body
- **changes** (FieldAppearanceChange[]) - Required - An array of changes to apply to the field appearance.
```
--------------------------------
### Generate Plugin Manifest
Source: https://github.com/datocms/plugins-sdk/blob/master/packages/sdk/ARCHITECTURE.md
Illustrates the `generateManifest.ts` script's process of parsing TypeScript AST to extract hook signatures, JSDoc comments, and context types to generate a `manifest.json` file.
```typescript
// generateManifest.ts:513
const hooks = hookFiles.map((file) => processFile(file, sharedCtxTypes));
const manifest: Manifest = {
hooks: Object.fromEntries(hooks.map((hook) => [hook.name, hook])),
baseCtx: {
properties: extractGroupsFromTypeInFilePath('src/ctx/base.ts', 'BaseProperties'),
methods: extractGroupsFromTypeInFilePath('src/ctx/base.ts', 'BaseMethods'),
},
// ...
};
```
--------------------------------
### Accessing Context in Field Extension Hooks
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/plugin-development-guide.md
Demonstrates how to access properties like site ID, user email, field API key, current value, and disabled status from the context object. Also shows how to use context methods to display notices, set field values, and create new items.
```typescript
connect({
async renderFieldExtension(id, ctx) {
// Properties
console.log('Project:', ctx.site.id);
console.log('Current user:', ctx.currentUser.email);
console.log('Field:', ctx.field.attributes.api_key);
console.log('Current value:', ctx.formValues[ctx.fieldPath]);
console.log('Is disabled:', ctx.disabled);
// Methods
await ctx.notice('Field loaded');
await ctx.setFieldValue(ctx.fieldPath, 'new value');
const item = await ctx.createNewItem('model_id');
}
});
```
--------------------------------
### Dialog Methods
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/context-and-types.md
Methods for opening various dialogs to interact with items, uploads, and metadata.
```APIDOC
## `createNewItem`
### Description
Opens dialog to create a new record of the specified type.
### Signature
`(itemTypeId: string) => Promise`
### Parameters
#### Path Parameters
- **itemTypeId** (string) - Required - The ID of the item type to create.
```
```APIDOC
## `selectItem`
### Description
Opens dialog to select one or more records. Returns array if `multiple: true`, single item otherwise.
### Signature
`(itemTypeId: string, options?: { multiple?: boolean; initialLocationQuery?: ItemListLocationQuery }) => Promise`
### Parameters
#### Path Parameters
- **itemTypeId** (string) - Required - The ID of the item type to select from.
#### Query Parameters
- **options** (object) - Optional - Configuration for the selection dialog.
- **multiple** (boolean) - Optional - Whether to allow multiple selections.
- **initialLocationQuery** (ItemListLocationQuery) - Optional - Initial query for the item list.
```
```APIDOC
## `editItem`
### Description
Opens dialog to edit an existing record.
### Signature
`(itemId: string) => Promise`
### Parameters
#### Path Parameters
- **itemId** (string) - Required - The ID of the item to edit.
```
```APIDOC
## `selectUpload`
### Description
Opens dialog to select one or more media assets.
### Signature
`(options?: { multiple?: boolean }) => Promise`
### Parameters
#### Query Parameters
- **options** (object) - Optional - Configuration for the upload selection dialog.
- **multiple** (boolean) - Optional - Whether to allow multiple selections.
```
```APIDOC
## `editUpload`
### Description
Opens dialog to edit a media asset. Returns asset with `deleted: true` if deleted.
### Signature
`(uploadId: string) => Promise<(Upload & { deleted?: true }) | null>`
### Parameters
#### Path Parameters
- **uploadId** (string) - Required - The ID of the upload to edit.
```
```APIDOC
## `editUploadMetadata`
### Description
Opens dialog to edit single asset field structure metadata.
### Signature
`(fileFieldValue: FileFieldValue, locale?: string) => Promise`
### Parameters
#### Request Body
- **fileFieldValue** (FileFieldValue) - Required - The file field value to edit.
#### Query Parameters
- **locale** (string) - Optional - The locale for which to edit the metadata.
```
--------------------------------
### Create a SelectField
Source: https://github.com/datocms/plugins-sdk/blob/master/_autodocs/react-ui-components.md
Implement a dropdown select input. Pass child `