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.
Table of Contents
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.