Kinsta® https://kinsta.com Fast, secure, premium hosting solutions Mon, 01 Apr 2024 16:45:43 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.5 https://kinsta.com/wp-content/uploads/2023/12/cropped-kinsta-favicon-32x32.png Kinsta® https://kinsta.com 32 32 Headless WooCommerce: from setup to deployment on Kinsta https://kinsta.com/blog/headless-woocommerce/ https://kinsta.com/blog/headless-woocommerce/#respond Wed, 03 Apr 2024 12:42:35 +0000 https://kinsta.com/?p=176424&preview=true&preview_id=176424 WooCommerce is one of the most popular WordPress plugins for building ecommerce applications. In addition to using WooCommerce in a traditional WordPress application, you can use it ...

The post Headless WooCommerce: from setup to deployment on Kinsta appeared first on Kinsta®.

]]>
WooCommerce is one of the most popular WordPress plugins for building ecommerce applications. In addition to using WooCommerce in a traditional WordPress application, you can use it as a headless solution.

This article teaches you how to build a headless WordPress application with React deployed on Kinsta.

Introduction to headless WooCommerce

The term “headless ecommerce” means the separation of the backend (head) from the frontend (body) of an ecommerce application. Headless architecture passes requests between the presentation layers (frontend) and the application layers (backend) of an ecommerce solution through APIs.

The APIs define interactions between intermediaries, allowing businesses to change the presentation layers without disturbing the functionality of application layers and update, edit, or add products to multiple application layers.

In a headless WooCommerce application, the WooCommerce API is an intermediary, providing communication between the frontend and backend. In addition to the benefits mentioned above, this supports flexible and scalable frontend development, empowering you to focus on crafting engaging and dynamic user interfaces with modern technology stacks like React or Vue.

Moreover, using headless WooCommerce future-proofs ecommerce infrastructure by helping you adapt to evolving customer needs and technological advancements. You can effortlessly update frontend components while ensuring the stability and reliability of the backend WooCommerce platform.

Illustration of a traditional CMS and a WooCommerce application backend separated from its frontend communicating through an API
Traditional ecommerce application and a headless WooCommerce application.

This modern approach offers numerous benefits compared to traditional WordPress ecommerce setups.

Now that you understand what a headless WooCommerce application is and its benefits, it’s time to build one for yourself. Using WordPress, React, and the WooCommerce plugin, you’ll create an ecommerce app and deploy it on Kinsta.

Prerequisites

Before beginning, ensure you have the following:

Benefits of headless WooCommerce

When you choose the headless route for your WooCommerce applications, you unlock a range of benefits—especially the flexibility of having one backend support various frontends for your application.

Here are some other benefits of headless WooCommerce:

  • Enhanced customization — You can build your WooCommerce application how you want using any web framework.
  • Improved site performance — You can leverage fast web frameworks like React and Vue to significantly boost your site’s performance.
  • SEO benefits — You have more control and flexibility over SEO strategies to achieve your business’s goals.
  • Better scalability — Your site can scale more efficiently, ensuring smooth performance even during periods of high traffic.
  • Ability to create unique customer experiences — You are free from the constraints of traditional templates. You can craft innovative and personalized experiences for your customers.

Setting up a headless WooCommerce site

Here’s a step-by-step guide to setting up a WooCommerce site:

  1. Log in to your MyKinsta dashboard
  2. Navigate to Add Service > WordPress site.
  3. Select the Install WordPress option.
  4. On the Add new WordPress site page, complete the fields required to install WordPress.
  5. Check the Install WooCommerce box before you click Continue.
Add new WordPress site page showing site title, admin username, admin password, admin email, and language fields. Underneath the fields there are optional plugins including WooCommerce, Yoast SEO, and Easy Digital Downloads. At the bottom of the page are Back and Continue buttons
Installing WordPress and the WooCommerce plugin.

Activate the WooCommerce plugin

  1. On your MyKinsta dashboard, click Domains on the sidebar.
  2. On the Domains page, click Open WordPress Admin.
  3. Log in to your WordPress Admin dashboard, navigate to plugins, select the WooCommerce plugin, and activate it.
WordPress Admin dashboard showing the optional plugins available including the WooCommerce plugin. Each plugin has an Activate and Delete button below the option
Activating the WooCommerce plugin.

Configure WooCommerce for headless operation

To configure WooCommerce for headless operations:

  1. Log in to your WordPress Admin dashboard. On the sidebar, click WooCommerce > Settings.
  2. On the Settings page, click the Advanced tab. Then, click Rest API.
  3. Now click Add key.

    Advanced page showing the REST API option selected and an Add key button beside it
    Adding the key for the REST API.
  4. Click Create an API key. Give your new REST API a description, set the Permissions field to Read/Write, and click Generate API key.

    Key details page for the REST API. It has Description, User, and Permissions fields. Underneath the fields there is a Generate API key button
    Generating the WooCommerce API key.
  5. Copy the consumer key and secret and store them safely for use in the React application.
  6. Finally, adjust the Permalink structure to ensure JSON data is returned when requesting the API. On the WordPress Admin dashboard, click Settings > Permalinks, and select Post name.

Before proceeding, add some products to your WooCommerce store. Navigate to the WooCommerce section in your WordPress dashboard, click on Products, and follow the prompts to add products. You can also import these sample products for your store.

With WordPress and WooCommerce set up, you’re ready to focus on the frontend of your headless ecommerce application.

Set up a React project

Here’s how to set up a React project:

  1. In your preferred directory, use the following commands to create a React project:
    # Remember to replace <app-name> with your preferred name
    
    # With npx
    npx create-react-app <app-name> && cd <app-name>
    
    # With yarn
    yarn create react-app <app-name> && cd <app-name>
  2. Once your project is created, create a .env file in the root of your project and add the following:
    REACT_APP_CONSUMER_KEY=your_Woocommerce_consumer_key
    REACT_APP_CONSUMER_SECRET=your_Woocommerce_consumer_secret

    Replace this with your WooCommerce consumer key and secret generated earlier.

  3. Next, use the command below to install a package for managing routes:
    ## With npm
    npm i react-router-dom
    
    ## With yarn
    yarn add react-router-dom
  4. Finally, launch the React project using the following command:
    ## With npm
    npm start
    
    ## With yarn
    yarn start

Develop the frontend for your headless WooCommerce site

A successful ecommerce store showcases products and facilitates purchases. Begin by displaying the products available in the WooCommerce store on the frontend. This involves making requests to the WooCommerce API.

The endpoint to list all products is wp-json/wc/v3/products. This endpoint must be appended to the host URL. Add this variable to your .env file for your base URL, which is the host URL appended with the products endpoint. Update http://example.com with your WooCommerce site domain.

REACT_APP_BASE_URL=http://example.com/wp-json/wc/v3/products

When making API requests, you must include your consumer key and secret in the URL. When combined, the URL looks like this:


https://kinstawoocommerce.kinsta.cloud/wp-json/wc/v3/products?consumer_key=your_consumer_key&consumer_secret=your_consumer_secret

Let’s make API requests in the React application using the Fetch API to fetch the WooCommerce products.

  1. In your React application, open the App.js file in the src directory and replace its contents with the code below:
    import {Link} from 'react-router-dom';
    import {useEffect, useState} from 'react';
    
    function App() {
        const BASE_URL = process.env.REACT_APP_BASE_URL;
        const CONSUMER_KEY = process.env.REACT_APP_CONSUMER_KEY;
        const CONSUMER_SECRET = process.env.REACT_APP_CONSUMER_SECRET;
    
        const [products, setProducts] = useState([]);
        const [loading, setLoading] = useState(true);
    
        useEffect(() => {
            const fetchProducts = async () => {
                const response = await fetch(`${BASE_URL}?consumer_key=${CONSUMER_KEY}&consumer_secret=${CONSUMER_SECRET}`);
                const data = await response.json();
                setProducts(data);
                setLoading(false);
            };
    
            fetchProducts();
        }, [BASE_URL, CONSUMER_KEY, CONSUMER_SECRET]);
    
        return loading ? (
            <div className="loaderText">
                <h2>Just a moment. Fetching products...</h2>{' '}
            </div>
        ) : (
            <ul>
                {products ? (
                    products.map((product) => (
                        <li key={product.id}>
                            <Link to={`/product/${product.id}`}>
                                <img src={product.images[0].src} alt="Product banner"/>
                                <h2>{product.name}</h2>
                                <p>Sale price: {product.sale_price}</p>
                                <strong>
                                    {product.stock_status === 'instock'
                                        ? 'In stock'
                                        : 'Out of stock'}
                                </strong>
                                <button>Add to Cart</button>
                            </Link>
                        </li>
                    ))
                ) : (
                    <li>No products found</li>
                )}
            </ul>
        );
    }
    
    export default App;

    This code fetches a list of products from the WooCommerce API endpoint using the Fetch API when the component mounts (useEffect hook). The endpoint URL is constructed using environment variables set earlier

    Once the data is fetched, it updates the component state (products) using setProducts(response) and sets loading to false using setLoading(false).

    While the data is being fetched, it displays a loading message. Once the data is fetched and loading is set to false, it maps through the products array and renders a list of product items using JavaScript XML (JSX). Each product item is wrapped in a Link component from react-router-dom, which generates a link to the individual product’s details page based on its ID.

    The product’s name, price, description (rendered using dangerouslySetInnerHTML to inject HTML content), stock status, and a button are displayed for each product.

  2. In the src directory, open the index.js file and replace the code with the snippet below:
    import React from "react";
    import ReactDOM from "react-dom";
    import { BrowserRouter, Route, Routes } from "react-router-dom";
    import "./index.css";
    import App from "./App";
    
    
    ReactDOM.render(
        <React.StrictMode>
            <div className="container">
                <header>
                    <h1>Kinsta Store</h1>
                </header>
                    <BrowserRouter>
                        <Routes>
                            <Route exact path="/" element={<App />} />
                        </Routes>
                    </BrowserRouter>
    
            </div>
        </React.StrictMode>,
        document.getElementById("root")
    );

    It renders the App component when the / route is called in the browser.

  3. Run your app to view the changes.
    ## With npm
    npm start
    
    ## With yarn
    yarn start

    The React application now displays a list of products from the WooCommerce store.

    Web page displaying a list of clothing products. Each listing has a name, a price, and a description, and is followed by an Add to Cart button
    WooCommerce store product list.

Create dynamic product pages

Now, to enhance the user experience, create dynamic product pages using the WooCommerce API. This API provides an endpoint to fetch data about a single product: wp-json/wc/v3/products/<id>. To use this endpoint to fetch and display data about a single product in the store, follow these steps:

  1. Create a component ProductDetail.js inside the src directory that fetches and displays data about a single product. This component fetches and displays detailed information about a single product.It operates in a similar manner to the code in the App.js file, except it retrieves details for a single product.
    import {useState, useEffect} from 'react';
    import {useParams} from 'react-router-dom';
    
    function ProductDetail() {
        const BASE_URL = process.env.REACT_APP_BASE_URL;
        const CONSUMER_KEY = process.env.REACT_APP_CONSUMER_KEY;
        const CONSUMER_SECRET = process.env.REACT_APP_CONSUMER_SECRET;
    
        const {id} = useParams();
        const [product, setProduct] = useState(null);
    
        useEffect(() => {
            const fetchSingleProductDetails = async () => {
                const response = await fetch(
                    `${BASE_URL}/${id}?consumer_key=${CONSUMER_KEY}&consumer_secret=${CONSUMER_SECRET}`
                );
                const data = await response.json();
                setProduct(data);
            };
            fetchSingleProductDetails();
        }, [BASE_URL, CONSUMER_KEY, CONSUMER_SECRET, id]);
    
        if (!product) {
            return (
                <div className="loaderText">
                    <h2>Fetching product details...</h2>
                </div>
            );
        }
    
        return (
            <div className="product-detail">
                <h2>{product.name}</h2>
                <h4>Original Price: {product.regular_price}</h4>
                <h4>Sale price: {product.sale_price}</h4>
                <img src={product.images[0].src} alt="Product banner"/>
                <strong>
                    {product.stock_status === 'instock' ? 'In stock' : 'Out of stock'}
                </strong>
            </div>
        );
    }
    
    export default ProductDetail;
  2. Create a new route in index.js and assign the ProductDetail component to it. This code snippet creates a new route in index.js and assigns the ProductDetail component. This ensures that when users click a product link, they are directed to the respective product page.
    // index.js
    …
    import ProductDetail from "./ProductDetail";
    
    ReactDOM.render(
      <React.StrictMode>
    	…
                   <Router>
              <Routes>
                <Route exact path="/" element={<App />} />
    		{/* the new route */}
                <Route path="/product/:id" element={<ProductDetail />} />
              </Routes>
            </Router>
        </div>
      </React.StrictMode>,
      document.getElementById("root")
    );

    With these modifications, clicking any product in the application redirects users to a page displaying detailed information about that specific product.

    Web page displaying detailed information about a clothing product
    Detailed information about a clothing product.

You can access the complete code in this GitHub repository.

Integrate key WooCommerce features in a headless setup

You can build on the foundation of listing products in a headless WooCommerce application by integrating essential features like the following:

  • Shopping carts — Manage cart data on the client side or use local storage to allow users to add, remove, and update items seamlessly.
  • Checkout processes — Design a streamlined checkout with React components, collect necessary information, validate user input, and ensure a smooth checkout experience.
  • User authentication — Implement secure authentication using JSON Web Token (JWT) or Open Authorization 2.0 (OAuth2) to enhance the user experience with registration, login, and password reset features.
  • Payment processing — Use secure payment gateway APIs, like Stripe or PayPal, for transactions and refunds.
  • Order management — Manage orders and statuses efficiently with the WooCommerce API. Provide user-friendly features for order history, tracking, returns, and refunds, and automate processes using webhooks or event-driven architecture.

Deploy your headless WooCommerce site on Kinsta

Once you’ve developed your headless WooCommerce site, deploying it on Kinsta’s WordPress Hosting platform is straightforward.

Kinsta offers a range of benefits, including high performance, robust security, and scalability, making it an ideal choice for hosting your headless ecommerce site. If you already have a WordPress site that isn’t on Kinsta, you can easily migrate it to Kinsta.

Additionally, you can deploy your React application to Kinsta’s Static Site Hosting service for free — all you have to push your code to your preferred Git provider (Bitbucket, GitHub, or GitLab).

Once you’ve pushed your code, follow these steps to deploy your site:

  1. Log in to your MyKinsta dashboard.
  2. Click Add service, then Static Site.
  3. Select a Git provider and click Connect git provider.
  4. Select the repository and the branch you want to deploy. The build settings are automatically detected.
  5. Make sure to add any necessary environment variables from your .env file.

    Environment variables page with fields for key and value pairs. There is a Create site button at the bottom on the right
    Adding environment variables.
  6. Finally, click Create site to deploy your React application.

You’ve successfully deployed your headless WooCommerce application!

Summary

This article explained the numerous advantages and new possibilities for creating dynamic and high-performing online stores by setting up headless WooCommerce sites.

By decoupling the frontend from the backend, you can customize your site to deliver more engaging and personalized shopping experiences to customers that benefit from high performance, robust security, and scalability.

Whether you’re a seasoned developer or just starting, Kinsta provides the support, tools, and other resources you need to build and manage innovative and successful ecommerce solutions. Host with Kinsta today to explore the possibilities of headless ecommerce!

Are you excited about the endless possibilities of headless WooCommerce for your online store? Share your insights or questions in the comments below.

The post Headless WooCommerce: from setup to deployment on Kinsta appeared first on Kinsta®.

]]>
https://kinsta.com/blog/headless-woocommerce/feed/ 0
How to parse Gutenberg content for headless WordPress https://kinsta.com/blog/headless-wordpress-gutenberg/ https://kinsta.com/blog/headless-wordpress-gutenberg/#respond Mon, 01 Apr 2024 13:30:48 +0000 https://kinsta.com/?p=176780&preview=true&preview_id=176780 Gutenberg is the default editor for WordPress. The editor lets you craft and style content using discrete blocks for text, images, video, and other site elements ...

The post How to parse Gutenberg content for headless WordPress appeared first on Kinsta®.

]]>
Gutenberg is the default editor for WordPress. The editor lets you craft and style content using discrete blocks for text, images, video, and other site elements through a drag-and-drop interface. This approach enhances WordPress’s flexibility and design capabilities.

This guide explains how to parse Gutenberg content as HTML using the WordPress REST API in a Next.js static site.

Prerequisites

To follow along, you need:

Fetch Gutenberg content using a REST API

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

To enable JSON data access via the REST API, adjust your WordPress permalink settings away from “Plain.” This allows API access through a structured URL, as follows:

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

By making API requests to this URL, you can programmatically retrieve various information and perform operations on your WordPress site. For example, you can fetch a list of posts by sending a GET request to:

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

This will return a JSON object containing information about the posts on your WordPress site, including titles, content, author details, and more.

Parse Gutenberg blocks as HTML

When retrieving posts from a WordPress site that uses the Gutenberg editor, the stored content in the database can feature a blend of HTML and JSON metadata to describe various block types, such as quotes and galleries. For instance:

<!-- 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 illustrates two Gutenberg blocks: a Quote and a Gallery. Each is augmented with JSON metadata encapsulated within HTML comments. The metadata defines attributes such as class names, styles, and other configurations relevant to the block’s presentation.

When you fetch these blocks through the WordPress REST API or WPGraphQL, WordPress processes them, transforming the combination of HTML and JSON metadata into fully rendered HTML elements that you can directly incorporate into web pages. The transformed HTML for the above blocks would appear as follows:

<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 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.

<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />

Additionally, you might need to perform further formatting for elements such as links and handle excess newline characters (\n), which this guide explains later.

Parse Gutenberg blocks content into Next.js static site

In this section, let’s fetch WordPress content into a Next.js project and then parse the Gutenberg blocks as HTML.

  1. Start by setting up a function to fetch posts from your WordPress site. Open the src/page.js file in your project and replace its content 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();
    	return posts;
    };

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

  2. Next, let’s utilize the fetched posts within a simple Next.js page component by logging the posts to the console and rendering a basic greeting:
    const page = async () => {
      const posts = await getWpPosts();
      console.log(posts);
      
      return (
        <div>
          <h1>Hello World</h1>
        </div>
      );
    };
    
    export default page;

    When you run your project using npm run dev, it displays the “Hello World” message and logs the fetched posts to 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" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <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.</p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"148\" src=\"https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg\" alt=\"\" class=\"wp-image-14\"/></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 elements.</p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380\" alt=\"\"/></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\">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a href=\"https://yoursite.com/?p=11\">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" : "<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. 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"
        },
        "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 individual Gutenberg post data include various fields, among which the content and excerpt fields are returned as Gutenberg blocks parsed as HTML strings.

  3. To render this HTML content correctly in Next.js, we employ the dangerouslySetInnerHTML property:
    const page = async () => {
      const posts = await getWpPosts();
    
      return (
        <>
          <h1> Headless Blog </h1>
    
          <div>
            {posts.map((post) => (
              <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 this updated component, we map over the fetched posts array to generate a list of post excerpts. Each excerpt is wrapped in a Link component for navigation, displaying the post title and a snippet of its content.

    The dangerouslySetInnerHTML property is used to parse and render the HTML content contained within the excerpt.rendered field.

  4. Next, create a file blog/[id]/page.js within the app directory. You use folders to define routes. So, by creating a blog folder, you define the blog route. You combine this with dynamic routing to generate routes for each post.
  5. Each post has an ID. You use this ID to generate its unique route, /blog/{post_id}in your application. Add the following code:
    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. The getPost() function fetches Gutenberg data from the REST API for the post with a passed ID.

    An earlier section showed sample parsed Gutenberg data returned from the REST API for a post. For now, we are only concerned with the content.rendered field:

    [
      {
        ...
        "content": {
          "rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <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.</p>\n\n\n\n<figure> class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"148\" src=\"https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg\" alt=\"\" class=\"wp-image-14\"/></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 elements.</p>\n\n\n\n<figure> class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380\" alt=\"\"/></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\">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a> href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a> href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Act 3</a></li>\n</ul>\n"
        },
        ...
      }
    ]

    This field contains the post’s raw HTML. It can be rendered directly using the dangerouslySetInnerHTML property like this, <div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />.

  6. Next, you can process the data by parsing internal links and resizing images. Install the html-react-parser package to simplify the process of parsing tags:
    npm install html-react-parser --save
  7. Add the following code to the blog/[id]/page.js file:
    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);
    }

    The fixInternalLinks() function uses a regular expression to find links to posts in your WordPress site from the HTML string. In the raw HTML, you can see that the post contains a List tag with links to other posts on your site, replacing those links with internal links to routes in your static site.

    The parseHTML() function finds multiple sequences of excess newlines, nand replaces them with <br /> tags. It also finds internal links and converts the anchor tags into Link tags. Then, this function resizes images using tag attributes.

  8. To generate the main UI for each dynamic route, 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 your project, the home page will display a list of posts on your WordPress. Also, when you click individual posts, you will see the parsed Gutenberg contents rendered properly.

Deploy your Next.js static site on Kinsta

When combining headless WordPress with cutting-edge frameworks like Next.js, finding a cost-effective deployment solution becomes essential, especially when using a powerful WordPress Hosting like Kinsta’s for your WordPress site. Kinsta’s Static Site Hosting service offers a seamless and affordable way to bring your site online.

Kinsta allows you to host up to 100 static websites for free. First, push your code to a preferred Git provider (Bitbucket, GitHub, or GitLab). Once your repo is ready, follow these steps to deploy your static site to Kinsta:

  1. Log in or create an account to view your MyKinsta dashboard.
  2. Authorize Kinsta with your Git provider.
  3. Click Static Sites on the left sidebar, then click Add site.
  4. Select the repository and the branch from which you wish to deploy.
  5. Assign a unique name to your site.
  6. Add the build settings in the following format:
    • Build command: npm run build
    • Node version: 18.16.0
    • Publish directory: out
  7. Finally, click Create site.

And that’s it! You now have a deployed site within a few seconds. A link is provided to access the deployed version of your site. You can later add your custom domain and SSL certificate if you wish.

As an alternative to static site hosting, you can opt to deploy your static site with Kinsta’s Application Hosting service, which provides greater hosting flexibility, a wider range of benefits, and access to more robust features — like scalability, customized deployment using a Dockerfile, and comprehensive analytics encompassing real-time and historical data. You also don’t need to configure your Next.js project for static rendering.

Summary

This guide has explained how to integrate and parse Gutenberg block content effectively as HTML via the WordPress API. This makes rendering any type of content on your front end possible when you use headless WordPress.

You can host your headless WordPress on our managed WordPress Hosting service and deploy your static site to our Static Site Hosting service. This means everything about your site is in one dashboard: MyKinsta.

By choosing Kinsta, you benefit from a hosting provider that prioritizes optimal site performance and scalability while strongly fortifying websites with advanced security measures. Try Kinsta today!

What do you think about headless WordPress and its rendering? Have a better way to integrate Gutenberg blocks? Share your ideas in the comments section!

The post How to parse Gutenberg content for headless WordPress appeared first on Kinsta®.

]]>
https://kinsta.com/blog/headless-wordpress-gutenberg/feed/ 0
Build a headless blog with WordPress and Frontity https://kinsta.com/blog/frontity/ https://kinsta.com/blog/frontity/#respond Fri, 29 Mar 2024 14:47:30 +0000 https://kinsta.com/?p=176405&preview=true&preview_id=176405 Frontity is a cutting-edge server-side framework designed for swiftly building contemporary websites using WordPress and React. It fetches data from WordPress via a REST API and then uses ...

The post Build a headless blog with WordPress and Frontity appeared first on Kinsta®.

]]>
Frontity is a cutting-edge server-side framework designed for swiftly building contemporary websites using WordPress and React.

It fetches data from WordPress via a REST API and then uses React to generate the final HTML displayed in the browser. You can continue using the WordPress CMS as usual without Frontity. Any changes made in WordPress are hot reloaded on your Frontity site, ensuring real-time updates on the frontend.

This article guides you through integrating Frontity with a headless WordPress site and provides a step-by-step overview of how to deploy your Frontity-powered site on Kinsta.

Prerequisites

To follow along with this tutorial, you need:

Understanding headless WordPress

Traditional WordPress combines content management and display into one platform. You can add content through the WordPress dashboard and display it through a WordPress theme or plugins.

While effective, this approach has limitations — the available themes may be too restrictive, it lacks native support for content delivery across multiple sites, and it relies heavily on plugins for extra features, potentially slowing down your site.

Headless WordPress addresses these issues by decoupling the WordPress CMS from its presentation layer. In this setup, WordPress remains the backend system for content management but you can retrieve its content through the REST API or WPGraphQL and build your website frontend using a tool like Frontity.

This approach has significant advantages:

  • Speed: You can use more efficient, modern web technologies optimized for speed.
  • Scalability: It’s easier to manage traffic surges because you can scale the CMS and the frontend independently.
  • Flexibility: You can use any frontend technology, creating custom, dynamic user experiences without the constraints of WordPress themes and plugins.

Set up your development environment

To begin with Frontity, first, you need an active WordPress installation. Frontity provides a demo WordPress site for every new project you create by default. However, let’s configure a local installation using DevKinsta.

DevKinsta is a WordPress development software suite from Kinsta that lets you install WordPress locally on your computer. It is powered by Docker. If you don’t have Docker Desktop installed, do so from the Docker site.

  1. Visit the DevKinsta download page and choose the installer suitable for your operating system.
  2. Once downloaded, open the file and follow the installation prompts.
  3. If this is your first site in DevKinsta, click New WordPress site. If not, click Add site in the upper-right corner, then select the New WordPress site option.
  4. Fill in your WordPress site name, admin username, and password.
  5. Click Create Site to create the site.
  6. On your site’s dashboard, click WP Admin to open the WordPress admin panel on your browser. Or, click Open Site to view the live site on the browser.

To function properly, Frontity requires your WordPress installation to have pretty permalinks activated. In your WordPress dashboard, navigate to Settings > Permalinks and select Post name to activate it.

WordPress installations now include the REST API. Append /wp-json to your live site’s URL to check it out.

The JSON data you see should look like this:

Screenshot displaying WordPress REST API JSON data output, showing a structured object of name, description, URL, home, gmt_offset, timezone_string, namespaces, authentication, and routes
WordPress REST API JSON data.

This is the API your Frontity site will use as a data source.

Integrate Frontity with WordPress and React

Follow these steps to integrate Frontity with WordPress and React.

  1. Open the terminal, navigate to the directory where you want to create your project and run this command:
    npx frontity create my-app

    Feel free to replace my-app with a different name of your choice for your project.

  2. Then, select a theme:
    Screenshot of a terminal showing the output of running npm frontify create my-app with a prompt to pick a starter theme to clone. The frontity mars-theme is selected
    Frontity theme options.

    Frontity offers two themes: mars-theme and twentytwenty-theme. Pick the recommended theme to finish setting up your project.

  3. Navigate to the new directory. Enter the following command in the terminal to run your project locally:
    npm frontity dev

    This action creates a development server listening on port 3000. If you open http://localhost:3000 on your browser, you should see a web page pre-populated with demo content from Frontity, similar to the one below:

    Screenshot of a webpage titled 'Test Frontity Blog' featuring content from Frontity's demo site. It has navigation links for 'Home', 'Nature', 'Travel', 'Japan', and 'About Us'. The 'Home' page is currently selected, displaying three blog posts. The header background is blue and the rest of the page has a light blue background
    The Frontity mars-theme with demo content.

    By default, in the frontity.setting.js file, the state.source.url is set to https://test.frontity.org/ (the demo WordPress site with the content your site is using). This is the value you’ll modify to point to your WordPress site.

    The frontity.settings.js file is where most of your app’s settings are located, including the data source URL (your WordPress URL), the packages, and the libraries required to run your site.

  4. To connect Frontity with your WordPress site, copy your site’s URL from DevKinsta, append it with /wp-json, and use it for the state.source value in frontity.settings.js. Also, change the state.frontity.url value to your site’s homepage.
    const settings = {
      ...,
      state: {
        frontity: {
          url: "http://your-site-url.com",
          ...
        },
      },
    
      packages: [
        ...,
        {
          name: "@frontity/wp-source",
          state: {
            source: {
              // Change this url to point to your WordPress site.
              api: “http://your-site-url.com/wp-json”
            }
          }
        }
      ]
    }
  5. Because your site will now use the WordPress REST API, change the state.source object name from url to api.
  6. Now, restart your Frontity site. It would display content from your WordPress site:
    Screenshot of a webpage titled 'Test Frontity Blog' featuring content from WordPress Local site. It has navigation links for 'Home', 'Nature', 'Travel', 'Japan', and 'About Us'. The 'Home' page is currently selected, displaying one blog posts titled 'Your first post' The header background is blue and the rest of the page has a white background
    Frontity site connected to local WordPress install.

    Everything should work except the menus, which point to pages you haven’t created yet. The next section explains how to set up pages.

Build a headless blog with Frontity, WordPress, and React

1. Rename the blog

Navigate into the frontity.settings.js file and change your blog’s name, url, title, and description.

const settings = {
  name: "my-travel-blog",
  state: {
    frontity: {
      url: "http://your-site-url.com",
      title: "My Travel Blog",
      description: "Travel Smart, Live Fully",
    },
  },

     //…
 };

If you restart the server, you should be able to view the changes:

Screenshot of a webpage titled 'My Travel Blog' with a tagline 'Travel Smart, Live Fully' featuring content from WordPress local site. It has navigation links for 'Home', 'Nature', 'Travel', 'Japan', and 'About Us'. The 'Home' page is currently selected, displaying one blog post. The header background is blue and the rest of the page has a white background
Frontity site with an updated header.

2. Add pages to the site

The site now has links for nature, travel, Japan, and the About page—all of which point to pages that don’t exist.

Let’s say you only want the About Us page. In this case, you can add it to your WordPress site and remove the links to the rest from the menu:

  1. On the left-hand side menu in your WordPress dashboard, click Pages. This takes you to the pages section, where you can see all your existing pages.
  2. At the top, click Add New to open the page editor.
  3. Enter “About” as the title and use the block editor to add content to the page.
  4. Finally, click Publish.

The next step is to configure the menu.

The Frontity mars-theme hardcodes menu items in frontity.settings.js and exports them to index.js. There’s already a link to the About us page, so you only need to delete the nature, travel, and Japan links from the frontity.settings.js file.

const settings = {
 //…
  packages: [
    {
      name: "@frontity/mars-theme",
      state: {
        theme: {
          menu: [
            ["Home", "/"],
            ["About Us", "/about-us/"],
          ],
          featured: {
            showOnList: false,
            showOnPost: false,
          },
        },
      },
    },

     //…
 };

Your site’s menu should now look like this:

Screenshot of 'My Travel Blog' webpage with the tagline 'Travel Smart, Live Fully', with content from a WordPress local site. Includes navigation links for 'Home' and 'About Us'. The 'About Us' page is active, featuring a heading 'About Us' and the introductory sentence 'This is a travel blog'
Frontity site with updated menu links.

There’s no limit to the number of pages you can have. You can even add categories or tags!

3. Customize your theme

The mars-theme is located in the packages/mars-theme directory of your project. Within this directory, you will find a src folder containing the components folder. To customize the theme, add, modify, or delete these components.

It’s worth noting that the mars-theme components use the Emotion library for styling, meaning they have attached styles. This makes it easier to track down the styles associated with each component.

For example, suppose you want to change the header’s background, locate index in the src/components folder and look for the HeadContainer styles. Then, adjust the background color to green or whichever color you prefer:

const HeadContainer = styled.div`
  display: flex;
  align-items: center;
  flex-direction: column;
  background-color: green;
`;

If you save your changes, Frontity will hot reload your site, and the header should change as shown:

Screenshot of 'My Travel Blog' webpage with the tagline 'Travel Smart, Live Fully', with content from a WordPress local site. Includes navigation links for 'Home' and 'About Us'. The 'About Us' page is active, featuring a heading 'About Us' and the introductory sentence 'This is a travel blog'. The header background is green
Updating the header background to green.

There are many other changes you can make to the components. You can add animations to make your site more dynamic, change the layout of the site, or even add new components.

Deploy the Frontity site to Kinsta

Before deploying your Frontity site to Kinsta, you need to push your site from DevKinsta to Kinsta WP hosting to enable public access.

1. Go to DevKinsta docs and follow the instructions to host your DevKinsta site on Kinsta WP. Then, you can add a domain or use the default domain.

Next, update the data source URL in frontity.settings.js with the new URL:

const settings = {
  ...,
  packages: [
    ...,
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          // Change this url to point to your WordPress site.
          api: “https://your-hosted-site-url.com/wp-json”
        }
      }
    }
  ]
}

You’ll deploy your site from your Git repository, so remember to push your code to your Git provider (Bitbucket, GitHub, or GitLab):

  1. Navigate to your MyKinsta dashboard.
  2. Authorize Kinsta with your preferred Git provider.
  3. Select Applications on the left sidebar, then click Add application.
  4. Select the repository and the branch you wish to deploy from.
  5. Assign a unique name to your app and choose a Data center location.
  6. Select the Standard build machine configuration with the recommended Nixpacks option to configure your build environment.
  7. Add your billing details and click Create application.

The deployment process may take a minute. Once it’s done, Kinsta will provide a URL for your site. Click Visit App to view your hosted site.

Summary

Using traditional WordPress might be sufficient if you’re looking to build a blog quickly. However, if you want to create custom blogs without being constrained by themes or plugins, try Frontity.

Since Frontity is React-based, it’s easy to customize. Thanks to React’s component-based architecture, you can add, modify, or delete components to fit your needs. Once you’ve finished building your site, use Kinsta’s WordPress Hosting to deploy your WordPress site and Application Hosting for your Frontity frontend site — without having to switch platforms.

Headless WordPress is revolutionizing the way we think about content management. Which technologies are you pairing it with? Share with us in the comments section below.

The post Build a headless blog with WordPress and Frontity appeared first on Kinsta®.

]]>
https://kinsta.com/blog/frontity/feed/ 0