Slice Machine with Content Relaionship: No documents were returned Nextjs

I struggle with building nested navigation, and I have a Layout Slice with content relationship links to reusable custom types.

Nav Parent               Nav Parent        Nav Parent           Nav Parent               Nav Parent                   
--Nav Link                --Nav Link         --Nav Link            --Nav Link                --Nav Link
--Nav Link                --Nav Link         --Nav Link            --Nav Link                --Nav Link

slices/Layout/index.tsx

const Layout = async ({ slice }: LayoutProps): Promise<JSX.Element> => {
  const client = createClient();

  const footer = await Promise.all(
    slice.items.map((item) => {
      if (isFilled.contentRelationship(item.footer) && item.footer.uid) {
        return client.getByUID("layout", item.footer.uid);
      }
    })
  );

Slice returns an object but throws an error in terminal: Error: No documents were returned

Any help is appreciated!

{
[next]   footer: {
[next]     id: 'ZcZdOxEAAM4m9nxn',
[next]     type: 'menuitems',
[next]     tags: [],
[next]     lang: 'en-us',
[next]     slug: '-',
[next]     first_publication_date: '2024-02-09T17:13:42+0000',
[next]     last_publication_date: '2024-02-09T17:13:42+0000',
[next]     uid: 'for-venues',
[next]     link_type: 'Document',
[next]     isBroken: false
[next]   }
[next] }
[next] {
[next]   footer: {
[next]     id: 'ZcZdSREAAM8m9nyA',
[next]     type: 'menuitems',
[next]     tags: [],
[next]     lang: 'en-us',
[next]     slug: '-',
[next]     first_publication_date: '2024-02-09T17:14:30+0000',
[next]     last_publication_date: '2024-02-09T17:14:30+0000',
[next]     uid: 'for-engineers',
[next]     link_type: 'Document',
[next]     isBroken: false
[next]   }
[next] }
[next]  ⨯ node_modules/@prismicio/client/dist/createClient.js (259:10) @ Client.getFirst
[next]  ⨯ Error: No documents were returned
[next]     at async Promise.all (index 0)
[next]     at async Layout (./src/slices/Layout/index.tsx:17:20)
[next] null
[next]  ⨯ node_modules/@prismicio/client/dist/createClient.js (259:10) @ Client.getFirst
[next]  ⨯ Error: No documents were returned
[next]     at async Promise.all (index 0)
[next]     at async Layout (./src/slices/Layout/index.tsx:17:20)
[next] digest: "1273337650"
[next] null
[next]  ✓ Compiled in 993ms (3299 modules)

You have a custom type called "layout" in addition to a slice named layout? return client.getByUID("layout", item.footer.uid);

Thank you for the reply.

I updated it to

return client.getByUID("menuitems", item.menu_items.uid);

but this error still shows on a browser when I use the slice Layout component in app/layout.tsx

Unhandled Runtime Error
Error: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

Source
src/slices/Layout/index.tsx (27:31) @ all```

  25 | const client = createClient();
  26 |
> 27 | const footer = await Promise.all(
     |                             ^
  28 |   slice?.items.map((item) => {
  29 |     // console.log(item);
  30 |     if (

Another tough one to figure out here.

undefined sure isn't iterable. The name footer shouldn't be a problem, but for me it doesn't make sense as your looking to get menuitems, right?

Is it possible that slice.items is an empty array causing your Promise.all to fail?

slice.items returns an object and renders the nav on the browser but when I passed this slice component to the app/layout.tsx it showed an error that I posted earlier.

{
[next]   menu_items: {
[next]     id: 'ZcZdOxEAAM4m9nxn',
[next]     type: 'menuitems',
[next]     tags: [],
[next]     lang: 'en-us',
[next]     slug: '-',
[next]     first_publication_date: '2024-02-09T17:13:42+0000',
[next]     last_publication_date: '2024-02-11T20:19:08+0000',
[next]     uid: 'for-venues',
[next]     link_type: 'Document',
[next]     isBroken: false
[next]   }
[next] }
[next] {
[next]   menu_items: {
[next]     id: 'ZcZdSREAAM8m9nyA',
[next]     type: 'menuitems',
[next]     tags: [],
[next]     lang: 'en-us',
[next]     slug: '-',
[next]     first_publication_date: '2024-02-09T17:14:30+0000',
[next]     last_publication_date: '2024-02-09T17:14:30+0000',
[next]     uid: 'for-engineers',
[next]     link_type: 'Document',
[next]     isBroken: false
[next]   }
[next] }
}

Your app/layout.tsx file will not have any knowledge of your slice object.
If you're looking to query your menu items to pass to a navigation component, you'll need to fetch them from your layout.tsx file. What I typically do for my navigation components is:

  1. I make a components/Header.tsx // server component where I fetch the Prismic bits I need
  2. I make client components for interactivity components/DesktopMenu.tsx components/MobileMenu.tsx
  3. These client components accept the menuitems as a prop.

I hope that helps.

I pass the slice as a prop to the footer client component

slice/index.tsx
<Footer menuData={menuData} id={slice.id} />

components/Footer/Footer.tsx

"use client";

import { MenuitemsDocumentData } from "../../../prismicio-types";
import { PrismicRichText } from "@prismicio/react";
import { PrismicNextLink } from "@prismicio/next";

export default function Footer({
  menuData,
  id,
}: {
  menuData: MenuitemsDocumentData[];
  id: string;
}) {

  return (
    <ul className="flex flex-col md:flex-row justify-start item-center md:item-left gap-10">
      {menuData &&
        menuData.map((item, index) => {
          // console.log(item);
          return (
            <li key={id + index} className="flex flex-col">
              <PrismicRichText field={item.label} />
              {item.menu_items.map((item, index) => (
                <PrismicNextLink key={index} field={item.label_link}>
                  {item.label_text}
                </PrismicNextLink>
              ))}
            </li>
          );
        })}
    </ul>
  );
}

app/layout.tsx
<Footer />

This is where an error occurs (For some reason, I can't upload a screenshot.).

Type '{}' is missing the following properties from type '{ menuData: MenuitemsDocumentData[]; id: string; }': menuData, idts(2739)

(alias) function Footer({ menuData, id, }: {
menuData: MenuitemsDocumentData[];
id: string;
}): JSX.Element
import Footer

Here's a sample of one of my layout.tsx files:

/**
 * fetch and generate Metadata
 */

export async function generateMetadata(): Promise<Metadata> {
  const client = createClient()
  const settings = await client.getSingle('settings')
  return {
    metadataBase: new URL(`https://${settings.data.domain || `example.com`}`),
    title: settings.data.site_title || 'Fallback Title Goes Here',
    description:
      settings.data.site_meta_description ||
      `Fallback Description Goes Here`,
    openGraph: {
      images: [settings.data.site_meta_image.url || ''],
    },
  }
}

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  return (
    <html lang="en">
      <body
        className={clsx(
          'flex min-h-screen flex-col justify-between',
          playfairDisplay.variable,
          openSans.variable,
          `text-primary-foreground font-opensans`,
        )}
      >
        <Suspense>
          <Analytics />
        </Suspense>

        <Header />
        {children}
        <Footer />
        <Consent />
        <PrismicPreview repositoryName={repositoryName} />
      </body>
    </html>
  )
}

You lost me a little with this `

/* slice/index.tsx */
<Footer menuData={menuData} id={slice.id} />

I assume that the above tsx code is in your Layout. However, you show your layout file as just

<Footer />

I fetched the setting custom type from components/Layout.tsx and used it in app/Layout.tsx and it worked if I have only ONE type in a content relationship (menuitems) -- see fetch below

However, I have two types (menuitems and social_icons).

components/Layout.tsx

 const menuItem = await Promise.all(
   menu?.data.menu_item.map((item) => {
   if (isFilled.contentRelationship(item.menu_item) && item.menu_item.uid) {
      return client.getByUID("menuitems", item.menu_item.uid);
       }
     })
  );

How to fetch two types (menuitems and social_icons)?

{
[next]   id: 'ZcktZhEAAH5M-nJs',
[next]   type: 'menuitems',
[next]   tags: [],
[next]   lang: 'en-us',
[next]   slug: '-',
[next]   first_publication_date: '2024-02-11T20:28:39+0000',
[next]   last_publication_date: '2024-02-11T20:28:39+0000',
[next]   uid: 'support',
[next]   link_type: 'Document',
[next]   isBroken: false
[next] }
[next] {
[next]   id: 'ZckuBREAAJBM-nNP',
[next]   type: 'menuitems',
[next]   tags: [],
[next]   lang: 'en-us',
[next]   slug: '-',
[next]   first_publication_date: '2024-02-11T20:51:19+0000',
[next]   last_publication_date: '2024-02-11T20:51:19+0000',
[next]   uid: 'company',
[next]   link_type: 'Document',
[next]   isBroken: false
[next] }
[next] {
[next]   id: 'ZclGOxEAADpP-pWT',
[next]   type: 'social_icons',
[next]   tags: [],
[next]   lang: 'en-us',
[next]   slug: '-',
[next]   first_publication_date: '2024-02-11T22:12:13+0000',
[next]   last_publication_date: '2024-02-11T22:12:13+0000',
[next]   uid: 'iocns',
[next]   link_type: 'Document',
[next]   isBroken: false
[next] }

Hey again @solution.stack99,
It appears that in your components/Layout file you're grabbing data from prismic in a way that I'm guessing looks like:

const settings = client.getSingle('settings', {
  fetchLinks: ['menuitems.label', 'menuitems.link', 'social_icon.name'] // not sure what props you have on menuitems
})

Does this look close to what you have in this file?

Thank you for helping!

Your fetchLink fetches only the menuitems types. However, I have two types which are menuitems and social_icons.

Would you be willing/able to post the full file where you fetch data from prismic to pass to your components? Also, I added the social_icon to the fetchLinks as I would have if I were using your repo (but I don't know what properties your social_icon has).

Thank you for helping! I found a workaround for this component but I am interested in learning how to fetch multiple TYPS and I will ask with other posts.

1 Like