GrapesJS/grapesjs · error
'container' is required
Error message
'container' is required
What it means
`grapesjs.init()` requires a `container` option identifying the DOM element(s) where the editor will render, unless the editor runs in `headless` mode. Without a container and headless off, there is nowhere to mount the canvas, so init throws immediately.
Source
Thrown at packages/core/src/index.ts:49
* Initialize the editor with passed options
* @param {Object} config Configuration object
* @param {string|HTMLElement} config.container Selector which indicates where render the editor
* @param {Boolean} [config.autorender=true] If true, auto-render the content
* @param {Array} [config.plugins=[]] Array of plugins to execute on start
* @param {Object} [config.pluginsOpts={}] Custom options for plugins
* @param {Boolean} [config.headless=false] Init headless editor
* @return {Editor} Editor instance
* @example
* var editor = grapesjs.init({
* container: '#myeditor',
* components: '<article class="hello">Hello world</article>',
* style: '.hello{color: red}',
* })
*/
init(config: EditorConfig = {}) {
const { headless } = config;
const els = config.container;
if (!els && !headless) throw new Error("'container' is required");
const initConfig: InitEditorConfig = {
autorender: true,
plugins: [],
pluginsOpts: {},
...config,
grapesjs: this,
el: headless ? undefined : isElement(els) ? els : (document.querySelector(els!) as HTMLElement),
};
const editor = new Editor(initConfig, { $ });
const em = editor.getModel();
em.initModules();
// Load plugins
initConfig.plugins?.forEach((pluginInput) => editor.Plugins.add(pluginInput as PluginInput));
// Execute `onLoad` on modules once all plugins are initialized.
// A plugin might have extended/added some custom type so this
// is a good point to load stuff like components, css rules, etc.View on GitHub (pinned to 2bdeda85b8)
Solutions
- Pass `container: '#editor'` (selector or HTMLElement) in the config.
- Set `headless: true` if you only need the editor's data model without rendering.
- Ensure the mount element exists in the DOM before calling init.
Example fix
// before
const editor = grapesjs.init({});
// after
const editor = grapesjs.init({ container: '#gjs' }); Defensive patterns
Strategy: validation
Validate before calling
const mountEl = document.querySelector('#gjs');
if (!mountEl) throw new Error('Mount element #gjs not found');
const editor = grapesjs.init({ container: mountEl }); Type guard
function canInit(config) {
return Boolean(config && (config.headless || config.container));
} Try / catch
try {
const editor = grapesjs.init(config);
} catch (err) {
if (err.message === "'container' is required") {
console.error('Pass container: "#id" or set headless: true');
} else throw err;
} Prevention
- Always pass container (selector or HTMLElement) in init config
- Ensure the mount node exists in the DOM before init
- Use headless:true only when you intentionally skip rendering
- Watch for typos: the option key is exactly `container`
When it happens
Trigger: Calling `grapesjs.init({})` or `grapesjs.init(config)` without `container` and without `headless: true`; passing a selector string that resolves at init time is fine, but omitting the key entirely throws.
Common situations: Typos like `containers` or `el` instead of `container`; calling init before the DOM element exists; SPA rendering where the mount node isn't in the document yet; copying headless examples into regular mode.
Related errors
- Target option is required
- Cannot modify immutable record
- Cannot remove immutable record
- Failed to send telemetry data ${await response.text()}
- Parser code "${parserCode}" not found
AI-assisted analysis of GrapesJS/grapesjs@2bdeda85b8 (2026-08-30).
Data as JSON: /api/errors/9a53a304632e658e.
Report an issue: GitHub.