Migrating WordPress Gutenberg to a Separate React Component: Troubleshooting Missing CSS Styles

I am in the process of developing a standalone version of the Gutenberg block editor from Wordpress that can function independently outside of the Wordpress environment. My goal is to integrate the Gutenberg editor as a React component within an existing React project.

Upon inspecting the official repository, I came across a "storybook" directory containing a React component at "storybook/stories/playground/index.js":


/**
* WordPress dependencies
*/
import "@wordpress/editor"; // This should ideally not be required

import { useEffect, useState } from "@wordpress/element";
import { BlockEditorKeyboardShortcuts, BlockEditorProvider, BlockList, BlockInspector, WritingFlow, ObserveTyping } from "@wordpress/block-editor";
import { Popover, SlotFillProvider, DropZoneProvider } from "@wordpress/components";
import { registerCoreBlocks } from "@wordpress/block-library";
import "@wordpress/format-library";

/**
* Internal dependencies
*/
import "./style.scss";

function App() {
    const [blocks, updateBlocks] = useState([]);

    useEffect(() => {
        registerCoreBlocks();
    }, []);

    return (
        <div className="playground">
            <SlotFillProvider>
                <DropZoneProvider>
                    <BlockEditorProvider
                        value={blocks}
                        onInput={updateBlocks}
                        onChange={updateBlocks}
                    >
                        <div className="playground__sidebar">
                            <BlockInspector />
                        </div>
                        <div className="editor-styles-wrapper">
                            <BlockEditorKeyboardShortcuts />
                            <WritingFlow>
                                <ObserveTyping>
                                    <BlockList />
                                </ObserveTyping>
                            </WritingFlow>
                        </div>
                        <Popover.Slot />
                    </BlockEditorProvider>
                </DropZoneProvider>
            </SlotFillProvider>
        </div>
    );
}

export default {
    title: "Playground|Block Editor"
};

export const _default = () => {
    return <App />;
};

This React component seemed like a good candidate for modification into a standalone component. I made some adjustments so it could function within a new create-react-app project:


import React from "react";
import "@wordpress/editor"; // This should ideally not be required

import { useEffect, useState } from "@wordpress/element";
import { BlockEditorKeyboardShortcuts, BlockEditorProvider, BlockList, BlockInspector, WritingFlow, ObserveTyping } from "@wordpress/block-editor";
import { Popover, SlotFillProvider, DropZoneProvider } from "@wordpress/components";
import { registerCoreBlocks } from "@wordpress/block-library";
import "@wordpress/format-library";

import "./style.scss";

export default function App() {
  const [blocks, updateBlocks] = useState([]);

  useEffect(() => {
    registerCoreBlocks();
  }, []);

  return (
    <div className="playground">
      <SlotFillProvider>
        <DropZoneProvider>
          <BlockEditorProvider value={blocks} onInput={updateBlocks} onChange={updateBlocks}>
            <div className="playground__sidebar">
              <BlockInspector />
            </div>
            <div className="editor-styles-wrapper">
              <BlockEditorKeyboardShortcuts />
              <WritingFlow>
                <ObserveTyping>
                  <BlockList />
                </ObserveTyping>
              </WritingFlow>
            </div>
            <Popover.Slot />
          </BlockEditorProvider>
        </DropZoneProvider>
      </SlotFillProvider>
    </div>
  );
}

I noticed that the component referred to a "style.scss" file (which included 'editor-styles.scss' and 'reset.scss'). Therefore, I copied these files into my new React project as well:

https://i.sstatic.net/olCoK.png

In the Gutenberg repository's "package.json" file, all the Wordpress dependencies were sourced from a "packages" directory, for instance:


"@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma",
"@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot",
"@wordpress/babel-preset-default": "file:packages/babel-preset-default",
"@wordpress/base-styles": "file:packages/base-styles",

To resolve this, I copied the "packages" folder from Gutenberg into my new React project and added all Wordpress dependencies to my "package.json" file:


// Dependencies section...

After running "npm i", my React application was able to import Wordpress packages through import statements.

However, upon launching the application with "npm start," the Gutenberg editor displayed without any CSS or styles:

https://i.sstatic.net/EJaEh.png

Despite the editor's functionality being intact, the absence of styles posed an issue. I attempted compiling the existing SCSS files using the following commands within package.json:


"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules --include-path ./packages src packages node_modules -o src --recursive --watch",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules --include-path ./packages -o src --watch"

Unfortunately, importing the resulting style.css file into my index.html did not rectify the style-related issues. Any guidance in resolving this matter would be greatly appreciated.

Answer №1

Upon further investigation, I made the surprising discovery of an additional style.scss file nestled within the confines of the storybook directory. As an experiment, I decided to transport this file to the root directory of my React application and make necessary updates to the package.json scripts:

"build-css": "node-sass-chokidar style.scss -o public/css",
"watch-css": "npm run build-css && node-sass-chokidar --include-path node_modules style.scss -o public/css --watch"

To my amazement, the styles were successfully compiled.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Autocomplete feature from the @react-google-maps/api component seems to be malfunctioning as it returns

I'm encountering some difficulties with the Autocomplete component in @react-google-maps/api. While Autocomplete is working and displaying options, clicking on an option fills the input box but I'm only getting 'undefined' from the Plac ...

I've been waiting forever for Product.find() to return some results, but it seems to

I have been encountering an issue where my code is supposed to return an empty object of a product but instead it just keeps loading forever. I have thoroughly checked through the code and explored every possible scenario where an error could be occurring, ...

How to Keep Button Highlighted After Clicking

I've experimented with various methods like using :active, :focus, adding a class, and modifying CSS rules through jQuery to maintain the button highlight, but none of them have been successful. Please take a look at my code and point out any mistakes ...

Creating an Interactive Menu System with Nested Options in Angular 2

I have a JSON structure that I need to transform into a menu with sub-menus based on the value of the sub-menu_location field. Here's an example: { "data": [ { "menu_name": "Primary Operations", "enabled": true, "sub-menu_lo ...

Utilizing Asynchronous Functions within a Loop

I have a situation where I am working with an array and need to make API calls for each index of the array. Once the API call is resolved, I need to append the result in that specific element. My goal is to ultimately return the updated array once this pro ...

Tips for updating div content when using dynamic content with EJS

I have created a blog using EJS and Node.js where the post content is stored in MongoDB as strings with HTML tags. However, when rendering the posts on the frontend, my current solution is replacing all div elements with the class of "blog_content" with th ...

What is the best method for caching inline SVG in web browsers?

Over the years, SVGs have remained popular due to their scalability. One key advantage of inline SVG is the ability to manipulate it with CSS and JS. Additionally, using the <use> tag allows for referencing the original element when repeating the sam ...

Encountering an issue while attempting to access a specific endpoint in my node.js and express application

I recently created an API Rest to allow users to register, but I'm facing an issue where I cannot access the endpoint http://localhost:5000/api/user/register/. The error message "Cannot GET /api/user/register/" keeps popping up. Here is a snippet from ...

Maximizing the efficiency of Auth middleware for specific routes in Node.js/Express

I'm currently developing a web application using Node.js and Express for the backend. I've implemented an authentication middleware to check if the user is logged in using JWT tokens. However, I want certain routes to be protected (require authen ...

The alignment of an inline unordered list is off-center

My website at this link features a sticky navigation bar. However, the list items are slightly misaligned to the left and I'm struggling to pinpoint the cause. Despite adjusting margins and padding extensively, the issue persists. It's important ...

The hover effects cease before the cursor is even shifted

Can someone explain why the hover effect stops before the mouse is moved off the element? I implemented the hover effect on a before pseudo element. ...

What is causing the React text component to fail to show changes made to my array state?

I am currently in the process of learning React Native. I have been working on an app and encountered an issue while attempting to update individual elements within an array. Here is an example of the code: function MyApp() { const [array, setArray] = ...

What is the best way to test a React component that includes a Router, Redux, and two Higher Order Components using Jest and Enzyme?

I'm currently facing a challenge with this issue. I have a React Component that is linked to React Router 4 and Redux store, and it's wrapped by two HOCs. It may sound complicated, but that's how it was implemented. Here's the export st ...

The BrowserRouter seems to be disregarding the forceRefresh property when it is assigned as a variable

Looking for a clever way to manage when my React SPA refreshes. I came across the forceRefresh prop in react-router-dom. It seems useful, but I'm facing an issue when trying to use a variable as its value. When set manually to true, everything functi ...

I'm struggling to solve a straightforward jQuery sliding issue

I am struggling to make text slide from right to left on my website. I want the text to appear only when the page loads or refreshes, and then slide off when a link is clicked, revealing new text. Can anyone help me figure this out? http://jsfiddle.net/XA ...

The server.close() method is ineffective when used in a Vow teardown

I've been working on creating some Vows-based tests for my typical Express application. Here is the code for the test: var vows = require('vows'); var assert = require('assert'); var startApp = require('./lib/start-app.js&ap ...

What is the best way to simulate callbacks on a ref for testing in a React environment?

For my React application, I am utilizing video-react plugin. In order to test a specific component that invokes ref methods from the video-react component, I aim to incorporate enzyme for mounting the component and verifying the invocation of the ref metho ...

Moving pictures using css3 transitions

Trying to create a straightforward image slider. Below is the provided JavaScript code: $(document).ready(function() { $('#slide1_images').on('click', 'img', function(){ $("#slide1_images").css("transform","translateX ...

Unable to retrieve an object using PHP

I have been encountering difficulties accessing JSON data while trying to loop through it: $request = wp_remote_get( 'https://api.riderhq.com/api/v1/3446/getevents?pretty=true' ); if( is_wp_error( $request ) ) { echo "wrong request"; ...

What is the best way to convert a Date into the JSON format before sending it to the database?

I'm currently delving into backend development with Node.js, and I am in the process of connecting my backend to a MongoDB. Specifically, I am working on creating a User object that includes Birth Date as one of its properties. However, I am strugglin ...