Creating a BlockRenderer component
Note: The example below assumes you have a paragraph block added to the homepage in WordPress.
Creating a <BlockRenderer />
component is the recommended way to render WordPress block data within your Astro project. We can use the .map
render function from the previous section and replace it with a new <BlockRenderer />
component. We can also import the BlockRenderer
into itself as a BlockRendererInner
component to render any innerBlocks
belonging to a particular block. First create a <BlockRenderer />
component:
// src/components/BlockRenderer.astro
---
import BlockRendererInner from "./BlockRenderer.astro";
import type { Block } from "@wp-block-tools/styles";
import { getBlockStyling } from "@wp-block-tools/styles";
type Props = {
blocks: Block[]
};
const { blocks } = Astro.props;
---
{blocks.map((block) => {
const { styles, classes } = getBlockStyling(block);
switch(block.name){
case "core/template-part":
return <BlockRendererInner blocks={block.innerBlocks} />;
case "core/post-content":
return (
<div class={classes} style={styles}>
<BlockRendererInner blocks={block.innerBlocks} />
</div>
);
case "core/paragraph":
return <p set:html={block.attributes?.content} class={classes} style={styles} />
default:
return null;
}
})}
Then update the index page:
// src/pages/index.astro
---
import { BlockRenderer } from "../components/BlockRenderer.astro";
import { getBlockStyling } from "@wp-block-tools/styles";
import type { Block } from "@wp-block-tools/styles";
const response = await fetch(`${import.meta.env.WPGRAPHQL_URL}`, {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({
query: `
query PageData {
cssVariables
nodeByUri(uri: "/"){
... on ContentNode {
blocks
}
}
}
`
})
});
const {
data: {
cssVariables,
nodeByUri
}
} = await response.json();
const blocks: Block[] = nodeByUri?.blocks ?? [];
---
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Homepage</title>
{!!cssVariables && <style set:html={`:root{${cssVariables}}`} />}
</head>
<body>
<BlockRenderer blocks={blocks} />
{blocks.map((block) => {
const { styles, classes } = getBlockStyling(block);
switch(block.name){
case "core/paragraph":
return <p set:html={block.attributes?.content} class={classes} style={styles} />
default:
return null;
}
})}
</body>
</html>