A completely revamped plugin SDK was released in November 2021. Plugins leveraging the legacy SDK will continue to work indefinitely, but are much more limited in their possibilities, as they can only manage what in the new SKD are called manual field extensions. All the other extension points are not available.
If you're looking for the Legacy SDK documentation, it is still available here.
If you are interested in migrating to the new SDK, please note the following points:
Global parameters no longer need to be declared in the package.json
, but are configurable through the config-screen hooks.
The data storage format is now also completely custom, as well as the interface that is shown to end users.
The old options:
"Type of plugin" (field editor, field add-on or sidebar widget), and
"Types of field" (specifying where it's possible to use the legacy plugin)
do not have to be declared in the package.json
anymore, but are configurable through the manualFieldExtensions
hook. The old "sidebar widget" plugin type is nothing but an additional asSidebarPanel
option you can pass to the new ManualFieldExtension
type:
import { connect, Field, InitCtx } from 'datocms-plugins-sdk';connect({manualFieldExtensions(ctx: InitCtx) {return [{id: 'sidebarWidget',name: 'My sidebar widget',type: 'editor',fieldTypes: ['integer'],asSidebarPanel: true,},];},renderFieldExtension(id, ctx) {// ...},});
Instance parameters no longer need to be declared in the package.json
, but are now completely arbitrary, as well as the interface that is shown to end users. Take a look at this part of the documentation.
plugin.xxx
methods and properties All methods and information previously available through plugin.xxx
calls is now available through the ctx
argument of the renderFieldExtension
hook.
Since new plugins can expose multiple manual field extensions, you need to implement an onBoot
hook to properly set the fieldExtensionId
attribute on each field that was previously hooked with the plugin.
connect({// plugin exposes a `myExtension` manual field extensionmanualFieldExtensions(ctx: InitCtx) {return [{id: 'myExtension',name: 'Foo bar',type: 'editor',fieldTypes: ['integer'],},];},async onBoot(ctx: OnBootCtx) {// if we already performed the migration, skipif (ctx.plugin.attributes.parameters.migratedFromLegacyPlugin) {return;}// if the current user cannot edit fields' settings, skipif (!ctx.currentRole.meta.final_permissions.can_edit_schema) {return;}// get all the fields currently associated to the plugin...const fields = await ctx.loadFieldsUsingPlugin();// ... and for each of them...await Promise.all(fields.map(async (field) => {// set the fieldExtensionId to be the new oneawait ctx.updateFieldAppearance(field.id, [{operation: 'updateEditor',newFieldExtensionId: 'myExtension',}]);}),);// save in configuration the fact that we already performed the migrationctx.updatePluginParameters({...ctx.plugin.attributes.parameters,migratedFromLegacyPlugin: true,});},});
connect({// plugin exposes a `myExtension` manual field extensionmanualFieldExtensions(ctx: InitCtx) {return [{id: 'myExtension',name: 'Foo bar',type: 'addon',fieldTypes: ['integer'],},];},async onBoot(ctx: OnBootCtx) {// if we already performed the migration, skipif (ctx.plugin.attributes.parameters.migratedFromLegacyPlugin) {return;}// if the current user cannot edit fields' settings, skipif (!ctx.currentRole.meta.final_permissions.can_edit_schema) {return;}// get all the fields currently associated to the plugin...const fields = await ctx.loadFieldsUsingPlugin();// ... and for each of them...await Promise.all(fields.map(async (field) => {const { appearance } = field.attributes;const changes: FieldAppearanceChange[] = [];// find where our plugin is used...appearance.addons.forEach((addon, index) => {// set the fieldExtensionId to be the new onechanges.push({operation: 'updateAddon',index,newFieldExtensionId: 'myExtension',});});await ctx.updateFieldAppearance(field.id, changes);}),);// save in configuration the fact that we already performed the migrationctx.updatePluginParameters({...ctx.plugin.attributes.parameters,migratedFromLegacyPlugin: true,});},});