Hey everyone,
I know there are many topics about content relationship fields in groups and how to access their data using graphquery. But I still can't get it to work. Also TypeScript is always yelling because it don't know of the type properties of the custom type in the relationship field.
I have following setup:
A slice called CompanyGrid
{
"id": "company_grid",
"type": "SharedSlice",
"name": "CompanyGrid",
"description": "CompanyGrid",
"variations": [
{
"id": "default",
"name": "Default",
"docURL": "...",
"version": "initial",
"description": "Default",
"imageUrl": "",
"primary": {
"title": {
"type": "Text",
"config": {
"label": "Title",
"placeholder": ""
}
},
"headline": {
"type": "StructuredText",
"config": {
"label": "Headline",
"placeholder": "",
"allowTargetBlank": true,
"multi": "heading2"
}
}
},
"items": {
"company": {
"type": "Link",
"config": {
"label": "Company",
"select": "document",
"customtypes": [
"company"
]
}
}
}
}
]
}
A company Custom type
{
"format": "custom",
"id": "company",
"label": "Company",
"repeatable": true,
"status": true,
"json": {
"Main": {
"uid": {
"config": {
"label": "UID"
},
"type": "UID"
},
"name": {
"type": "Text",
"config": {
"label": "Name",
"placeholder": ""
}
},
"logo": {
"type": "Image",
"config": {
"label": "Logo",
"constraint": {},
"thumbnails": []
}
},
"description": {
"type": "StructuredText",
"config": {
"label": "Description",
"placeholder": "",
"allowTargetBlank": true,
"multi": "paragraph,strong,em"
}
},
"career_image": {
"type": "Image",
"config": {
"label": "Career Image",
"constraint": {},
"thumbnails": []
}
}
}
}
}
I'm using Next.js App Router. This is my page.tsx with the path 'app/[lang]/[uid]/page.tsx'
import { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { SliceZone } from '@prismicio/react'
import * as prismic from '@prismicio/client'
import { createClient } from '@/prismicio'
import { components } from '@/slices'
import { getLocales } from '@/utils/getLocales'
import Header from '@/app/components/Header'
import Footer from '@/app/components/Footer'
type Params = { uid: string; lang: string }
/**
* This page renders a Prismic Document dynamically based on the URL.
*/
export default async function Page({ params }: { params: Params }) {
const client = createClient()
const page = await client
.getByUID('page', params.uid, {
lang: params.lang,
})
.catch(() => notFound())
const locales = await getLocales(page, client)
const header = await client.getSingle('header')
const footer = await client.getSingle('footer')
return (
<>
<Header data={header.data} lang={params.lang} locales={locales} />
<SliceZone slices={page.data.slices} components={components} />
<Footer data={footer.data} />
</>
)
}
export async function generateStaticParams() {
const client = createClient()
/**
* Query all Documents from the API, except the homepage.
*/
const pages = await client.getAllByType('page', {
predicates: [prismic.filter.not('my.page.uid', 'home')],
lang: '*',
})
/**
* Define a path for every Document.
*/
return pages.map(async (page) => {
return { uid: page.uid, lang: page.lang }
})
}
And this my CompanyGrid Slice
'use client'
import Section from '@/app/components/Section'
import SectionHeadline from '@/app/components/SectionHeadline'
import { Content } from '@prismicio/client'
import { SliceComponentProps } from '@prismicio/react'
import { useEffect } from 'react'
import { Container, Grid } from 'theme-ui'
import { CompanyGridSliceDefaultItem } from '../../../prismicio-types'
/**
* Props for `CompanyGrid`.
*/
export type CompanyGridProps = SliceComponentProps<Content.CompanyGridSlice>
/**
* Grid item component.
*/
const GridItem = ({ item }: { item: CompanyGridSliceDefaultItem }) => {
useEffect(() => {
console.log('item', item)
}, [])
return <div>{item.company.data.name}</div>
}
/**
* Component for "CompanyGrid" Slices.
*/
const CompanyGrid = ({ slice }: CompanyGridProps): JSX.Element => {
return (
<Section
data-slice-type={slice.slice_type}
data-slice-variation={slice.variation}
>
<Container>
<SectionHeadline
title={slice.primary.title}
headline={slice.primary.headline}
hasArrow
/>
<Grid columns={[1, null, 2]} gap={4}>
{slice.items.map((item, index) => (
<GridItem key={index} item={item} />
))}
</Grid>
</Container>
</Section>
)
}
export default CompanyGrid
I want to access the data of the company type on the GridItem Component. I found out that when I add a graphquery to the Page Component that i have access to the data. But when I do this, I can't access the other slices data anymore:
export default async function Page({ params }: { params: Params }) {
const client = createClient()
const page = await client
.getByUID('page', params.uid, {
lang: params.lang,
graphQuery: `
{
page {
slices {
...on company_grid {
variation {
...on default {
items {
company {
...on company {
name
logo
}
}
}
}
}
}
}
}
}
`,
})
.catch(() => notFound())
Is this the right way to do this?
Thanks in advance!
Cheers,
Marvin