Plugin SDK > Asset sources

    Asset sources

    By default, to add new assets to the Media Area through the interface, you can upload files from your computer. But plugins can define custom asset sources to allow contributors to upload assets from external providers.

    For example, the Unsplash plugin present in the Marketplace allows to upload royalty-free high-resolution images:

    Define custom asset sources

    Within a plugin you can define the assetSources hook to expose new asset sources. Every source must specify an internal ID, and a name and a representative icon that will be shown in the interface.

    import { connect } from 'datocms-plugin-sdk';
    connect({
    assetSources() {
    return [
    {
    id: 'unsplash',
    name: 'Unsplash',
    icon: {
    type: 'svg',
    viewBox: '0 0 448 512',
    content:
    '<path fill="currentColor" d="M448,230.17V480H0V230.17H141.13V355.09H306.87V230.17ZM306.87,32H141.13V156.91H306.87Z" class=""></path>',
    },
    modal: {
    width: 'm',
    },
    },
    ];
    },
    });

    Rendering the custom asset source

    When the user selects the custom source, a modal will be opened with the size you specified, and the renderAssetSource hook will be called. Inside of this hook we initialize React and render a custom component called AssetBrowser, passing down as a prop the second ctx argument, which provides a series of information and methods for interacting with the main application:

    import { connect } from 'datocms-plugin-sdk';
    connect({
    assetSources() {
    return [{...}];
    },
    renderAssetSource(sourceId: string, ctx: RenderAssetSourceCtx) {
    render(<AssetBrowser ctx={ctx} />);
    },
    });

    As we just saw, a plugin might offer different asset sources, so we can use the sourceId argument to know which one we are requested to render, and write a specific React component for each of them.

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

    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.

    We can use this component to render whatever we want. The important thing is to call the ctx.select method to communicate to the main DatoCMS app the selected asset URL:

    import { ButtonLink } from 'datocms-react-ui';
    function AssetBrowser({ ctx }: PropTypes) {
    const handleSelect = () => {
    ctx.select({
    resource: {
    url: 'https://unsplash.com/photos/yf8qPXQFDJE',
    filename: `sky.jpg`,
    },
    });
    }
    return (
    <Canvas ctx={ctx}>
    <Button onClick={handleSelect}>Select</Button>
    </Canvas>
    );
    }

    If you're generating your asset on the fly (ie. by rendering on a canvas), instead of a regular URL you can also pass a base64-encoded data URI:

    ctx.select({
    resource: {
    base64: 'data:image/png;base64,PD94bWwgd..',
    filename: `generated-image.png`,
    },
    });

    You can also optionally specify some metadata to associate with the newly created upload:

    ctx.select({
    resource: {
    url:
    'https://images.unsplash.com/photo-1416339306562-f3d12fefd36f',
    filename: 'man-drinking-coffee.jpg',
    },
    copyright: 'Royalty free (Unsplash)',
    author: 'Jeff Sheldon',
    notes: 'A man drinking a coffee',
    tags: ['man', 'coffee'],
    });

    assetSources

    Use this function to declare additional sources to be shown when users want to upload new assets.

    Properties available in context

    The following information and methods are available:

    renderAssetSource

    This function will be called when the user selects one of the plugin's asset sources to upload a new media file.

    Properties available in context

    The following information and methods are available:

    Methods available in context

    The following information and methods are available: