How to create and use a separate CSS file for Gutenberg editor in Sage 9

Hey,

First pass at this so open to review, but this might be of interest to anyone edging closer to using Gutenberg in Production.

With TinyMCE you could push your entire CSS file to the editor to adopt your theme’s styles but that won’t work in Gutenberg. Instead you’ll need to create and import another seperate CSS file with just the styles specific to the editor.

(Also there may be a better way to do this that doesn’t involve keeping two seperate top-level SCSS files going? You tell me.)


So here’s how to load your theme’s styles into the Gutenberg editor in Sage 9.

  1. Edit config.json to include another top-level CSS file, something like:
"gutenberg": ["./styles/gutenberg.scss"],
  1. Duplicate your main.scss file and call it gutenberg.scss. In here remove anything that’s not related to the editor. Like your grid layout, etc. Most likely just your variables, global styles and wp-classes.scss file.
  2. Run yarn run build to create both main.css and gutenberg.css files.
  3. Add an action to one of your functions files (eg setup.php) to enqueue the right file and load it when the Gutenberg editor loads.
add_action('enqueue_block_editor_assets', function () {
     wp_enqueue_style('sage/gutenberg.css', asset_path('styles/gutenberg.css'), false, null);
});
  1. That’s it! You should now see the same styles in the backend editor as you see on the front page.

You will need to run a build each time you want to update the gutenberg.css file. But personally I’ve gotten in the habit of keeping a terminal window open just to regularly update the current build since using Sage 9.

Suggestions? Problems? Improvements? Go for it.

11 Likes

Cool.

Only thing I’d change is rolling with an anonymous function instead to keep things uniform with the code style of Sage’s existing setup.php.

add_action('enqueue_block_editor_assets', function () {
     wp_enqueue_style('sage/gutenberg.css', asset_path('styles/gutenberg.css'), false, null);
});
2 Likes

Good stuff. You saved me a lot of time there.

I was going to ask if you have any ideas on how to get browsersync to utilise the new gutenberg.css styles but then i found this quote by a roots leader:

Editing site content while running yarn start is not the intended workflow. We recommend editing site content, and developing the site theme, separately.

Thanks again.

1 Like

I only would like to mention in here (might be some time saver for someone until Sage 10 will be released) that if someone is trying to make custom Gutenberg editor styles work in WP admin, just following this oficial WP codex guide and adding following lines

add_theme_support( 'editor-styles' );
add_editor_style( asset_path('styles/your-gutenberg-editor-styles.css') );

in after_setup_theme action does not work with Sage 9. On the other hand @Simeon solution does fix it indeed. I was bit sceptical at the beginning as this solution here is a bit older and no search results on this topic were pointing to enqueue_block_editor_assets action hook. My fault I did not try it since the beginning, just give it a try it might save you some time researching.

Good luck!

1 Like

This works for the most part but does any one know how to get this working with BrowserSync?

The editor styles for Gutenberg are downloaded on server-side via HTTP (usually maps to localhost, so it should be fast), parsed on the client side, body remapped to the styles wrapper and then injected into the page. So stock browsersync couldn’t really do anything here.
As Gutenberg is based on React components, Hot Reloading comes to mind, but then the current component style system would have to be rewritten.
Related, but closed issue:

1 Like

Gotcha. Thanks for explaining.

I have to revise my post a bit as I found this PostCSS plugin and thought about the setup:

So you could actually use browsersync to inject the editor stylesheet by browsersync and make the PostCSS plugin wrap the styles for you. You have to ensure that these injected styles are not overriden by the old auto-injected styles by Gutenberg itself. But doing it this way should be possible.

The “right” way IMHO would be still React Hot Reloading (and Gutenberg in its current implementation is based on React).

How would you include the JS file? I tried this, but no go. No errors – WP just doesn’t see it.

// setup.php
function sage_gutenberg_blocks() {
    wp_register_script( 'custom-cta-js', asset_path('scripts/blocks/custom-cta.js'), array( 'wp-blocks' ) );

    register_block_type( 'sage/custom-cta', array(
        'editor_script' => 'custom-cta-js'
            ) );
}
add_action('init', 'sage_gutenberg_blocks');
// custom-cta.js 
const { registerBlockType } = wp.blocks;

registerBlockType('sage/custom-cta', {

  title: 'Call to Action',
  description: 'CTA block',
  icon: 'format-image',
  category: 'layout',

  attributes: {},


});

You can configure your sage (9 here) setup to build a separate editor.js (webpack, babel, and so on support). Check out the resources/assets/config.json.
You need to use a specific action hook to enqueue the editor JavaScript and Style files:

/**
 * Gutenberg scripts and styles
 * @see https://www.billerickson.net/block-styles-in-gutenberg/
 */
function gutenberg_scripts() {
    wp_enqueue_script(
        'editor-theme',
        asset_path('scripts/editor.js'),
        array( 'wp-blocks', 'wp-dom', 'wp-i18n' ), // what is used in the editor script, e.g. Blocks, DOM, i18n (`__(...)`)
        false,
        true
    );

    wp_enqueue_style(
        'editor-theme',
        asset_path('styles/editor.css'),
        false,
        true
    );
}
add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\gutenberg_scripts' );
2 Likes

@strarsis Thanks so much, that did it!

This isn’t exactly working today inside the editor. I have to add !important tags to all my styles to override gutenberg’s own. Is there anyway to have my styles follow after?

I tried this too:

add_action('enqueue_block_editor_assets', function () {
    wp_enqueue_style('sage/editor-style.css', asset_path('styles/editor-style.css'), false, null);
}, 100);

So is this caused by the styles ordering? Are the theme editor styles wrapped correctly?
You can always boost the specificity globally by using e.g. another SCSS wrapper (e.g. html) or a PostCSS plugin.

wp_enqueue_style() allows to to define an array of dependencies (defined through the handles for those styles), which will ensure that your style link is printed out after any of its dependencies. If you set the editor styles (I don’t know what the handle is–potentially wp-block-directory-css? You’d need to find that) as a dependency, it should print your styles after those.

Although https://sage-gateway.local/wp-admin/load-styles.php loads before my editor-style.css, it’s still having precedence. Even if I add body in front of my style.

Thanks, that makes sense. I think in my case it might be array('wp-editor') since it’s the post/page title.