Skip to main content

Assets

With GrapesJS Studio SDK, your end-users can add images, fonts, videos and pdf files to their projects.

Asset Storage

You can configure how to store these assets, so they can be used safely in the published product. This is controlled by the assets option of the SDK.

You can either use our cloud storage, or use a custom storage method of your own.

warning

Always configure one of these, otherwise assets will be added as data urls, resulting in heavy html exports and potentially slower load times.

Cloud Storage

We provide an easy way to upload assets for your users. To use this, set assets.storageType to cloud, and add a unique id for each of your projects and end-users.

import StudioEditor from '@grapesjs/studio-sdk/react';
import '@grapesjs/studio-sdk/style';

// ...
<StudioEditor
options={{
licenseKey: "YOUR_LICENSE_KEY",
assets: {
storageType: "cloud"
},
project: {
id: "UNIQUE_PROJECT_ID"
},
identity: {
id: "UNIQUE_END_USER_ID"
}
}}
/>
warning

Avoid sensitive data in these identifiers, like emails, or phone numbers.

These project and identity ids are mandatory. We use them for allowing end-users to reuse their assets across different projects.

Custom Storage

If you want to handle asset storage on your own, set assets.storageType to self. Now you can specify assets.onUpload, assets.onLoad and assets.onDelete callbacks.

import StudioEditor from '@grapesjs/studio-sdk/react';
import '@grapesjs/studio-sdk/style';

const myUploadAssetsLogic = async (files) => {
await waitAndFailRandomly('Testing when upload assets failed');
const mockUploadedFiles = files.map(file => ({ file, url: URL.createObjectURL(file) }));
console.log('Assets to upload to the self-hosted storage', mockUploadedFiles);
return mockUploadedFiles;
}

const myDeleteAssetsLogic = async ({ assets }) => {
await waitAndFailRandomly('Testing when delete assets failed');
console.log('Assets to delete from the self-hosted storage', assets.map(asset => asset.getSrc()));
}

const waitAndFailRandomly = async (str) => {
await new Promise(res => setTimeout(res, 1000)); // fake delay
if (Math.random() >= 0.7) throw new Error(str);
}

// ...
<StudioEditor
options={{
// ...
assets: {
storageType: 'self',
// this is an example, you can do whatever you want in these callbacks as long as you return the same arrays.
onUpload: async ({ files, editor }) => {
// TODO: implement myUploadAssetsLogic to upload files
const results = await myUploadAssetsLogic(files);
// return an array with the uploaded assets
return results.map(({ file, url }) => ({
id: url,
src: url,
name: file.name,
mimeType: file.type,
size: file.size
}));
},
onDelete: async ({ assets, editor }) => {
// TODO: implement myDeleteAssetsLogic to delete assets
await myDeleteAssetsLogic({ assets });
// No need to return anything, just let the promise resolve without errors
}
},
project: {
default: {
// project assets
assets: Array(5).fill(0).map((_, i) => ({
name: 'Project image ' + i,
src: `https://picsum.photos/seed/from-project-${i}/300/300`
})),
pages: [
{ name: 'Home', component: '<h1>Double click the image to open the Asset Manager</h1><img src="https://picsum.photos/seed/x/300/300"/>'},
]
}
},
}}
/>