Creating a Custom API in Sage 10 and Fetching Data with React

Sage 10 is a powerful modern WordPress starter theme, and combining it with React.js can help create dynamic and interactive components. In this tutorial, we’ll build a custom WordPress REST API endpoint to fetch “Property” posts and display them in a React component using Tailwind CSS.

Step 1: Register the Custom API Endpoint

First, we need to create a custom REST API endpoint that fetches property posts.

Create a Function in app/helpers/api.php

If the api.php file doesn’t exist, create it inside app/helpers/. Then, add the following code:

add_action('rest_api_init', function () {
    register_rest_route('custom/v1', '/properties', [
        'methods'  => 'GET',
        'callback' => 'get_property_posts',
        'permission_callback' => '__return_true',
    ]);
});

function get_property_posts() {
    $args = [
        'post_type'      => 'property',
        'posts_per_page' => -1,
        'post_status'    => 'publish',
    ];

    $query = new WP_Query($args);
    $properties = [];

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            $properties[] = [
                'id'     => get_the_ID(),
                'title'  => get_the_title(),
                'link'   => get_permalink(),
                'image'  => get_the_post_thumbnail_url(get_the_ID(), 'full'),
                'price'  => get_field('property_price'), // Assuming ACF field
                'location' => get_field('property_location'), // Assuming ACF field
            ];
        }
        wp_reset_postdata();
    }

    return rest_ensure_response($properties);
}

This will create an API endpoint at:

https://yourwebsite.com/wp-json/custom/v1/properties

Step 2: Fetch API Data in a React Component

Now, let’s create a React component inside Sage 10 to display the fetched properties.

Install React in Sage 10 (If Not Installed)

If you haven’t already installed React in Sage 10, do so using Bud.js:

npm install @roots/bud-react

Then, enable React in bud.config.js:

export default async (app) => {
  app.use(['@roots/bud-react']);
};

Now, restart the build process:

npm run dev

Step 3: Create the PropertyList.jsx Component

Inside your Sage 10 theme folder (resources/scripts/components/), create a file named PropertyList.jsx and add the following code:

import React, { useEffect, useState } from "react";

const PropertyList = () => {
  const [properties, setProperties] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch("/wp-json/custom/v1/properties")
      .then((response) => response.json())
      .then((data) => {
        setProperties(data);
        setLoading(false);
      })
      .catch((error) => {
        console.error("Error fetching properties:", error);
        setLoading(false);
      });
  }, []);

  if (loading) {
    return <p className="text-center text-gray-600">Loading properties...</p>;
  }

  return (
    <div className="container mx-auto p-4">
      <h2 className="text-2xl font-bold mb-4">Available Properties</h2>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        {properties.map((property) => (
          <div key={property.id} className="border rounded-lg p-4 shadow-lg">
            <img
              src={property.image || "https://via.placeholder.com/300"}
              alt={property.title}
              className="w-full h-48 object-cover rounded"
            />
            <h3 className="text-xl font-semibold mt-3">{property.title}</h3>
            <p className="text-gray-500">πŸ“ {property.location}</p>
            <p className="text-green-600 font-bold">πŸ’° {property.price}</p>
            <a
              href={property.link}
              className="block mt-3 text-blue-500 hover:underline"
            >
              View Details β†’
            </a>
          </div>
        ))}
      </div>
    </div>
  );
};

export default PropertyList;

Step 4: Import and Render the Component in app.js

Now, open resources/scripts/app.js and import the PropertyList component:

import React from "react";
import { createRoot } from "react-dom/client";
import PropertyList from "./components/PropertyList";

document.addEventListener("DOMContentLoaded", () => {
  const propertyContainer = document.getElementById("property-list");
  if (propertyContainer) {
    createRoot(propertyContainer).render(<PropertyList />);
  }
});

Step 5: Display the React Component in a Blade Template

Open resources/views/template.blade.php (or wherever you want to display the properties) and add this:

<div id="property-list"></div>

Now, when you visit your site, the PropertyList component will fetch and display data dynamically! πŸŽ‰

πŸ”₯ Need expert guidance? Let’s collaborate! Reach out at rajanwebdev@gmail.com or connect with me on LinkedIn.

Trustpilot