Skip to main content
DocsHow-To GuidesRendering Blocks

Rendering Blocks

In headless WordPress with Faust.js, the template router offers a powerful way to dynamically map WordPress pages and posts to specific templates, streamlining how content is fetched and rendered. When working with WordPress block data, the template router allows you to efficiently map block types to React components, giving you greater control over how individual blocks are rendered within each template.

This guide walks you through rendering native WordPress core blocks using the template router.

0. Basic Setup

If you don't already have a working Faust.js site, follow the Basic Setup to get Faust.js set up.

1. Setup WPGraphQL Content Blocks Plugin

A. Download the WPGraphQL Content Blocks Plugin

To set up the WPGraphQL Content Blocks plugin on the WP backend. Head over to the GitHub repo and download the latest version of the wp-graphql-content-blocks plugin from the releases tab.

B. Upload the Plugin

Upload the plugins .zip file to your WordPress site via the plugins page or unzip and copy the file contents into your WordPress wp-content/plugins folder manually.

C. Activate the plugin

Activate the plugin on the WordPress plugins page.

2. Render Blocks from the @faust/blocks package

The @faust/blocks package contains a small reference list of core blocks that you can use in your site.

Tip

These blocks are provided as a quick start option and reference. Blocks can be overridden and custom blocks added to fit your site's needs.

A. Install the @faust/blocks package

npm install @faustwp/blocks

B. Import Block Components

To use them, you need to import the relevant blocks into your wp-blocks/index.js block list:

wp-blocks/index.js
import { CoreBlocks } from "@faustwp/blocks";
 
export default {
	...CoreBlocks,
};

C. Update the _app.js file

Next, we update the _app.js file like so:

pages/_app.js
import { useRouter } from "next/router";
import "../faust.config";
import { FaustProvider } from "@faustwp/core";
import "@/styles/blocks.scss";
import { WordPressBlocksProvider, fromThemeJson } from "@faustwp/blocks";
import blocks from "../wp-blocks";
 
export default function MyApp({ Component, pageProps }) {
	const router = useRouter();
 
	return (
		<FaustProvider pageProps={pageProps}>
			<WordPressBlocksProvider
				config={{
					blocks,
				}}
			>
				<Component {...pageProps} key={router.asPath} />
			</WordPressBlocksProvider>
		</FaustProvider>
	);
}

Here, we import our custom blocks from the wp-blocks module, which contains all the block components tailored for our WordPress content. These imported blocks are then passed into the WordPressBlocksProvider as part of its configuration.

The provider uses this mapping to dynamically render the appropriate block components based on the data coming from WordPress.

D. Import Fragments

Then in your template queries, you will need to pass the provided fragment entries. here's an example of how to do that using the front-page template:

wp-templates/front-page.js
import blocks from "../wp-blocks";
 
Component.query = gql`
  ${blocks.CoreParagraph.fragments.entry}
  ${blocks.CoreColumns.fragments.entry}
  ${blocks.CoreColumn.fragments.entry}
  ${blocks.CoreCode.fragments.entry}
  ${blocks.CoreButtons.fragments.entry}
  ${blocks.CoreButton.fragments.entry}
  ${blocks.CoreQuote.fragments.entry}
  ${blocks.CoreImage.fragments.entry}
  ${blocks.CoreSeparator.fragments.entry}
  ${blocks.CoreList.fragments.entry}
  ${blocks.CoreHeading.fragments.entry}
  query GetPage(
    $databaseId: ID!
    $asPreview: Boolean = false
  ) {
    page(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {
      title
      content
      editorBlocks {
        name
        __typename
        renderedHtml
        id: clientId
        parentId: parentClientId
        ...${blocks.CoreParagraph.fragments.key}
        ...${blocks.CoreColumns.fragments.key}
        ...${blocks.CoreColumn.fragments.key}
        ...${blocks.CoreCode.fragments.key}
        ...${blocks.CoreButtons.fragments.key}
        ...${blocks.CoreButton.fragments.key}
        ...${blocks.CoreQuote.fragments.key}
        ...${blocks.CoreImage.fragments.key}
        ...${blocks.CoreSeparator.fragments.key}
        ...${blocks.CoreList.fragments.key}
        ...${blocks.CoreHeading.fragments.key}
      }
    }
  }
`;

E. Rendering Blocks

Now that you have all the queries ready, you can render the blocks using the provided flatListToHierarchical method and WordPressBlocksViewer:

wp-templates/front-page.js
import { gql } from "@apollo/client";
import { flatListToHierarchical } from "@faustwp/core";
import { WordPressBlocksViewer } from "@faustwp/blocks";
import blocks from "../wp-blocks";
 
export default function Component({ loading, data }) {
	// Loading state for previews.
	if (loading) {
		return <>Loading...</>;
	}
 
	const { title, editorBlocks } = data?.page ?? { title: "" };
	const blockList = flatListToHierarchical(editorBlocks, {
		childrenKey: "innerBlocks",
	});
 
	return (
		<div className="is-layout-constrained">
			<h1>{title}</h1>
			<WordPressBlocksViewer blocks={blockList} />
		</div>
	);
}

3. All done!

run npm run dev and navigate to your front page to see the blocks rendered! For Further customization, you can create custom blocks.