How to parse Gutenberg content in WordPress

Gutenberg is the default editor for WordPress. This editor allows content to be created and designed using discrete blocks of text, images, video, and other website elements through a drag-and-drop interface. This approach enhances the flexibility and design capabilities of WordPress.

Image[1]-How to parse WordPress Gutenberg content - Photon Flux | Professional WordPress Repair Service, Global Reach, Fast Response

Getting Gutenberg Content with the REST API

To programmatically interact with a WordPress site and retrieve structured content in Gutenberg blocks, you can use the WordPress REST API or the WPGraphQL plugin. These tools enable you to fetch WordPress content in JSON format.

To enable JSON data access via the REST API, adjust the WordPress permalink settings away from "Plain". That way, the API can be accessed through a URL in a specific format, as shown below:

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

By sending API requests to this URL, you can programmatically retrieve various information and perform actions on your WordPress site. For example, you can get a list of posts by sending a GET request to the following address:

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

A JSON object is returned containing information about the post on the WordPress site, including the title, content, author details, and so on.

Image [2] - How to parse WordPress Gutenberg content - Photon Flux | Professional WordPress Repair Service, Global Reach, Fast Response

Parsing Gutenberg blocks into HTML

When retrieving posts from a WordPress site using the Gutenberg editor, the content stored in the database can use a mix of HTML and JSON metadata to describe various block types, such as quotes and galleries:

<!-- wp:quote {"className":"inspirational-quote","style":{"typography":{"fontSize":"large"}}} -->
<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>"The journey of a thousand miles begins with one step."</p><cite>Lao Tzu</cite></blockquote>
<!-- /wp:quote -->

<!-- wp:gallery {"ids":[34,35],"columns":2,"linkTo":"none","sizeSlug":"medium","className":"custom-gallery"} -->
<ul class="wp-block-gallery columns-2 is-cropped custom-gallery"><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="A breathtaking view of the mountains" class="wp-image-34"/></figure></li><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serene lakeside at dawn" class="wp-image-35"/></figure></li></ul>
<!-- /wp:gallery -->

This snippet shows two Gutenberg blocks: a citation and a gallery. Each block has JSON metadata encapsulated in HTML comments. The metadata defines attributes such as class names, styles, and other configurations related to the presentation of the blocks.

Image [3] - How to parse WordPress Gutenberg content - Photon Flux | Professional WordPress repair service, global reach, fast response

When you fetch these blocks via the WordPress REST API or WPGraphQL, WordPress processes them and converts the combination of HTML and JSON metadata into fully rendered HTML elements that you can integrate directly into your pages. The converted HTML of the above block is displayed below:

<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>"The journey of a thousand miles begins with one step."</p><cite>Lao Tzu</cite></blockquote>

<ul class="wp-block-gallery columns-2 is-cropped custom-gallery">
  <li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="A breathtaking view of the mountains" class="wp-image-34" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
  <li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serene lakeside at dawn" class="wp-image-35" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
</ul>

For developers building decoupled or applications using JavaScript frameworks such as Next.js, this provides an easy way to display content by injecting HTML directly into the page using attributesdangerouslySetInnerHTMLto present the markers.

<div dangerouslysetinnerhtml="{{" __html: <raw_html_string> }} />
Image [4] - How to parse WordPress Gutenberg content - Photon Flux | Professional WordPress repair service, global reach, fast response

Parse Gutenberg block content into Next.js static site

We extract the WordPress content into a Next.js project and then parse the Gutenberg blocks into HTML.

1. First set up a function to fetch posts from the WordPress site. Open the src/page.js file and replace its contents with the following code snippet:

const getWpPosts = async () => {
const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
  const posts = await res.json();
const posts = await fetch(''); const posts = await res.json(); return posts;
};

This asynchronous function performs an API request to the WordPress REST API. It gets all the available posts on your site and returns them as an array.

2. Next, let's utilize the fetched post in a simple Next.js page component by logging the post to the console and rendering the basic greeting:

const page = async () =&gt; {
  const posts = await getWpPosts(); console.log(posts); {
  console.log(posts);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
}.

export default page.

    When you run a project usingnpm run devIt displays a "Hello World" message and logs the fetched post to the terminal.

    [
      {
        "_links" : {
          "about" : [...] ,
          "author" : [...] ,
          "collection" : [...] , "curies" : [...] , "collection" : [...] , "collection" : [...]
          "curies" : [...] . ,
          "predecessor-version" : [...] . , "replies" : [...] , "curies" : [...] , "predecessor-version" : [...]
          "replies" : [...] . , "self" : [...] , "replies" : [...]
          "self" : [...] , "version-history" : [...] , "replies" : [...] , "self" : [...]
          "version-history" : [...] . , "wp:attachment" : [...] , "self" : [...] , "version-history" : [...]
          "wp:attachment" : [...] . , "wp:term" : [...] , "version-history" : [...] , "wp:attachment" : [...]
          "wp:term" : [...] .
        },
        "author" : 1,
        "categories" : [...] } , "author" : 1, "categories" : [...] }
        "comment_status" : "open", "content" : { "wp:term" : [...] }
        "content" : {
          "protected" : false, "rendered" : "\new", "content" : {
          "rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate. devastate.</p>\n\n\\n\n<figure class="\"wp-block-image" size-full\"><img loading="\"lazy\"" decoding="\"async\"" width="\"250\"" height="\"148\"" src="\"https:></figure>\n\n\\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and 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 world. 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.</p>\n\n\\n\n<figure class="\"wp-block-image" size-large\"><img decoding="\"async\"" src="\"https:></figure>\n\n\\n\n<p>You can check out other articles on our blog.</p>\n\n\\n\n<ul>\n<li><a href="/en/"https:>Lorem Ipsum: Beginnings</a></li>\n\n\\n\n<li><a href="/en/"https:>Lorem Ipsum: Act 2</a></li>\n\n\\n\n<li><a href="/en/"https:>Lorem Ipsum: Act 3</a></li>\n</ul>\n"
        },
        "date" : "2024-02-27T12:08:30",
        "date_gmt" : "2024-02-27T12:08:30",
        "excerpt" : {
          "protected" : false, "rendered" :
          "rendered" : "<p>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. Its dance symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate. In ancient times, fire was a beacon of light and warmth, [...]</p>\n"
        },
        "featured_media" : 0,
        "format" : "standard",
        "guid" : {
          "rendered" : "https://yoursite.com/?p=13"
        },
        
        
        "meta" : {
          "footnotes" : ""
        },
        
        
        
        
        
        
        
        "template" : "",
        "title" : {
          "rendered" : "Fire"
        },
        "type" : "post"
       },
      },
      ...
    ]

    The JSON object representing the data for individual Gutenberg posts includes various fields, with the content and excerpt fields returned as Gutenberg blocks parsed as HTML strings.

    3. To render this HTML content correctly in Next.js, we use thedangerouslySetInnerHTMLProperties:

    const page = async () =&gt; {
      const posts = await getWpPosts();
    
      return (
        <>
          <h1> Headless Blog </h1>
    
          <div>
            {posts.map((post) =&gt; (
              <link href="{'/blog/'" + post.id} key="{post.id}">
                <h2>
                  {post.title.rendered} <span>-></span>
                </h2>
                <div dangerouslysetinnerhtml="{{" __html: post.excerpt.rendered }} />
              </Link>
            ))}
          </div>
        </>
      );
    }.
    
    export default page.

      In the updated component, we map the array of fetched posts to generate a list of post excerpts. Each excerpt is contained in aLinkThe post title and its content snippet are displayed in the component used for navigation.

      ought todangerouslySetInnerHTMLAttributes are used for parsing and renderingexcerpt.renderedThe HTML content contained in the field.

      4.Next, in the applicationCreate a file in the directoryblog/[id]/page.js  . You can use folders to define routes. Thus, a route can be defined by creatingblog (loanword) folder, you can defineblog (loanword) Routes. This can be combined with dynamic routing , which generates routes for each post.

      5. Each post has an ID./blog/{post_id}Generate its unique path in the application. Add the following code:

      import Link from 'next/link';
      
      export async function generateStaticParams() {
          
          const posts = await res.json(); return posts.map((post) => { {{post}}})
          return posts.map((post) => {
              return {
                  params: {
                      id: post.id.toString(), { params: { post.id.
                  }, }
              }; }
          });
      }
      
      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; const post = await response.
          const post = await response.json(); return post; }
      }

        ought togenerateStaticParams() function statically generates paths at build time based on the corresponding IDs returned by each post. ThegetPost()The function gets the Gutenberg data for the post from the REST API using the ID passed.

        The previous section shows an example of parsed Gutenberg data returned from the post's REST API. For now, we are only concerned with thecontent.rendered Fields:

        [
          {
            ...
            "content": {
              "rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate. devastate.</p>\n\n\\n\n<figure> class=\"wp-block-image size-full\"&gt;<img loading="\"lazy\"" decoding="\"async\"" width="\"250\"" height="\"148\"" src="\"https:></figure>\n\n\\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and 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 world. 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.</p>\n\n\\n\n<figure> class=\"wp-block-image size-large\"&gt;<img decoding="\"async\"" src="\"https:></figure>\n\n\\n\n<p>You can check out other articles on our blog.</p>\n\n\\n\n<ul>\n<li><a> href=\"https://yoursite.com/?p=6\"&gt;Lorem Ipsum: Beginnings</a></li>\n\n\\n\n<li><a> href=\"https://yoursite.com/?p=9\"&gt;Lorem Ipsum: Act 2</a></li>\n\n\\n\n<li><a> href=\"https://yoursite.com/?p=11\"&gt;Lorem Ipsum: Act 3</a></li>\n</ul>\n"
            },
            ...
          }
        ]

        This field contains the raw HTML of the post. it can be used directly with thedangerouslySetInnerHTML Properties like this one render<div dangerouslysetinnerhtml="{{" __html: <raw_html_string> }} />The

        6. Next, the data can be processed by parsing internal links and resizing the image. Install thehtml-react-parser package to simplify the process of parsing tags:

        npm install html-react-parser --save

          7. Add the following code toblog/[id]/page.js Documentation:

          import parse, { domToReact } from "html-react-parser";
          
          /*
           * We use a regular expression (pattern) to match the specific URL you want to replace.
           * The (\d+) part captures the numeric ID 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 '<br />' tag
            const _content = html.replace(/\n{2,}/g, '<br />');
            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 (
                    <Link href={attribs.href} {...attribs}>
                      {domToReact(children, options)}
                    </Link>
              	  );
                } else if (name === "img") {
                  attribs["width"] = "250";
                  attribs["height"] = "150";
                  return (
                    <img {...attribs}/>
                  );
                }
              },
            };
          
            return parse(content, options);
          }

          ought tofixInternalLinks() function uses a regular expression to find a link to a post on the WordPress site from a string of HTML. In the raw HTML, you can see that the post contains aListtag, which contains links to other posts on the site, and replaces those links with internal links pointing to paths in the static site.

          ought toparseHTML() function finds multiple redundant newline sequences.nand replace them with labels<br /> . It also looks for internal links and converts anchor tags to link tags. The function then resizes the image using the tag attribute.

          8. To generate the main UI for each dynamic path, add the following code:

          export default async function Post({ params }) {
            const post = await getPost(params.id);
          
            const content = parseHtml(post.content.rendered);
          
            return (
              <>
                <h1>
                  {post.title.rendered}
                </h1>
           	 
                <div>{content}</div>
              </>
            );
          }

          After parsing the raw HTML from the Gutenberg data, the code returns JSX representing the page's formatted UI.

            Finally, when you run the project, the homepage will show a list of posts on WordPress. In addition, when you click on individual posts, you will see the parsed Gutenberg content rendered correctly.


            Contact Us
            Can't read the tutorial? Contact us for a free answer! Free help for personal, small business sites!
            Customer Service
            Customer Service
            Tel: 020-2206-9892
            QQ咨询:1025174874
            (iii) E-mail: info@361sale.com
            Working hours: Monday to Friday, 9:30-18:30, holidays off
            © Reprint statement
            This article was written by Harry
            THE END
            If you like it, support it.
            kudos0 share (joys, benefits, privileges etc) with others
            commentaries sofa-buying

            Please log in to post a comment

              No comments