# Asset Manager

In this section, you will see how to set up and take full advantage of the built-in Asset Manager in GrapesJS. The Asset Manager is lightweight and includes only the image asset type in its core, but as you'll see, it's easy to extend and create your own asset types.
TIP
Want an asset manager that looks great out of the box? Try the Grapes Studio SDK! (opens new window)
# Configuration
To change the default configuration, pass the assetManager property in the main configuration object:
const editor = grapesjs.init({
...
assetManager: {
assets: [...],
...
}
});
You can update most options later using the module's getConfig method:
const amConfig = editor.AssetManager.getConfig();
Check the full list of available options here: Asset Manager Config (opens new window)
# Initialization
The Asset Manager is ready to work by default, so pass a few URLs to see them loaded:
const editor = grapesjs.init({
...
assetManager: {
assets: [
'https://placeholder.photo/350x250/78c5d6/fff?text=image1.jpg',
// Pass an object with your properties
{
type: 'image',
src: 'https://placeholder.photo/350x250/459ba8/fff?text=image2.jpg',
height: 350,
width: 250,
name: 'displayName'
},
{
// As 'image' is the base asset type, omitting the type
// will default to `image`
src: 'https://placeholder.photo/350x250/79c267/fff?text=image3.jpg',
height: 350,
width: 250,
name: 'displayName'
},
],
}
});
For a complete list of available properties, check the AssetImage Model source (opens new window).
The built-in Asset Manager modal appears when requested. By default, you can open it by dragging Image Components onto the canvas, double-clicking images, or using other image-related features (e.g., CSS styling).
# Uploading assets
The default Asset Manager also includes an easy-to-use drag-and-drop uploader with a few UI helpers. The default uploader is already visible when you open the Asset Manager.
You can click on the uploader to select your files or just drag them directly from your computer to trigger the uploader. Before it will work, you have to set up your server to receive assets and specify the upload endpoint in your configuration:
const editor = grapesjs.init({
...
assetManager: {
...
// Upload endpoint, set `false` to disable upload, default `false`
upload: 'https://endpoint/upload/assets',
// The name used in POST to pass uploaded files, default: `'files'`
uploadName: 'files',
...
},
...
});
# Listeners
To execute an action before/after uploading (e.g., showing a loading animation) or when a response arrives, use these listeners:
// The upload has started
editor.on('asset:upload:start', () => {
startAnimation();
});
// The upload has ended (successfully or otherwise)
editor.on('asset:upload:end', () => {
endAnimation();
});
// Error handling
editor.on('asset:upload:error', (err) => {
notifyError(err);
});
// Do something on response
editor.on('asset:upload:response', (response) => {
...
});
# Response
When uploading finishes, the editor expects a JSON response containing the uploaded assets under a data key and tries to add them to the main collection by default (via the configuration parameter autoAdd: 1). The JSON might look like this:
{
data: [
'https://.../image.png',
// ...
{
src: 'https://.../image2.png',
type: 'image',
height: 100,
width: 200,
},
// ...
];
}
# Programmatic usage
To manage your assets programmatically, use the Asset Manager API.
// Get the Asset Manager module first
const am = editor.AssetManager;
The Asset Manager keeps two collections of assets:
- global - Contains all available assets. Access it with
am.getAll(). - visible - Contains the assets currently rendered by the Asset Manager. Access it with
am.getAllVisible().
This allows you to decide which assets to show and when. Let's say we'd like to have a category switcher. First, add all your assets to the global collection (you may have already defined them during initialization with config.assetManager.assets = [...]):
am.add([
{
// You can pass any custom property you want
category: 'c1',
src: 'https://placeholder.photo/350x250/78c5d6/fff?text=image1.jpg',
},
{
category: 'c1',
src: 'https://placeholder.photo/350x250/459ba8/fff?text=image2.jpg',
},
{
category: 'c2',
src: 'https://placeholder.photo/350x250/79c267/fff?text=image3.jpg',
},
// ...
]);
Now, if you call render() without an argument, you will see all the assets rendered:
// without any argument
am.render();
am.getAll().length; // <- 3
am.getAllVisible().length; // <- 3
Now let's show only assets from the first category:
const assets = am.getAll();
am.render(assets.filter((asset) => asset.get('category') == 'c1'));
am.getAll().length; // Still have 3 assets
am.getAllVisible().length; // but only 2 are shown
You can also mix arrays of assets:
am.render([...assets1, ...assets2, ...assets3]);
To update or remove an asset, use these methods:
// Get the asset via its `src`
const asset = am.get('http://.../img.jpg');
// Update asset property
asset.set({ src: 'http://.../new-img.jpg' });
// Remove asset
am.remove(asset); // or via src, am.remove('http://.../new-img.jpg');
For more API methods, check out the API Reference.
# Custom select logic
WARNING
This section applies to GrapesJS v0.17.26 or higher.
You can open the Asset Manager with your own select logic.
am.open({
types: ['image'], // This is the default option
// Without select, nothing will happen on asset selection
select(asset, complete) {
const selected = editor.getSelected();
if (selected && selected.is('image')) {
selected.addAttributes({ src: asset.getSrc() });
// The default AssetManager UI will trigger `select(asset, false)`
// on asset click and `select(asset, true)` on double-click
complete && am.close();
}
},
});
# Customization
The default Asset Manager UI is useful for simple tasks and can be styled with CSS. Adding more complex features, such as a search input or filters, requires replacing the default UI.
Tell the editor to use a custom UI, then subscribe to the asset:custom event, which provides information about any requested changes.
const editor = grapesjs.init({
// ...
assetManager: {
// ...
custom: true,
},
});
editor.on('asset:custom', (props) => {
// The `props` will contain all the information you need in order to update your UI.
// props.open (boolean) - Indicates if the Asset Manager is open
// props.assets (Array<Asset>) - Array of all assets
// props.types (Array<String>) - Array of asset types requested, e.g., ['image'],
// props.close (Function) - A callback to close the Asset Manager
// props.remove (Function<Asset>) - A callback to remove an asset
// props.select (Function<Asset, boolean>) - A callback to select an asset
// props.container (HTMLElement) - The element where you should append your UI
// Here you would put the logic to render/update your UI.
});
Here's an example of a custom Asset Manager using a Vue component.
The example above shows how to replace the default UI. Notice that we append the mounted element to the container with props.container.appendChild(this.$el);.
This is required as the Asset Manager, by default, is placed in the Modal.
If your Asset Manager is a completely independent/external module (e.g., it should appear in its own custom modal), you can bind its state via assetManager.custom.open.
const editor = grapesjs.init({
// ...
assetManager: {
// ...
custom: {
open(props) {
// `props` contains the same properties as in the `asset:custom` event
// ...
// Init and open your external Asset Manager
// ...
// IMPORTANT:
// When the external library is closed you have to communicate
// this state back to the editor, otherwise GrapesJS will think
// the Asset Manager is still open.
// example: myAssetManager.on('close', () => props.close())
},
close(props) {
// Close the external Asset Manager
},
},
},
});
Also declare the close function so the editor can close the Asset Manager via am.close().
# Events
For a complete list of available events, check here.