Body -> Decorations -> Background-image
As a workaround for body background I use the following actions:save body background to DB separately from components and styles, via editor.DomComponents.getWrapper().attributes.stylewhen template is loaded set the style via editor.DomComponents.getWrapper().setStyle(/set proper styles/)clear canvas with editor.DomCo...
Read full answer below ↓Question
Version 0.14.25 | Local copy GrapesJS Tested in: Chrome 68, Firefox 61
Add a background image in "Body (Selected #wrapper) -> Decorations -> Background -> Layer # -> Image", save to db, refresh page, load from db, blank background. Same with image or color.
Adding background

After refresh page

and, how can add a background image gif or video? need to pull a request?
Thanks.
Answers (3)
As a workaround for body background I use the following actions:
- save body background to DB separately from components and styles, via
editor.DomComponents.getWrapper().attributes.style - when template is loaded set the style via
editor.DomComponents.getWrapper().setStyle(/*set proper styles*/) - clear canvas with
editor.DomComponents.getWrapper().setStyle(''), but this doesn't clear background from traits
I need to know what do you store in DB and how do you load it.
Hi, this is the code.
<div id="builder"></div>
<script type="text/javascript">
var token = "{{ csrf_token() }}";
var editor = grapesjs.init({
fromElement: 1,
clearOnRender: true,
container: '#builder',
plugins: ['gjs-preset-newsletter', 'gjs-blocks-basic', 'gjs-blocks-flexbox'],
pluginsOpts: {
'gjs-blocks-basic': { category: false },
},
storageManager: {
autosave: false,
setStepsBeforeSave: 1,
type: 'remote',
urlStore: '/dashboard/pages/builder/' + {{ $page->id }},
urlLoad: '/dashboard/pages/builder/' + {{ $page->id }} + '/load',
contentTypeJson: true,
params: { _token:token },
},
assetManager: {
assets: {!! !empty($page->builder['gjs-assets']) ? $page->builder['gjs-assets'] : '[]' !!},
storeOnChange : true,
storeAfterUpload : true,
upload: '/dashboard/pages/builder/' + {{ $page->id }} + '/postimages',
uploadName: 'images',
params: { _token:token, enctype:'multipart/form-data' },
autoAdd: 1,
},
});
var assets = editor.AssetManager.getAll();
assets.on('remove', function(asset) {
var removefile = asset.get('src').split('/').reverse()[0];
$.ajax({
url: '/dashboard/pages/builder/' + {{ $page->id }} + '/postimages',
type: 'POST',
data: { file:removefile, _token:token },
success: function(response){
assets.remove(asset.get('src'));
}
});
});
editor.Panels.addButton
('options',
[{
id: 'save-db',
className: 'fa fa-floppy-o',
command: 'save-db',
attributes: {title: 'Save'}
}]
);
editor.Commands.add
('save-db',
{
run: function(editor, sender)
{
sender && sender.set('active');
editor.store();
}
});
editor.Panels.removeButton("options", ["export-template", "gjs-toggle-images", "gjs-open-import-template"]);
editor.on('storage:load', function(e) {
console.log('Loaded ', e);
});
editor.on('storage:store', function(e) {
console.log('Stored ', e);
});
var btnClass = editor.Panels.addButton
('options',
[{
id: 'add-class',
className: 'fa fa-plus',
command: 'add-class',
attributes: {title: 'Add Clicker Zone'}
}]
);
var cmdClass = editor.Commands.add
('add-class',
{
run: function(editor, sender)
{
var componentModel = editor.getSelected();
componentModel.addClass('open-box');
sender && sender.set('active', true);
},
stop: function(editor, sender)
{
var componentModel = editor.getSelected();
componentModel.removeClass('open-box');
sender && sender.set('active', false);
}
}
);
</script>
This is the php code: store
public function builderPost(Page $page, Request $request)
{
if (!empty($page->exists) AND Gate::allows('page-access', $page)) {
$page->builder = json_encode($request->except('_token'));
$page->save();
return ['status' => 'success', 'message' => 'Your Page was successfully saved!'];
}
Session::flash('flashSession', ['status' => 'danger', 'message' => 'Error, you cannot build this Page!']);
return redirect('dashboard/pages');
}
for load
public function builderLoad(Page $page)
{
if (!empty($page->exists) AND Gate::allows('page-access', $page)) {
return json_decode($page->builder, true);
}
Session::flash('flashSession', ['status' => 'danger', 'message' => 'Error, you cannot build this Page!']);
return redirect('dashboard/pages');
}
Thanks.
Related Questions and Answers
Continue research with similar issue discussions.
Issue #4174
Refresh page we will lost body/wrapper background color
GrapesJS version [X] I confirm to use the latest version of GrapesJS What browser are you using? Chrome 98.0.4758.109 Reproducible demo lin...
Issue #2044
Npm start to develop on local server didn't work
Did the procedure to start the local server using dev branch as described on README, it worked on the console, but fails on chrome and the...
Issue #373
Color input does not update the element on page
when using the color picker everything works fine. however if you add a hex value to the input and press enter the color preview updates bu...
Issue #1812
[Bug]: 404 when trying to add background image (reproducible in demo)
Visit https://grapesjs.com/demo.html in Chrome IncognitoClick the "Header" elementClick Decorations > BackgroundDelete Layer 2Click Layer 1...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.
Browse free plugins →Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.
Browse premium plugins →Related tutorials
In-depth guides on the same topic.
Tutorial
How to Build a Production GrapesJS Editor: The Complete Walkthrough of Brief, Preset, Plugins, and Services
A complete walkthrough of building a production GrapesJS editor: how to choose a preset, pick plugins, and scope setup services without burning a sprint.
Tutorial
GrapesJS Inline RTE Plugins Update: CKEditor 5 v0.1.4 and Froala Inline Text Editor
CKEditor 5 Inline for GrapesJS v0.1.4 fixes Studio SDK toolbar clipping, iframe injection and link balloon bugs. Compare with Froala Inline — both $69.
Tutorial
Embed GrapesJS in Your SaaS: A Weekend Guide
Embed GrapesJS in your SaaS and ship a white-label page builder over a weekend. Honest tradeoffs, real code, and the plugins that close the UX gap.
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.