Mastering the art of connecting content within Prismic

I have been working on creating a mega menu for my website header, but I am encountering a type error. Has anyone else faced this issue before and how did you resolve it? I am currently importing the generated types from @/prismicio-types.

Here is an example of my client query:

export default async function getHeaderSettings(
  client: Client<AllDocumentTypes>
): Promise<HeaderDocument<string>> {
  return client.getSingle('header', {
    graphQuery: `
          {
              header {
                  logo
                  menu {
                      label
                      is_link
                      link
                      submenu {
                          cta_image
                          menu {
                              item {
                                  ...itemFields
                              }
                          }
                      }
                  }
              }
          }
      `,
  });
}

The above query fetches the necessary data that gets passed into the header component:

interface IHeader {
  data: Simplify<HeaderDocumentData>;
}

However, I'm facing an issue when trying to access the submenu data, resulting in the following error:

Property 'data' does not exist on type 'ContentRelationshipField<"header_submenu">'.
  Property 'data' does not exist on type 'EmptyLinkField<"Document">'.
const formatHeaderData = (data: Simplify<HeaderDocumentData>) => {
  const { menu, logo } = data;

  const formattedMenu = menu.length
    ? menu.map((item) => {
        return {
          label: item.label,
          is_link: item.is_link,
          link: item.link,
          submenu: {
            cta_image: item.submenu.data.cta_image,
            menu: item.submenu.data.menu.map((subMenuItem) => {
              return {
                menu_label: subMenuItem.item.data.menu_label,
                menu: subMenuItem.item.data.menu,
              };
            }),
          },
        };
      })
    : [];
  
  return {
    logo,
    menu: formattedMenu,
  };
};

Answer №1

The HeaderDocument type you are using does not automatically include the types for content relationship fields. To address this, one approach is to modify the return type of the getHeaderSettings function.

Here's an example illustrating one level of nesting (additional levels will need to be added):

import type { Content } from '@prismicio/client';

type HeaderWithMenuDocument =
  Content.HeaderDocument & {
    data: {
      menu: Content.MenuDocument;
    };
  };

After defining the above structure, update the return type of your function as follows:

export default async function getHeaderSettings(
  client: Client<AllDocumentTypes>
): Promise<HeaderWithMenuDocument>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to incorporate cors modules in TypeScript?

I am encountering some difficulties while attempting to import the cors module in a TypeScript project using Express. When I use the following code: import cors from "cors"; I receive the following error message: "Cannot find module &apos ...

Using selectors and mappers in Typescript generics

I am looking to create a versatile selector and mapper method. interface State { user: { name: string; age: number; } } const pickName = (state: State) => state.user.name; const selectAge = (state: State) => state.user.age; ...

Using Tailwind CSS to set the margin of an element at certain breakpoints is not functioning as expected

I attempted to customize the margin of a div element at specific screen sizes by using a {screen}: prefix, but it did not have the desired effect. Here is what I tried: <div className={'flex justify-center'}> <div className={'w-fu ...

Error in Angular6: Why can't handleError read injected services?

It appears that I am facing an issue where I cannot access a service injected inside the handleError function. constructor(private http: HttpClient, public _translate: TranslateService) { } login(user: User): Observable<User> { ...

Creating a DynamoDB table and adding an item using CDK in Typescript

Can anyone guide me on how to add items to a Dynamodb Table using CDK and Typescript? I have figured out the partition/sort keys creation, but I am struggling to find a straightforward solution for adding items or attributes to those items. Additionally, ...

Using Typescript to pass an interface as an argument to a function that requires a JSON type

Here is an extension related to the topic of Typescript: interface that extends a JSON type Consider the following JSON type: type JSONValue = | string | number | boolean | null | JSONValue[] | {[key: string]: JSONValue} The goal is to inform type ...

What is the correlation between single-page applications and server-side rendering?

My issue lies in grasping the concept of how server-side rendering single-page application frameworks like Next.js are able to receive pre-rendered full HTML on the front end without having to completely rewrite the entire page. The Next.js website explain ...

The optimal location to declare a constructor in Typescript

When it comes to adding properties in an Angular component, the placement of these properties in relation to the constructor function can be a topic of discussion. Is it best to declare them before or after the constructor? Which method is better - Method ...

Guide to importing a function exclusively on the client side in Next.js

Being a beginner in Next.js, I humbly ask for your understanding of any errors on my part. I have a function utilizing axios that should only be executed on the client side, as it involves localstorage. While dynamic imports are suitable for components, ...

Hover Effect for 3D Images

I recently came across an interesting 3D Hover Image Effect that I wanted to implement - https://codepen.io/kw7oe/pen/mPeepv. After going through various tutorials and guides, I decided to try styling a component with Materials UI and apply CSS in a differ ...

Retrieving a single object in NEXT.JS and MongoDB can be achieved by returning just a single object

Is there a way to retrieve a single object instead of an array from the API? I am specifically looking for just a single "Event" while using MongoDB and Next.js. Currently, I always receive: [{}] But I would like to receive: {} const fetchWithId = (url ...

Adding text in CKEditor with Angular while preserving the existing formatting

To add my merge field text at the current selection, I use this code: editor.model.change(writer => { var position = editor.model.document.selection.getFirstPosition(); // trying to connect with the last node position.stickiness = 'toP ...

The value of type 'string' cannot be assigned to type '"menu" | "selectedMenu" | undefined' as it is not compatible with the specified types

I'm working on creating a multiple select feature using TypeScript, material-ui, and React. I am encountering an error when trying to set MenuProps.variant = 'menu'. The error message reads: "Type '{ variant: string; PaperProps: { styl ...

type of key extractor is unknown in React Native

How can I specify a type for the renderItem function of a FlatList in React Native? This is my current approach: // Importing the generic type for the FlatList render item function import { ListRenderItem } from "react-native"; // Assigning the ...

Is it possible to restrict optionality in Typescript interfaces based on a boolean value?

Currently, I am working on an interface where I need to implement the following structure: export interface Passenger { id: number, name: string, checkedIn: boolean, checkedInDate?: Date // <- Is it possible to make this f ...

The getInitialProps function in Next.js React components does not automatically bind props

When building applications with Next.js, you have the opportunity to leverage a server-side rendering lifecycle method within your React components upon initial loading. I recently attempted to implement this feature following instructions from ZEIT' ...

Difficulty encountered when attempting to create a lambda function in TypeScript

I'm having trouble understanding the following lambda function definition in TypeScript. It could be a beginner question. type P = { id: string } type F = <T>(x: T) => string const f: F = (x: P) => x.id f({ id: 'abc' } However, ...

Error: The URL constructor is unable to process /account as a valid URL address

Working on a new social media app using appwrite and nextjs, encountering an error "TypeError: URL constructor: /account is not a valid URL" upon loading the website. Here's the current file structure of my app: File Structure Below is the layout.tsx ...

When using a functional component as the initial state value, make sure to wrap it in React.memo to avoid

I'm facing an issue when trying to set the DefaultLayout component as the initial state value. The error message "cannot destructure property children of undefined" is thrown. Interestingly, wrapping the DefaultLayout component in React.memo resolves ...

Create an HTTP-only cookie through the next API

Having trouble setting a cookie using my Next.js API. I attempted to use "res.cookie" (similar to ExpressJS), but it seems that res.cookie is undefined in my API. The 'cookie' property itself is the one coming up as undefined, not the entire &ap ...