Skip to content

Block editor cannot be rendered in a server-side context #49288

Open
@mrmurphy

Description

Description

When I try to import modules from various block-related gutenberg components in non-standard browser environments, I get a bundle failure because the window object is not defined. Ideally, I'd like to pre-render block-editor content on the server. Minimally, I'd like to be able to have imports from block-editor related files without breaking my bundler.

Here's a list of patches that I found in my experimentation that contain possible fixes:

@wordpress/block-editor

diff --git a/node_modules/@wordpress/block-editor/build/components/block-toolbar/utils.js b/node_modules/@wordpress/block-editor/build/components/block-toolbar/utils.js
index ff21367..be3b5e5 100644
--- a/node_modules/@wordpress/block-editor/build/components/block-toolbar/utils.js
+++ b/node_modules/@wordpress/block-editor/build/components/block-toolbar/utils.js
@@ -14,7 +14,7 @@ var _element = require("@wordpress/element");
 const {
   clearTimeout,
   setTimeout
-} = window;
+} = globalThis;
 
 const noop = () => {};
 
diff --git a/node_modules/@wordpress/block-editor/build/components/typewriter/index.js b/node_modules/@wordpress/block-editor/build/components/typewriter/index.js
index 826c512..35be029 100644
--- a/node_modules/@wordpress/block-editor/build/components/typewriter/index.js
+++ b/node_modules/@wordpress/block-editor/build/components/typewriter/index.js
@@ -25,7 +25,10 @@ var _store = require("../../store");
 /**
  * Internal dependencies
  */
-const isIE = window.navigator.userAgent.indexOf('Trident') !== -1;
+let isIE = false;
+if (typeof window !== 'undefined') {
+  isIE = window.navigator.userAgent.indexOf('Trident') !== -1;
+}
 const arrowKeyCodes = new Set([_keycodes.UP, _keycodes.DOWN, _keycodes.LEFT, _keycodes.RIGHT]);
 const initialTriggerPercentage = 0.75;

@wordpress/blocks

diff --git a/node_modules/@wordpress/blocks/build/api/raw-handling/image-corrector.js b/node_modules/@wordpress/blocks/build/api/raw-handling/image-corrector.js
index 77df21e..2d64494 100644
--- a/node_modules/@wordpress/blocks/build/api/raw-handling/image-corrector.js
+++ b/node_modules/@wordpress/blocks/build/api/raw-handling/image-corrector.js
@@ -17,7 +17,7 @@ var _blob = require("@wordpress/blob");
 const {
   atob,
   File
-} = window;
+} = globalThis;
 
 function imageCorrector(node) {
   if (node.nodeName !== 'IMG') {
diff --git a/node_modules/@wordpress/blocks/build/api/raw-handling/ms-list-converter.js b/node_modules/@wordpress/blocks/build/api/raw-handling/ms-list-converter.js
index 59b270a..39242a9 100644
--- a/node_modules/@wordpress/blocks/build/api/raw-handling/ms-list-converter.js
+++ b/node_modules/@wordpress/blocks/build/api/raw-handling/ms-list-converter.js
@@ -8,9 +8,9 @@ exports.default = msListConverter;
 /**
  * Browser dependencies
  */
-const {
+let {
   parseInt
-} = window;
+} = globalThis;
 
 function isList(node) {
   return node.nodeName === 'OL' || node.nodeName === 'UL';
diff --git a/node_modules/@wordpress/blocks/build/api/raw-handling/paste-handler.js b/node_modules/@wordpress/blocks/build/api/raw-handling/paste-handler.js
index 75ac1f0..1622366 100644
--- a/node_modules/@wordpress/blocks/build/api/raw-handling/paste-handler.js
+++ b/node_modules/@wordpress/blocks/build/api/raw-handling/paste-handler.js
@@ -72,7 +72,7 @@ var _slackParagraphCorrector = _interopRequireDefault(require("./slack-paragraph
  */
 const {
   console
-} = window;
+} = globalThis;
 /**
  * Filters HTML to only contain phrasing content.
  *
diff --git a/node_modules/@wordpress/blocks/build/store/actions.js b/node_modules/@wordpress/blocks/build/store/actions.js
index ebbcc4b..af7f52a 100644
--- a/node_modules/@wordpress/blocks/build/store/actions.js
+++ b/node_modules/@wordpress/blocks/build/store/actions.js
@@ -51,7 +51,7 @@ var _constants = require("../api/constants");
 const {
   error,
   warn
-} = window.console;
+} = globalThis.console;
 /**
  * Mapping of legacy category slugs to their latest normal values, used to
  * accommodate updates of the default set of block categories.

I'm not sure those are the only places, because I'm running into plenty of other problems from my own code 😄 , but I know at least those are problematic.

This isn't only a problem for SSR, but for Web Workers as well. We currently have to be careful not to import any files that import block-related code into our worker process, or we'll get a runtime error there on initial load.

Step-by-step reproduction instructions

Try to set up a basic block editor in Next.js, or write code in a web worker that uses functions from the @wordpress/blocks library, specifically these imports are an example of what we're using:

import {
  BlockInstance,
  createBlock,
  findTransform,
  getBlockAttributes,
  getBlockTransforms,
} from "@wordpress/blocks";

Screenshots, screen recording, code snippet

No response

Environment info

    "@wordpress/blocks": "12.5.0",
    "@wordpress/block-editor": "11.5.0",
    ...

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

Metadata

Assignees

No one assigned

    Labels

    [Feature] ExtensibilityThe ability to extend blocks or the editing experience[Type] DiscussionFor issues that are high-level and not yet ready to implement.npm PackagesRelated to npm packages

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions