Theres a lot of information behind this problem. I'll try to show everything here.
I'm using Hygraph and GraphQL to create a Blog with Headless CMS and on my API call I have the getPostDetails. This is working and my problem is related to content { raw }.
export const getPostDetails = async (slug) => {
const query = gql`
query GetPostDetails($slug: String!) {
post(where: {slug: $slug}) {
title
excerpt
featuredImage {
url
}
author{
name
bio
photo {
url
}
}
createdAt
slug
content {
raw
}
categories {
name
slug
}
}
}
`;
const result = await request(graphqlAPI, query, { slug });
return result.post;
};
I needed to create a way to render all the nodes the hygraph provides when you create a text. So used as example the content I saw on this video (here) at 2:01:36, article details.
'use client'
import React, { useEffect, useState } from 'react';
import { getPostDetails } from '@/app/api';
import { Flex, Grid, GridItem, Heading, Image, Link, Text } from '@chakra-ui/react';
import AdAside from '../../UI/Atoms/AdAside';
export default function PostPage({ params: { slug }}) {
const getContentFragment = (index, text, obj, type) => {
let modifiedText = text;
if (obj) {
if (obj.bold) {
modifiedText = (<b key={index}>{text}</b>);
}
if (obj.italic) {
modifiedText = (<em key={index}>{text}</em>);
}
if (obj.underline) {
modifiedText = (<u key={index}>{text}</u>);
}
if (obj.link) {
modifiedText = (<a key={index} href={obj.nodeId}>{text}</a>);
}
}
switch (type) {
case 'heading-three':
return <Heading as='h3' key={index}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Heading>;
case 'paragraph':
return <Text key={index} maxWidth="1200px" mb={8}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Text>;
case 'heading-four':
return <Heading as='h4' key={index}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Heading>;
case 'image':
return (
<Image
key={index}
alt={obj.title}
height={obj.height}
width={obj.width}
src={obj.src}
/>
);
case 'link':
return <Link key={index} href={obj.nodeId}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Link>
default:
return modifiedText;
}
};
const [pagePost, setPagePost] = useState(null);
useEffect(() => {
const fetchPost = async () => {
try {
if (slug) {
const result = await getPostDetails(slug);
setPagePost(result);
}
} catch (error) {
console.error(error);
}
};
fetchPost();
console.log(pagePost)
}, [slug]);
if (!pagePost) {
return <div>Loading...</div>;
}
return (
<>
<Image
w="100vw"
maxHeight='600px'
objectFit='cover'
alt='banner content'
src={pagePost.featuredImage.url}
/>
<Grid
templateColumns="repeat(12, 1fr)"
gap={1}
px={6}
py={10}
>
<GridItem
gridColumn={{ base: 'span 12', lg: 'span 8' }}
>
<Flex
maxWidth="1200px"
flexDirection="column"
>
<Heading textAlign='left' mb={16}>
{pagePost.title}
</Heading>
<Flex
textAlign="left"
flexDirection="column"
>
{pagePost.content.raw.children.map((typeObj, index) => {
const children = typeObj.children.map((item, itemindex) => getContentFragment(itemindex, item.text, item));
return getContentFragment(index, children, typeObj, typeObj.type);
})}
</Flex>
</Flex>
</GridItem>
<GridItem gridColumn={{ base: 'span 12', lg: 'span 4' }}>
<AdAside />
</GridItem>
</Grid>
</>
);
}
If you see the video you'll see that
if (obj.link) {
modifiedText = (<a key={index} href={obj.nodeId}>{text}</a>);
}
and
case 'link':
return <Link key={index} href={obj.nodeId}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Link>
don't exist there. I included trying to make a way to use hyperlinks. Futhermore, I toke a look in the Hygraph Playground to see what is related to 'link' and there are too properties: nodeId and Href.
The content with hyperlink aren't being rendering and I don't know what I'm doing wrong. I want to use nodeId to pass from a blogpost to another and to use hyperlink to send the user to a external website.
Can you help me?