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

  1. Pass `container: '#editor'` (selector or HTMLElement) in the config.
  2. Set `headless: true` if you only need the editor's data model without rendering.
  3. 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

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


AI-assisted analysis of GrapesJS/grapesjs@2bdeda85b8 (2026-08-30). Data as JSON: /api/errors/9a53a304632e658e. Report an issue: GitHub.