Plugin SDK > Form outlets

    Form outlets

    Through plugins it is possible to add customize the area above the record form. We call this special area "form outlet":

    A form outlet is nothing more than an iframe, inside of which the plugin developer can render what they prefer, while also having the possibility to:

    • access a series of information relating to the record that's being edited, the project in which the plugin is installed or the logged-in user;

    • make calls to DatoCMS to produce various effects and interact with the main application (changing form values, navigating to other pages, triggering notifications, opening modals, etc.);

    If you prefer, a form outlet can also be completely hidden from the interface, and work under the cover to tweak the default behaviour of DatoCMS.

    Implementing a simple form outlet

    The first step is to implement the itemFormOutlets hook, to declare our intent to add the outlet to the form:

    import { connect, IntentCtx } from 'datocms-plugin-sdk';
    connect({
    itemFormOutlets(model: ModelBlock, ctx: IntentCtx) {
    return [
    {
    id: 'myOutlet',
    initialHeight: 100,
    },
    ];
    },
    });

    The initialHeight property sets the initial height of the frame, while the plugin itself is loading. It can also be useful to completely hide the outlet, by passing the value zero to it.

    The code above will add the outlet to the form of every record in our project, but you can also add some settings to the plugin to ie. let the final user pick only some specific models:

    itemFormOutlets(model: ModelBlock, ctx: IntentCtx) {
    const { modelApiKeys } = ctx.plugin.attributes.parameters;
    if (!modelApiKeys.includes(model.attributes.api_key)) {
    // Don't add the outlet!
    return [];
    }
    // Add the outlet!
    }

    Rendering the outlet

    The final step is to actually render the outlet itself by implementing the renderItemFormOutlet hook.

    Inside of this hook we can initialize React and render a custom component, passing down as a prop the second ctx argument, which provides a series of information and methods for interacting with the main application:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { connect, RenderItemFormOutletCtx } from 'datocms-plugin-sdk';
    connect({
    renderItemFormOutlet(
    outletId,
    ctx: RenderItemFormOutletCtx,
    ) {
    ReactDOM.render(
    <React.StrictMode>
    <MyCustomOutlet ctx={ctx} />
    </React.StrictMode>,
    document.getElementById('root'),
    );
    },
    });

    A plugin might render different types of outlets, so we can use the outletId argument to know which one we are requested to render, and write a specific React component for each of them.

    import { Canvas } from 'datocms-react-ui';
    type PropTypes = {
    ctx: RenderItemFormOutletCtx;
    };
    function MyCustomOutlet({ ctx }: PropTypes) {
    return (
    <Canvas ctx={ctx}>
    Hello from the outlet!
    </Canvas>
    );
    }
    Always use the canvas!

    If you want to render something inside the outlet, it is important to wrap the content inside the Canvas component, so that the iframe will continuously auto-adjust its size based on the content we're rendering, and to give our app the look and feel of the DatoCMS web app.

    If you want the outlet to be hidden from the interface, just return null and set an initialHeight: 0 in the itemFormOutlets hook.


    itemFormOutlets

    Use this function to declare custom outlets to be shown at the top of the record's editing page.

    Return value

    The function must return an array of objects with the following structure:

    Properties available in context

    The following information and methods are available:

    renderItemFormOutlet

    This function will be called when the plugin needs to render an outlet (see the itemFormOutlets function).

    Properties available in context

    The following information and methods are available:

    Methods available in context

    The following information and methods are available: