How to read Gutenberg contents for headless WordPress (r) (r)

Jul 12, 2024
Parse Gutenberg content

-sidebar-toc>

The prerequisites

To be able to follow the instructions for the course, you'll require:

Retrieve Gutenberg content using an API REST

In order to enable JSON data access through the REST API, adjust your WordPress settings for permalinks to be different from "Plain." The setting will allow API access via a structured URL, according to:

https://yoursite.com/wp-json/wp/v2

Through sending API requests to this URL, you will be able to automatically retrieve different information as well as perform various tasks on your WordPress website. You can, for instance, get a list of your blog posts through an GET request to:

https://yoursite.com/wp-json/wp/v2/posts

It will produce an JSON object, which contains details about the posts published on your WordPress website, such as titles and content, details about the author and much more.

Parse Gutenberg blocks as HTML

This short clipping illustrates two Gutenberg blocks: a Quote and Gallery. Both are enhanced with JSON metadata that is encapsulated in HTML comments. The metadata defines attributes such as classes names, styles, and other configurations that are relevant to the layout of the block.

When you fetch these blocks using the WordPress REST API or WPGraphQL, WordPress processes them and transforms the mixture of HTML and JSON metadata to completely rendered HTML elements you are able to easily incorporate into your webpages. The transformed HTML for these blocks would appear as follows:


"The journey of a thousand miles starts with one move." Lao Tzu
   
   HTML10 

For developers building decoupled or headless applications using JavaScript frameworks like Next.js, this presents a straightforward method to display content by directly injecting the HTML into the page using the dangerouslySetInnerHTML property to render the markup.

  />
  
   In addition, you may need do additional formatting on elements like links or handle excess newline characters ( \n), which this guide explains further down.
  
  
   Parse Gutenberg blocks content from Next.js static site
  
  
   In this chapter, let's fetch WordPress content in the Next.js project, and then decode the Gutenberg blocks to create HTML.
  
  
   
    Start by setting up a function that will fetch posts from your WordPress site. Start by opening the
    
     src/page.js
    
    Include the file into your project and then replace the content of it using the following code snippet:
    const getWpPosts = async () => 
 const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
 const posts = await res.json();
 return posts;
 ;
    
     This asynchronous function performs an API request to WordPress REST API. It collects all of the blog content on your website and returns them as an array.
    
   
   
    Now, let's make use of the fetched posts within a simple Next.js page component by writing the post to the console and creating a basic greeting
    const page = async () => 
 const posts = await getWpPosts();
 console.log(posts);
 
 return (
 
 Hello World
 
 );
 ;
 
 export default page;
    
     When you run your project by using the command npm run dev It displays the "Hello World" message and logs the posted posts it fetched into the Terminal.
    
    [
 
 "_links" : 
 "about" : [...],
 "author" : [...],
 "collection" : [...],
 "curies" : [...],
 "predecessor-version" : [...],
 "replies" : [...],
 "self" : [...],
 "version-history" : [...],
 "wp:attachment" : [...],
 "wp:term" : [...]
 ,
 "author" : 1,
 "categories" : [...],
 "comment_status" : "open",
 "content" : 
 "protected" : false,
 "rendered" : "\nFire, a primal force, captivates with its flickering flames, evoking both awe and caution. The dance symbolizes destruction and renewal, consuming the old in order to create the new. While it warms our homes and hearts, fire demands respect for its power to devastate.\n\n\n\n\n\n\n\nIn ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and even danger. From the comforting glow of a hearth to the destructive fury of wildfires, fire's dual nature reminds us of our fragile relationship with the elements.\n\n\n\n\n\n\n\nYou can check out other articles on our blog:\n\n\n\n\nLorem Ipsum: Beginnings\n\n\n\nLorem Ipsum: Act 2\n\n\n\nLorem Ipsum: Act 3\n\n"
 ,
 "date" : "2024-02-27T12:08:30",
 "date_gmt" : "2024-02-27T12:08:30",
 "excerpt" : 
 "protected" : false,
 "rendered" : "Fire, a primal force, captivates with its flickering flames, evoking both awe and caution. Its dance symbolizes destruction and renewal, consuming the old to make way for the new. Although it is a source of warmth for our homes and our hearts, fire demands respect because of its ability to destroy. In ancient times, fire was a beacon of light and warmth, [...]\n"
 ,
 "featured_media" : 0,
 "format" : "standard",
 "guid" : 
 "rendered" : "https://yoursite.com/?p=13"
 ,
 "id" : 13,
 "link" : "https://yoursite.com/?p=13",
 "meta" : 
 "footnotes" : ""
 ,
 "modified" : "2024-02-29T16:45:36",
 "modified_gmt" : "2024-02-29T16:45:36",
 "ping_status" : "open",
 "slug" : "fire-fire",
 "status" : "publish",
 "sticky" : false,
 "tags" : [],
 "template" : "",
 "title" : 
 "rendered" : "Fire"
 ,
 "type" : "post"
 ,
 ,
 ...
 ]
    
     The JSON objects representing the individual Gutenberg post data include various fields. Among them are the content and excerpt fields are provided in the form of Gutenberg blocks, which are then parsed to create HTML strings.
    
   
   
    To render this HTML content properly for rendering correctly Next.js, we employ the
    
     dangerouslySetInnerHTML
    
     property:
    const page = async () => 
 const posts = await getWpPosts();
 
 return (
 
  Headless Blog 
 
 
 posts.map((post) => (
 
 
 post.title.rendered ->
 
 
 
 ))
 
 >
 );
 ;
 
 export default page;
    
     The updated component we overlay the fetched posts array and generate a list excerpts from posts. Each excerpt is wrapped in an Link component to facilitate navigation, displaying the post title as well as a short excerpt of the post's information.
    
    
     The dangerouslySetInnerHTML property is used to parse and render the HTML content contained within the excerpt.rendered field.
    
   
   
    Every post is assigned an ID. You use this ID to create its own unique route,
    
     /blog/post_id
    
    In your application. Include the following code in your application:
    import Link from 'next/link';
 
 export async function generateStaticParams() 
 const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
 const posts = await res.json();
 return posts.map((post) => 
 return 
 params: 
 id: post.id.toString(),
 ,
 ;
 );
 
 
 export async function getPost(id) 
 const response = await fetch('https://yoursite.com/wp-json/wp/v2/posts/' + id);
 const post = await response.json();
 return post;
 
    
     The generateStaticParams() function statically generates routes at build-time based on the corresponding ID returned on each post. Its caller function, getPost() function fetches Gutenberg data via the REST API for the specific post that has the ID passed.
    
    
     The previous article showed sample parsed Gutenberg information returned by the REST API to post. At present, we're focused on what is known as the content.rendered field:
    
    [
 "content"..."content""content":  --"rendered" : "\nFire, an elemental force, is captivating by its glowing flames and evokes both fear as well as a sense of prudence. Its dance is a symbol of destruction and regeneration by consuming the old in order to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate.\n\n\n\n class=\"wp-block-image size-full\">\n\n\n\nIn ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and risk. From the comforting glow of a hearth to the destructive fury of wildfires, fire's dual nature reminds us of our fragile relationship with the elements.\n\n\n\n class=\"wp-block-image size-large\">\n\n\n\nYou can check out other articles on our blog:\n\n\n\n\n href=\"https://yoursite.com/?p=6\">Lorem Ipsum: Beginnings\n\n\n\n href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2\n\n\n\n href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Act 3\n\n"
 ,
 ...
 
 ]
    
     This field contains the content's raw HTML. It can be rendered directly using the dangerouslySetInnerHTML property like this,   />.
    
   
   
    Then, you'll be able to use the information to process it by analyzing internal links as well as resizing images. Install the
    
     html-react-parser
    
    package to simplify the process of parsing tags
    NPM install html-react-parser -save
   
   
    Include the code below to the
    
     blog/[id]/page.js
    
     file:
    import parse: domToReact is derived from "html-react-parser" •/*This is the regular expression (pattern) to identify the URL that you wish to replace. * The (\d+) component is the part that captures the ID numeric after ?p=. * Then, we use the replacement string 'data-internal-link="true" href="/blog/$1"',
 * where $1 is a placeholder for the captured ID. */
 export function fixInternalLinks(html_string) 
 const pattern = /href="https:\/\/yoursite.com\/\?p=(\d+)"/g;
 const replacement = 'data-internal-link="true" href="/blog/$1"';
 
 return html_string.replace(pattern, replacement);
 
 
 export function parseHtml(html) 
 // Replace 2+ sequences of '\n' with a single '' tag
 const _content = html.replace(/\n2,/g, '');
 const content = fixInternalLinks(_content);
 
 const options = 
 replace: ( name, attribs, children ) => 
 // Convert internal links to Next.js Link components. const isInternalLink =
 name === "a" && attribs["data-internal-link"] === "true";
 
 if (isInternalLink) 
 return (
 
 domToReact(children, options)
 
 );
  else if (name === "img") 
 attribs["width"] = "250";
 attribs["height"] = "150";
 return (
 
 );
 
 ,
 ;
 
 return parse(content, options);
 
    
     The fixInternalLinks() function uses a regular expression to find hyperlinks to your posts on your WordPress site using the HTML string. When you look at the unformatted HTML it is evident the article has the List tag with links to other posts that are on your website, and replaces those links with internal links to the routes on your static website.
    
    
     The parseHTML() function finds several sequences of excessive newlines andand replaces them with  tags. Also, it locates internal links, and transforms anchor tags to Link tags. This function then resizes images using tag attributes.
    
   
   
    For the main user interface to be generated for every dynamic route include the below code:
    export default async function Post( params ) 
 const post = await getPost(params.id);
 
 const content = parseHtml(post.content.rendered);
 
 return (
 
 
 post.title.rendered
 
 
 content
 >
 );
 
    
     After parsing the unformatted HTML from the Gutenberg data, the script generates JSX, which represents the page's formatting UI.
    
   
  
  
   In the end, once you have launched your website, the home page will show a listing of your posts in WordPress. If you also click each post, you'll be able to see the filtered Gutenberg contents rendered properly.
  
  
   Deploy your Next.js static site on
  
  
   
    Log in or create an account to view Your dashboard. My dashboard.
   
   
    Authorize with your Git provider.
   
   
    Select static sites on the left sidebar Click Static Sites, and click Add site.
   
   
    Select the repository and branch from which you wish to install.
   
   
    Assign a unique name to your site.
   
   
    Set the build parameters according to the following format:
    
     
      Build command: npm run build
     
     
       Node version: 18.16.0
     
     
       Publish directory: out
     
    
   
   
    Then, click to create your site..
   
  
  
   Summary
  
  
   This guide has explained how you can integrate and read Gutenberg block contents efficiently as HTML using The WordPress API. This allows you to render any kind of content on your front end possible when you use headless WordPress.
  
  
   You can host your website headless WordPress on the managed WordPress Hosting service and deploy your static site to our Static Site Hosting service. This means everything about your website is on one dashboard My.
  
  
   
    What are your thoughts on headless WordPress and the rendering? Do you have a better idea to connect Gutenberg blocks? Tell us about it in the comment section!
   
  
  
   
    
      
    
    
     
      Jeremy Holcombe
     
     
      Content & Marketing Editor at , WordPress Web Developer, and Content Writer. In addition to all things WordPress I like the beach, golf, as well as movies. Also, I have height issues ;).
     
     
      
       
        
         Website
        
        
         
         
        
       
      
      
       
        
         LinkedIn