# Asset Manager
In this section, you will see how to setup and take the full advantage of built-in Asset Manager in GrapesJS. The Asset Manager is lightweight and implements just an image
in its core, but as you'll see next it's easy to extend and create your own asset types.
# Configuration
To change default configurations you'd need to pass the assetManager
property with the main configuration object
const editor = grapesjs.init({
...
assetManager: {
assets: [...],
...
}
});
You can update most of them later by using getConfig
inside of the module
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 few URLs to see them loaded
const editor = grapesjs.init({
...
assetManager: {
assets: [
'http://placehold.it/350x250/78c5d6/fff/image1.jpg',
// Pass an object with your properties
{
type: 'image',
src: 'http://placehold.it/350x250/459ba8/fff/image2.jpg',
height: 350,
width: 250,
name: 'displayName'
},
{
// As the 'image' is the base type of assets, omitting it will
// be set as `image` by default
src: 'http://placehold.it/350x250/79c267/fff/image3.jpg',
height: 350,
width: 250,
name: 'displayName'
},
],
}
});
If you want a complete list of available properties check out the source AssetImage Model (opens new window)
The built-in Asset Manager modal is implemented and is showing up when requested. By default, you can make it appear by dragging Image Components in canvas, double clicking on images and all other stuff related to images (eg. CSS styling)
# Uploading assets
The default Asset Manager includes also 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. Obviously, before it will work you have to setup your server to receive your 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
If you want to execute an action before/after the uploading process (eg. loading animation) or even on response, you can make use of these listeners
// The upload is started
editor.on('asset:upload:start', () => {
startAnimation();
});
// The upload is ended (completed or not)
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 the uploading is over, by default (via config parameter autoAdd: 1
), the editor expects to receive a JSON of uploaded assets in a data
key as a response and tries to add them to the main collection. The JSON might look like this:
{
data: [
'https://.../image.png',
// ...
{
src: 'https://.../image2.png',
type: 'image',
height: 100,
width: 200,
},
// ...
];
}
# Programmatic usage
If you need to manage your assets programmatically you have to use its APIs
// Get the Asset Manager module first
const am = editor.AssetManager;
First of all, it's worth noting that Asset Manager keeps 2 collections of assets:
- global - which is just the one with all available assets, you can get it with
am.getAll()
- visible - this is the collection which is currently rendered by the Asset Manager, you get 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 of all you gonna add to the global collection all your assets (which you may already defined at init by config.assetManager.assets = [...]
)
am.add([
{
// You can pass any custom property you want
category: 'c1',
src: 'http://placehold.it/350x250/78c5d6/fff/image1.jpg',
},
{
category: 'c1',
src: 'http://placehold.it/350x250/459ba8/fff/image2.jpg',
},
{
category: 'c2',
src: 'http://placehold.it/350x250/79c267/fff/image3.jpg',
},
// ...
]);
Now if you call the render()
, without an argument, you will see all the assets rendered
// without any argument
am.render();
am.getAll().length; // <- 3
am.getAllVisible().length; // <- 3
Ok, 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]);
In case you want to update or remove an asset, you can make use of this 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 APIs methods check out the API Reference.
# Custom select logic
WARNING
This section is referring 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 great for simple things, but except the possibility to tweak some CSS style, adding more complex things like a search input, filters, etc. requires a replace of the default UI.
All you have to do is to indicate the editor your intent to use a custom UI and then subscribe to the asset:custom
event that will give you all the information on any requested change.
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, eg. ['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 an example of using custom Asset Manager with a Vue component.
The example above is the right way if you need to replace the default UI, but as you might notice we append the mounted element to the container props.container.appendChild(this.$el);
.
This is required as the Asset Manager, by default, is placed in the Modal.
How to approach the case when your Asset Manager is a completely independent/external module (eg. should be shown in its own custom modal)? Not a problem, you can bind the Asset Manager state via assetManager.custom.open
.
const editor = grapesjs.init({
// ...
assetManager: {
// ...
custom: {
open(props) {
// `props` are the same used in `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
},
},
},
});
It's important to declare also the close
function, the editor should be able to close the Asset Manager via am.close()
.
# Events
For a complete list of available events, you can check it here.