I want to build a array that takes my other schema-components so that the user can choose which element they want to have. I then built a textBlock object to have in my other components that I referenced in my main document. Everything works as I want in Sanity Studio but I can’t figure out why it dosen’t work on the page – it says that it can’t read
{block.offerContent.title}
.
I’m appreciative of all given help!!
Products page (main document)
import { defineArrayMember, defineField, defineType } from "sanity";
const products = defineType({
name: "products",
title: "Products",
type: "document",
fields: [
defineField({
name: "title",
title: "Title",
type: "string",
}),
defineField({
name: "slug",
title: "Slug",
type: "slug",
options: {source: 'title'}
}),
defineField({
name: "headerText",
title: "Header text",
type: "text",
}),
defineField({
name: "headerImage",
title: "Header bild",
type: "image",
options: { hotspot: true },
fields: [
{
name: "alt",
title: "Alt",
type: "string",
},
],
}),
defineField({
name: 'content',
type: 'array',
title: 'Innehåll',
of: [
defineArrayMember({
type: 'advantages',
}),
defineArrayMember({
type: 'offer',
}),
defineArrayMember({
type: 'faq',
}),
]
}),
],
});
export default products;
Offer component
import { defineField, defineType } from "sanity";
const offer = defineType({
name: "offer",
title: "Hur vi kan hjälpa till",
type: "object",
fields: [
defineField({
title: 'Titel',
name: 'title',
type: 'string',
}),
defineField({
title: 'Inledande text',
name: 'text',
type: 'text',
}),
defineField({
title: 'Innehåll',
name: 'offerContent',
type: 'textBlock',
}),
],
});
export default offer;
TextBlock component
import { defineField, defineType } from "sanity";
const textBlock = defineType({
name: "textBlock",
title: "Text block",
type: "object",
fields: [
defineField({
title: 'Text',
name: 'content',
type:'array',
of: [{type: "block"}],
}),
],
});
export default textBlock;
My groq query
export async function getProduct(slug: string){
return createClient(clientConfig).fetch(
groq`*[_type == "products" && slug.current == $slug][0]{
_id,
_createdAt,
title,
"slug": slug.current,
headerText,
headerImage{
asset->{
_id,
url
}
},
content[]{
_type == "offer" => {
_type,
title,
text,
offerContent{text},
}
}
}`,
{slug}
)
}
Page where I want to display it:
import { getProduct } from "@/sanity/sanity-utils";
import { PortableText } from "@portabletext/react";
import Image from "next/image";
type Props = {
params: { product: string };
};
export default async function Product({ params }: Props) {
const slug = params.product;
const product = await getProduct(slug);
return (
<div>
<h1>{product.title}</h1>
<PortableText value={product.headerText} />
{product.image ? (
<Image
src={product.headerImage}
alt={product.alt}
width={1000}
height={1000}
/>
) : null}
<div>
{product.content.map((block: any, index: any) => {
switch (block._type) {
case "offer":
return (
<div key={index}>
<p>{block.title}</p>
<p>{block.text}</p>
<PortableText value={block.offerContent.title} />
</div>
);
default:
return null;
}
})}
</div>
</div>
);
}
Amanda Hultén is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.