dark_mode

Getting Started with the Gutenberg / React Bridge

How to load and display Gutenberg content natively in React, while also applying your website styles and custom blocks in Gutenberg.


The Gutenberg editor empowers marketers to build content and layouts, but it is incompatible with React and front-end design systems. We're here to fix that!

Preparing: A website for displaying Gutenberg blocks

For this tutorial, you'll need a website. If you have that already, just skip to the next section, or follow these instructions to build a new Next.js-based test site.

cd into a directory that you like for programming, and then create a generic Next.js Typescript app like this (it will create a new sub-directory called "atlas-tester"). (Consult Next.js's documentation if you run into trouble.)

npx create-next-app --example with-typescript atlas-tester
cd atlas-tester
npm run dev # run the auto-updating development server on port 3000
open 'http://localhost:3000' # or just open this in your web browser

To edit the root page of the site, open up pages/index.tsx. In the next section, we'll be replacing this entire page.

Configuring the Gutenberg Bridge

Start by installing our npm package:

npm install @asmartbear/gutenberg-bridge

Now create (or reuse) a page for testing Gutenberg. Here is a complete example (so e.g. if you use Next.js, you can completely replace a page with this code).

import { AtlasContainer, AtlasGutenberg, StandardThemeGenerator } from '@asmartbear/gutenberg-bridge';
import '@asmartbear/gutenberg-bridge/dist/registerAll';
const Page: React.FC = () => {
const gutenbergHtml = `
<h2>Hello, World!</h2>
<p>
This is Gutenberg content without blocks, for example
if you use the Classic Editor.
</p>
`;
const themeGen = new StandardThemeGenerator();
const theme = themeGen.getTheme();
return <>
<h1>Hello Atlas</h1>
<AtlasContainer theme={theme}>
<AtlasGutenberg htmlRaw={gutenbergHtml} />
</AtlasContainer>
</>;
}
export default Page

Restart the dev server (e.g. npm run dev for Next.js) to see the results. It's not doing much yet, but let's explain the code:

import '@asmartbear/gutenberg-bridge/dist/registerAll'
This import registers all Atlas blocks. The system automatically registers Gutenberg core blocks, because without those, you can't use Gutenberg at all. However, the Atlas blocks are optional. You could register only certain ones, to keep your Javascript size to a minimum. For this tutorial, we'll just take everything. The entire module is only 25k gzipped anyway!
const themeGen = new StandardThemeGenerator()
Atlas does not dictate anything about your design system: How to use CSS, how to build themes, which libraries or systems to use. However, Atlas does need a baseline of information about your typography and color palette, so that it can style Gutenberg blocks to match your site in React, as well as style the Gutenberg Editor to match your site. This line of code uses a helper object -- a theme "generator" -- which fills lots of fields with reasonable defaults, saving you time in generating the full theme. Of course in practice you will want to tune the theme to be pixel-perfect, but this code is fine for getting started. You can also provide arguments to the constructor: The first argument is whether to use a serif font, and the second can be true to create a dark-mode theme.
<AtlasContainer theme={theme}>
Everything in Atlas must be wrapped by this container. It sets up React context required by the system. Most web frameworks have a special place to put "global wrappers" like this. (In Next.js, that place is _app.tsx, as explained here.) In this tutorial, we'll just keep it here in the page.
<AtlasGutenberg htmlRaw={gutenbergHtml} />
This component converts raw Gutenberg data into native React components, and mounts them in this location in the DOM. Here we're supplying hard-coded data for the sake of the example, but typically this would come from an API request to WordPress (which we'll do in a future section).

That was just plain HTML. To prove that this system converts full Gutenberg blocks to React components, replace the hard-coded input with the Atlas "Paper" block, with an inner Gutenberg Core "Paragraph" block:

const gutenbergHtml = `
<!-- wp:atlas-material/paper {"elevation":8,"rounded":true,"rotation":"-2"} -->
<div class="atlas-paper"><!-- wp:paragraph -->
<p>This is demonstrating one of the Atlas components,
sourced from Gutenberg data.</p>
<!-- /wp:paragraph --></div><!-- /wp:atlas-material/paper -->
<!-- wp:paragraph --><p></p><!-- /wp:paragraph -->
`;

When you run this, you'll discover that, while it mostly works, some CSS styles appear to be missing. You can tell, because here is how this renders in our example app:

[image]

But here is how it renders in the Gutenberg editor:

[image]

So, we need to add CSS styles. There are a few global stylesheets to add. They're bundled with the npm package, so you already have them. The trick is, every React application framework has a different way of including global stylesheets! So, you'll have to use whatever technique is appropriate for your system.

For example, if you're using Next.js, global stylesheets are imported in pages/_app.tsx. Here's a full example you can use if you're following along with the app from above:

// Atlas CSS, detailed below.
import '@asmartbear/gutenberg-bridge/dist/css/full.css';
import '@asmartbear/gutenberg-bridge/dist/css/core-blocks.css';
import '@asmartbear/gutenberg-bridge/dist/css/atlas-blocks.css';
import '@asmartbear/gutenberg-bridge/dist/css/atlas-material-blocks.css';
// Everything from here-down is Next.js stuff, not Atlas stuff.
import React from 'react';
import Head from 'next/head';
interface AppProps {
Component: any;
pageProps: any;
};
export default function App({ Component, pageProps }: AppProps): JSX.Element {
return (
<React.Fragment>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</Head>
<Component {...pageProps} />
</React.Fragment>
);
}

Not all of these stylesheets are required. Here's what they do:

full.css
This is only for people who don't have a design system at all. This takes over your entire stylesheet, applying the Atlas Theme to the entire site. Don't use this if you're already styling your site in another way!
core-blocks.css
Styles for the WordPress Gutenberg core blocks. You'll need this for the basic built-in blocks that come with Gutenberg.
atlas-blocks.css
Styles for all of the core Atlas blocks.
atlas-material-blocks.css
Styles for extra Atlas blocks that implement a subset of Google's Material Design philosophy. Omit if you're not using these blocks.

With stylesheets in place, the blocks are rendering correctly:

[image]

Sourcing data from WordPress

Now that we can display arbitrary Gutenberg blocks, we need to grab that data from WordPress.

You can use either the WordPress REST API or WP GraphQL. The key piece of data you need from a page or a post is called the "raw content." This is different from the "content," a.k.a. the rendered content. Only the raw content contains the Gutenberg block data.

Both the REST API and WP GraphQL require authentication in order to query the raw content. You can use any type of WordPress authentication to do this. If you want something simple and already built into Core, just use a user account (possibly creating one specifically for this purpose) and generate an "Application Password," which you can do at the bottom of your User Profile page (where you edit your name and avatar). You can then authenticate with WordPress using that username, and that generated application password.

Note for WP GraphQL users: The way you get raw content is by specifying the "raw" format parameter to post content. Here's a simple example:

query MyQuery {
pageBy(uri: "/my-page") {
title
content(format: RAW)
}
}

Configuring the Theme

The Atlas Theme System provides a variety of tools for encoding typefaces (including support for Google Fonts), type sizing and spacing, color palettes, layout grids, and viewport width breakpoints. Getting this to match your website theme (or just building your theme using our system directly!), creates an integrated WYSIWYG experience in the Gutenberg editor, where marketers and content authors are "locked down" to the specific options of your site design, while still supporting great features like automated "dark mode."

The StandardThemeGenerator object from our example is a good place to start. Everything is documented and Typescript-safe, so it's easiest to just look through your options there and play with settings.

Here's an example of some things you can do with the generator:

const themeGen = new StandardThemeGenerator();
themeGen.baseFontScale = 1.2; // increase all font sizes by 20%
themeGen.baseHeadingWeight = 600; // CSS weight for headings
themeGen.baseTypefaces.unshift("Roboto Slab"); // Insert a preferred font
themeGen.googleFontFamilies.push("Roboto Slab"); // Load font from Google
themeGen.addBrandColor("tiffany", "#0ecad4"); // Named brand colors
themeGen.addBrandColor("mirage", "#002838");
themeGen.addBrandColor("seafoam", "#50e3c2");
themeGen.addBrandColor("royal", "#7e5cef");
themeGen.addBrandColor("sunset", "#ff6c29");
const theme = themeGen.getTheme();

After generating the theme object, there are even more settings you can tweak! Everything from letter-spacing in headings to named font pre-sets to auto-scaling fonts for narrow devices.

The more you add to the font typefaces, the presets, and the palette colors, the more you will also be empowering marketers, because all of that appears in the WordPress Gutenberg editor, and automatically supports "dark mode."

Creating the WordPress theme for blocks and styles

To get the Atlas blocks, plus your custom blocks, plus your website's styles, all appearing in the Gutenberg Editor, you'll need your own, specially-built theme for WordPress. Atlas will create that for you.

First, install the utility that builds the WordPress theme. This is packaged separately from the run-time library. You can install it into your project as a development dependency, or install it globally:

npm install --global @asmartbear/gutenberg-bridge-theme-builder

Next, create a JSON configuration file containg all your custom theme data (which you've tweaked with code), as well as information about the Gutenberg blocks which are supported in React (including your custom blocks, which we haven't created yet). Because this configuration is established from code, you'll need to export it from the running website.

A simple way to do this in development is to use a special React component Atlas supplies for this purpose:

import CopyBlockConfig from '@asmartbear/gutenberg-bridge/dist/react-util/CopyBlockConfig'
...
return <>
<h1>Hello Atlas</h1>
<AtlasContainer theme={theme}>
<AtlasGutenberg htmlRaw={gutenbergHtml} />
<CopyBlockConfig /> {/* <-- right here */}
</AtlasContainer>
</>;

The component looks like this:

[image]

Just click on the text box and the content is copied to the clipboard. Place that content in a file wherever is convenient; for the tutorial, we'll put it in a file named atlas-block-config.json in the root of the project.

Next, edit package.json to add two things: A script that builds the WordPress theme, and configuration commands to the theme-builder utility. Add the script and below it (often just before the end of the file), this other configuration:

{
"scripts": {
...
"wp-theme": "sh node_modules/@asmartbear/gutenberg-bridge-theme-builder/build-wp-theme.sh"
},
...
"atlas": {
"config-json": "./atlas-block-config.json",
"theme-dest": "./wp-theme",
"block-css-output-file": "css/block.css",
"block-dirs": [
"node_modules/@asmartbear/gutenberg-bridge/dist"
]
}
}

Here's what that configuration means:

.../build-wp-theme.sh
The build script. In this example, the module has been installed inside the project. If you installed it globally, this will look something like /usr/local/lib/node_modules/@asmartbear/gutenberg-bridge-theme-builder/build-wp-theme.sh.
"config-json"
Points to that theme-and-block configuration file we just exported.
"theme-dest"
Destination directory for generating the WordPress theme. Here we're using a directory in the root of the project, but it can be anywhere, even outside of the project directory.
"block-css-output-file"
Destination for generating a single, merged, block-specific CSS file. Any block can have custom CSS (actually, SCSS!), which the builder tool compiles both for Gutenberg and for the front-end. The Gutenberg CSS is bundled into the WordPress theme, but the front-end CSS needs to be included in the app by the front-end developer. Use this configuration option to set the location for that front-end CSS. Parent directories are created if they don't already exist.
"block-dirs"
An array of paths to scan recursively for Atlas block implementations. This configuration is necessary because the tool has to actually compile Typescript/Javascript, and build CSS styles from code on disk. It will even bundle custom application code and modules for use inside Gutenberg! Here we're supplying the path to the Atlas blocks that come with the core package. When you use other packages, you'd list their paths here, and if your project has custom blocks of its own, those paths would be listed too.

Finally, we can generate the theme!

npm run wp-theme

Note that it generated both a directory called wp-theme/ as well as a ZIP file called wp-theme-vX.X.X.zip. Both should be excluded from git using the pattern wp-theme* as a line inside .gitignore.

You can install this theme in any of the usual ways, including from wp-cli or from the web interface. For the latter, go to the menu "Appearence > Themes", then click the "Add New" button at the top, then click the "Upload Theme" button at the top, and supply the ZIP file. Finally, activate the theme by clicking the "Activate" button in the list of themes.

That's it! The Gutenberg editor will have all the Atlas blocks, and your website's theme.

Now that you're generating the theme yourself, you should use your own, generated CSS for blocks instead of the CSS that is bundled with the core npm package. This is because the Atlas blocks are included in the generated CSS, and any custom blocks you create will also be included. To do this, just include the generated CSS instead of the built-ins. Using the earlier example, and assuming the package.json configuration from our example above, the CSS includes would become:

import '@asmartbear/gutenberg-bridge/dist/css/full.css';
import '@asmartbear/gutenberg-bridge/dist/css/core-blocks.css';
import '../css/block.css';

Now that you have the bridge working, let's take a look at the Atlas blocks that are already at your disposal, both in React and in Gutenberg.

  • Getting Started with the Gutenberg / React Bridge
    Display blocks from Gutenberg, and creating a WordPress Theme for WYSIWYG editing inside Gutenberg.
  • Atlas Blocks
    The built-in Atlas blocks, in React and in Gutenberg.
  • Atlas Layouts
    Custom Layout blocks: Layouts with controls
  • Atlas Custom Blocks
    How to create new React components that automatically generate Storybook documentation and rich, composable Gutenberg blocks.
  • Atlas Slabs
    Mocking up and filling sections within a React page, using sections within Gutenberg.
  • Atlas Theming
    A complete system of color, typopgraphy, and layout, supporting dark mode, Gutenberg, and Storybook
  • Storybook Integration
    How to automate Storybook stories for everything - custom, WordPress Core, and Atlas blocks.
  • Storybook Reference
    Storybook-based interactive documentation for Atlas Core and Gutenberg Core blocks.