Fields

Content Relationship

This article explains what the content relationship field is and how to configure it.

A screenshot of a content relationship field in the Page Builder.

A content relationship field in the Page Builder.

Content writers can link documents through content relationship fields. Developers can then access content from those documents.

Content relationship fields are often used for:

  • Connecting a blog post to its author.
  • Displaying a testimonial on a landing page.
  • Linking a product to its category.

Add a content relationship to a content model

  • Open Slice Machine

    In your Prismic project, start Slice Machine to begin editing content models.

    npx start-slicemachine --open
  • Add a content relationship field

    In Slice Machine, navigate to the slice, page type, or custom type you want to modify. Add a content relationship field.

    The label determines the label shown to content writers in the Page Builder. Use an easily understood name.

    The API ID determines the property name in the Document API. Use a short, snake-cased name.

  • Select the allowed document type

    You can restrict the field to a specific document type. For example, you can configure the field to only allow Author documents in an Author field.

    In the field’s settings, click the Add type button to select a document type.

    You’ll be able to select fields from that document type to include in the API response in the next step.

  • Select the fields to fetch

    If you restrict the field to a specific document type, you can select which fields to include in the API response.

    Under the Allowed type section, use the field picker to choose which fields should be included. Up to 2 levels of nested fields can be selected (e.g. blog -> author -> profession).

    The selected fields are included in Slice Machine’s generated TypeScript types.

Display content relationships

Content from a related document can be displayed like any other field. The name of a blog post’s author, for example, can be rendered using the <PrismicText> component.

See the fields page

Before accessing nested content, use isFilled.contentRelationship() to ensure the relationship has a document.

{
  isFilled.contentRelationship(post.data.author) && (
    <p>
      Written by <PrismicText field={post.data.author.data?.name} />,
      {isFilled.contentRelationship(post.data.author.data?.profession) && (
        <PrismicText field={post.data.author.data.profession?.data.name} />
      )}
    </p>
  );
}

Learn more about isFilled

Examples

Blog post authors

Landing page testimonials

Taxonomies

Nested menus

API response

Here is what a content relationship looks like from the Document API:

{
  "author": {
    "id": "XxnD3REAACYAk_CJ",
    "type": "author",
    "tags": [],
    "slug": "ada-lovelace",
    "lang": "en",
    "uid": "ada-lovelace",
    "data": {
      "name": [
        {
          "type": "paragraph",
          "text": "Ada Lovelace",
          "spans": []
        }
      ],
      "profession": {
        "id": "ZpqX7SFJJKEBl_VK",
        "type": "profession",
        "tags": [],
        "slug": "mathematician",
        "lang": "en",
        "uid": "mathematician",
        "data": {
          "name": [
            {
              "type": "paragraph",
              "text": "Mathematician",
              "spans": []
            }
          ]
        },
        "link_type": "Document",
        "isBroken": false
      }
    },
    "link_type": "Document",
    "isBroken": false
  }
}

The data property’s contents is determined by the selected fields.

When a selected field is deleted, it’s automatically removed from the API response.

GraphQuery (Legacy)

GraphQuery is a legacy API option that allows selective fetching (specific fields only) and deep fetching (fields from linked documents). This feature is maintained for existing users but is not recommended for new projects.

Basic Usage

GraphQuery uses GraphQL-like syntax. The top-level property represents a document type and its children represent its fields.

Pass the GraphQuery to the Prismic client’s graphQuery option.

const blogPost = await client.getByUID("blog_post", "my-first-post", {
  graphQuery: `
    {
      blog_post {
        title
        description
      }
    }
  `,
});

This example fetches the title and description fields from blog posts.

Arrays

Fields from an array of objects can be selected. Repeatable groups, slice zones, and queries for multiple documents return arrays.

const blogPost = await client.getByUID("blog_post", "my-first-post", {
  graphQuery: `
    {
      blog_post {
        title
        gallery {
          photo
          caption
        }
      }
    }
  `,
});

This example fetches the gallery group array with its photo and caption fields from blog posts.

Unions

Use unions for content that can return multiple kinds of content, like slices, slice variations, or linked documents.

Each kind of content should be listed with desired the fields. Prepend the API ID with ...on:

// Linked documents
const blogPost = await client.getByUID("blog_post", "my-first-post", {
  graphQuery: `
    {
      blog_post {
        author_link {
          ...on author {
            name
            bio
          }
        }
      }
    }
  `,
});

// Slices
const page = await client.getByUID("page", "my-page", {
  graphQuery: `
    {
      page {
        slices {
          ...on text_block {
            primary {
              title
            }
          }
          ...on image_gallery {
            items {
              image
            }
          }
        }
      }
    }
  `,
});

This example fetches a the name and bio fields from a blog post’s author. It also fetches fields from the text_block and image_gallery slices.

Spread Operator

Select all fields from a set using the spread operator with ... and Fields:

const blogPost = await client.getByUID("blog_post", "my-first-post", {
  graphQuery: `
    {
      blog_post {
        ...blog_postFields
        author_link {
          ...on author {
            ...authorFields
          }
        }
      }
    }
  `,
});

This example fetches all fields from the blog post and all fields from the blog post’s author.

TypeScript Support

Type fetched fields using type assertion (the as operator).

import { Content } from "@prismicio/client";

const featuredBlogPost = home.data
  .featured_blog_post as typeof home.data.featured_blog_post & {
  data: Pick<Content.BlogPostDocument["data"], "title" | "description">;
};

const title = featuredBlogPost.data.title;
//    ^ Typed as Content.BlogPostDocument['data']['title']
Was this page helpful?