i am building a webapp with nextjs 14 and using wordpress as headless CMS. One of my pages which purely renders a Client component does not show or fetch the data when i deploy the app on aws but shows and fetch the data on my local machine. I have read the nextjs 14 documentation on CSR and SSR but i cant seem to solve the problem.
I would like to know if it is wrong to fetch data in a client component and render it
This is my Page component
export default async function CaseStudies() {
return (
<>
<CaseStudyClient />
</>
);
}
This is my client component where i fetch and use the data
"use client";
import React, { useState, useEffect } from "react";
const BATCH_SIZE = 2;
function CaseStudyClient({ searchParams }) {
const [industries, setIndustries] = useState([]);
const [selectedIndustry, setSelectedIndustry] = useState("");
const [caseStudyData, setCaseStudyData] = useState([]);
const [selectedOption, setSelectedOption] = useState("DESC");
const [pageInfo, setPageInfo] = useState();
const [loading, setLoading] = useState(true);
const selectedIndustryNoSpaces = selectedIndustry.replace(/\s+/g, "");
const handleIndustryChange = (event) => {
setSelectedIndustry(event.target.value);
};
const query = searchParams?.query || "";
function handleChange(event) {
setSelectedOption(event.target.value);
}
useEffect(() => {
async function fetchInitialData() {
console.log("initial data");
setLoading(true);
let casestudies = await getAllCStudies(
"",
BATCH_SIZE,
null,
null,
null,
selectedOption,
"DATE",
query
);
// let industriesData = await GetTags();
let data = await getCaseStudyCategories();
// console.log(data.edges[0].node.children.edges, "CASE CAT");
setCaseStudyData(casestudies.nodes);
setPageInfo(casestudies.pageInfo);
setIndustries(data.edges[0].node.children.edges);
setLoading(false);
}
fetchInitialData();
}, []);
useEffect(() => {
async function fetchPostsByCategory() {
setLoading(true);
try {
let data;
// Check if 'Allcategories' is selected
if (selectedIndustry === "") {
data = await getAllCStudies(
"",
BATCH_SIZE,
null,
null,
null,
selectedOption,
"DATE"
);
} else if (selectedIndustry) {
data = await getAllCStudies(
selectedIndustryNoSpaces,
BATCH_SIZE,
null,
null,
null,
selectedOption,
"DATE"
);
}
if (query) {
data = await getAllCStudies(
selectedIndustryNoSpaces,
BATCH_SIZE,
null,
null,
null,
selectedOption,
"DATE",
query
);
}
if (data) {
setCaseStudyData(data.nodes);
setPageInfo(data.pageInfo);
}
} catch (error) {
console.error("Error fetching case studies:", error);
} finally {
setLoading(false);
}
}
fetchPostsByCategory();
}, [selectedIndustry, selectedOption, query]);
const handleNext = async () => {
if (pageInfo.hasNextPage) {
let newPosts = await getAllCStudies(
selectedIndustryNoSpaces,
BATCH_SIZE,
pageInfo.endCursor,
null,
null,
selectedOption,
"DATE"
);
setCaseStudyData(newPosts?.nodes);
setPageInfo(newPosts?.pageInfo);
}
};
const handlePrevious = async () => {
if (pageInfo.hasPreviousPage) {
let newPosts = await getAllCStudies(
selectedIndustryNoSpaces,
null,
null,
BATCH_SIZE,
pageInfo.startCursor,
selectedOption,
"DATE"
);
setCaseStudyData(newPosts?.nodes);
setPageInfo(newPosts?.pageInfo);
}
};
console.log(caseStudyData);
console.log(selectedIndustry);
console.log(selectedIndustryNoSpaces);
return (
<>
<Box display={{ mobile: "none", portraitTab: "block" }}>
<CaseStudyCarousel />
</Box>
<Container className="" sx={{}}>
<CustomContainer>
<Box paddingTop={"3rem"}>
<HomeIcon>
<Link href={"/casestudies"}>
{" "}
<Typography
variant="body1"
fontSize={{ mobile: "1.6rem", portraitTab: "1.4rem" }}
fontWeight={"500"}
>
Case Studies{" "}
</Typography>
</Link>
</HomeIcon>
</Box>
<Box marginTop={"5rem"} marginBottom={"7.4rem"}>
<Box
display={"flex"}
justifyContent={"space-between"}
flexDirection={{ mobile: "column", portraitTab: "row" }}
gap={{ mobile: "2rem", portraitTab: "" }}
>
<Typography
variant="h2"
fontSize={{ mobile: "3.8rem", portraitTab: "3.2rem" }}
fontWeight={"500"}
className="text-midnight-blue"
>
Key Solutions We Provided To Top Businesses
</Typography>
<Box sx={{ minWidth: "20rem" }}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">
Clusters
</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={selectedIndustry}
label="All Categories"
onChange={handleIndustryChange}
>
<MenuItem value="">
<em>industries</em>
</MenuItem>
{industries &&
industries.map((item, index) => {
return (
<MenuItem key={index} value={item.node.name}>
{item?.node.name.replace(
/([a-z])([A-Z])/g,
"$1 $2"
)}
</MenuItem>
);
})}
</Select>
</FormControl>
</Box>
</Box>
<Box
display={"flex"}
flexDirection={{
mobile: "column",
portraitTab: "row",
}}
marginBottom={"3rem"}
marginTop={"3rem"}
justifyContent={"space-between"}
>
<Box
display={"flex"}
flexDirection={{
mobile: "column",
portraitTab: "row",
}}
flex={1}
justifyContent={"space-between"}
gap={"3rem"}
>
{" "}
<Box flex={1}>
<Search />
</Box>
<Box
display={"flex"}
alignItems={"center"}
flex={1}
gap={"2rem"}
>
<Typography
variant="h3"
fontSize={{ mobile: "1.8rem", portraitTab: "1.6rem" }}
className={`text-grayish-blue ${openSans.className}`}
style={{ fontWeight: "normal" }}
>
Sort By:
</Typography>
<Box sx={{ width: "20rem" }} flex={1}>
<FormControl fullWidth>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={selectedOption}
label="Sort Post"
onChange={handleChange}
>
<MenuItem value="DESC">
<Typography
variant="h3"
fontSize={{
mobile: "1.6rem",
portraitTab: "1.4rem",
}}
className={`text-grayish-blue ${openSans.className}`}
style={{ fontWeight: "normal" }}
>
Newest Case Studies
</Typography>
</MenuItem>
<MenuItem value="ASC">
<Typography
variant="h3"
fontSize={{
mobile: "1.6rem",
portraitTab: "1.4rem",
}}
className={`text-grayish-blue ${openSans.className}`}
style={{ fontWeight: "normal" }}
>
Least Recent Case Studies
</Typography>
</MenuItem>
</Select>
</FormControl>
</Box>
</Box>
</Box>
<Box
flex={0.5}
display={{
mobile: "none",
portraitTab: "flex",
}}
justifyContent={"flex-end"}
>
<Box
width={"15rem"}
display={"flex"}
justifyContent={"space-between"}
alignItems={"center"}
>
<Box>
{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
color={"#3768B0"}
onClick={handlePrevious}
disabled={pageInfo && !pageInfo.hasPreviousPage}
width={"3rem"}
style={{ cursor: "pointer" }}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M6.75 15.75 3 12m0 0 3.75-3.75M3 12h18"
/>
</svg>
</Box>
<Box>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
color={"#3768B0"}
width={"3rem"}
style={{ cursor: "pointer" }}
onClick={handleNext}
disabled={pageInfo && !pageInfo.hasNextPage}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
/>
</svg>
</Box>
</Box>
</Box>
</Box>
{loading ? (
"loading"
) : (
<Box
display={"grid"}
gridTemplateColumns={{
mobile: "repeat(1 , 1fr)",
portraitTab: "repeat(2 , 1fr)",
}}
gap={"2.5rem"}
marginTop={"5rem"}
>
{caseStudyData.map((item, index) => {
console.log(item);
return (
<Box flex={1} key={index}>
{" "}
<ImagewithSubtitle
src={item.casestudies.mainimage?.mediaItemUrl}
subtitle={item.categories?.nodes[0].name.replace(
/([a-z])([A-Z])/g,
"$1 $2"
)}
alt={item?.title}
// xsWidth={"100%"}
// mdWidth={"31.4rem"}
xsHeight={"35rem"}
mdHeight={"25rem"}
color={"#3768B0"}
fontWeight={"normal"}
iconWidth={"2.5rem"}
xsText={"2.4rem"}
mdText={"1.8rem"}
noArrow={true}
textBgColor={"white"}
noHover={true}
// link={true}
// linkUrl={image.linkUrl}
/>
<Box
sx={{
padding: "3rem 0",
paddingLeft: "1rem",
marginTop: "-2rem",
}}
>
<Typography
variant="body1"
paddingTop={"0.3rem"}
fontSize={{
mobile: "1.9rem",
portraitTab: "1.6rem",
}}
className={`color-primary-bold `}
style={{ fontWeight: "normal" }}
>
{item?.title}
</Typography>
<Typography
variant="body1"
padding={"1.1rem 0"}
fontSize={{
mobile: "1.9rem",
portraitTab: "1.6rem",
}}
className={`text-grayish-blue ${openSans.className}`}
style={{ fontWeight: "normal" }}
>
{item.casestudies.description}
</Typography>
<Link href={`/casestudies/${item?.slug}`}>
<Typography
variant="body1"
fontSize={{
mobile: "1.9rem",
portraitTab: "1.6rem",
}}
sx={{
"&:hover": {
textDecoration: "underline",
},
}}
className={`color-primary-light ${openSans.className}`}
style={{ fontWeight: "normal" }}
>
Learn about their customer journey
</Typography>
</Link>
</Box>
</Box>
);
})}
</Box>
)}
<Box
flex={0.5}
display={"flex"}
justifyContent={"flex-end"}
marginTop={"5rem"}
>
<Box
width={"15rem"}
display={"flex"}
justifyContent={"space-between"}
alignItems={"center"}
>
<Box>
{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
color={"#3768B0"}
onClick={handlePrevious}
disabled={pageInfo && !pageInfo.hasPreviousPage}
width={"3rem"}
style={{ cursor: "pointer" }}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M6.75 15.75 3 12m0 0 3.75-3.75M3 12h18"
/>
</svg>
</Box>
<Box>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6"
color={"#3768B0"}
width={"3rem"}
style={{ cursor: "pointer" }}
onClick={handleNext}
disabled={pageInfo && !pageInfo.hasNextPage}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M17.25 8.25 21 12m0 0-3.75 3.75M21 12H3"
/>
</svg>
</Box>
</Box>
</Box>
</Box>
</CustomContainer>
</Container>
</>
);
}
export default CaseStudyClient;