### 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 (
setApiKey(e.target.value)} hint="Your API key from the service" />
); } 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 ( { // Update the field value in the form ctx.setFieldValue(ctx.fieldPath, e.target.value); }} /> ); } ``` -------------------------------- ### 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'; Edit Delete ``` -------------------------------- ### 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 (
setTitle(e.target.value)} /> setFeatured(e.target.checked)} />
{saving && }
); } 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'; {/* Your plugin UI here */} ``` -------------------------------- ### 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 ( <> {/* Canvas content */} ); } ``` -------------------------------- ### 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 `