Properties Page
Creating Properties Page Components
Preparations
Add properties.json file in your project root directory:
Create properties images folder in public folder as follows: public>images>properties and then add all images in images>properties folder
1. Set Up the Properties Page
a. Update the Properties Page File
In your Next.js project, update a Page.jsx file for the properties page. For example:
app/properties/page.jsx
This file will serve as the main page where all property listings are displayed.
b. Import the JSON Data
Place your
properties.json
file in an accessible location (e.g., in the project root or in a/data
folder).In your
page.jsx
file, import the JSON data://app/properties/page.jsx //import Link from 'next/link' import properties from '@/properties.json'; // Adjust the path as needed function Properties() { return ( <> {/* <h1 className="text-3xl"> Welcome to Property Page </h1> <Link href="/"> Go to Home </Link> */} </> ) } export default Properties
find <!— All Listings --> comment section and just copy first three lines of code and past them to page,jsx
//app/properties/page.jsx
//import Link from 'next/link'
import properties from '@/properties.json'; // Adjust the path as needed
function Properties() {
return (
<>
<section class="px-4 py-6">
<div class="container-xl lg:container m-auto px-4 py-6">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
</div>
</div>
</section>
</>
)
}
export default Properties
2. Build the Page Structure
a. Create a Container for Listings
Start by creating a section element that holds your property listings. You can copy the outer container markup from your theme file:
import properties from '@/properties.json'; // Adjust the path as needed function Properties() { return ( <section className="container mx-auto px-4 py-6"> <h2 className="text-3xl font-bold text-blue-500 mb-6 text-center">All Listings</h2> {/* Listings grid will go here */} {properties.map((property) => ( <div> {property.name} </div> ))} </section> ); } export default Properties
b. Implement Conditional Rendering for Empty Data
Before rendering the listings, check if the properties array is empty and display a message if so:
import properties from '@/properties.json'; // Adjust the path as needed function Properties() { return ( <section className="container mx-auto px-4 py-6"> <h2 className="text-3xl font-bold text-blue-500 mb-6 text-center">All Listings</h2> {properties.length === 0 ? ( <p>No properties found.</p> ) : ( <div className="grid grid-cols-1 md:grid-cols-3 gap-6"> {properties.map((property) => ( <p key={property._id}> {property.name} </p> ))} </div> )} </section> ); } export default Properties
3. Render the Property Listings
a. Loop Through the Properties Data
Use JavaScript’s
.map()
to iterate through the properties array and render each listing as a card:{properties.map((property) => ( <PropertyCard key={property._id} property={property} /> ))}
Insert this code inside the grid container from the previous step.
4. Create the Property Card Component
a. Create a New Component File
In the
components/
folder, create a new file namedPropertyCard.jsx
:components/PropertyCard.jsx
b. Build the Component Structure
Copy the relevant HTML markup for a property listing from your theme’s
properties.html
(the markup between the listing divs) intoPropertyCard.jsx
.Modify the static content to dynamically display property data using the
property
prop.Example:
function PropertyCard({ property }) { return ( <div className="bg-white rounded-xl shadow-md relative flex flex-col md:flex-row"> <img src={`/images/properties/${property.images[0]}`} // Assuming the first image exists alt={property.name} className="object-cover rounded-t-xl md:rounded-tr-none md:rounded-l-xl w-full md:w-2/5" /> <div className="p-6"> <h3 className="text-xl font-bold">{property.name}</h3> <div className="text-gray-600 mb-4">{property.type}</div> {/* Display rates if available */} {property.rates && ( <h3 className="absolute top-2 left-2 bg-white px-4 py-2 rounded-lg text-blue-500 font-bold"> {property.rates.nightly ? `$${property.rates.nightly}/wk` : 'Contact for rates'} </h3> )} <div className="flex justify-between items-center"> <div className="flex gap-2 text-gray-500"> <p> <i className="fa-solid fa-bed"></i> {property.beds} </p> <p> <i className="fa-solid fa-bath"></i> {property.baths} </p> <p> <i className="fa-solid fa-ruler-combined"></i> {property.squareFeet} sqft </p> </div> <Link href={`/property/${property._id}`}> <a className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg text-sm"> Details </a> </Link> </div> </div> </div> ); } export default PropertyCard
Note: Adjust the paths and markup as needed to match your actual JSON structure and theme design.
5. Integrate the Property Card Component
a. Import the PropertyCard Component
In your
app/properties/page.jsx
file, import the component at the top:import PropertyCard from '@/components/PropertyCard';
b. Use the Component in the Map Function
Replace the placeholder div in your
.map()
loop with the<PropertyCard />
component, passing the property data as props:<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> {properties.map((property) => ( <PropertyCard key={property._id} property={property} /> ))} </div>
6. Leverage Next.js Rendering Strategies
a. Server Rendering for Static Data
Since the properties data is coming from a static JSON file, you can leverage Next.js’s server components or static generation to render this page.
In Next.js 13+ with the app directory, pages are server components by default, which means the data is fetched at build time or request time and the page is rendered on the server.
b. Future Enhancements
Once you integrate an API or database, you can modify the data fetching strategy (e.g., using
getStaticProps
orfetch
inside server components) without affecting your component structure.
7. Test and Refine
a. Run the Development Server
Start your Next.js server:
npm run dev
Navigate to http://localhost:3000/properties and verify that:
The container displays a heading and the grid.
If there are no properties, the “No properties found” message appears.
Each property from your JSON data is rendered as a PropertyCard with dynamic content.
b. Adjust Styling and Layout
Refine the Tailwind CSS classes and layout to match your desired design.
Verify responsiveness on different screen sizes.
Recap
Properties Page Setup: Create a dedicated page that imports data from a JSON file and conditionally renders a grid of property listings.
Dynamic Rendering: Use
.map()
to iterate over the properties and render each one with a reusable PropertyCard component.Component Reusability: Build a PropertyCard component that dynamically displays property details, leveraging the structure provided in your theme files.
Next.js Rendering: Leverage Next.js server components (default in the app folder) for efficient, server-side rendering of static data, with room for future API integration.
Last updated