@walltowall/gatsby-source-prismic-schemas

Gatsby source plugin for building websites using Prismic custom type schemas as a data source.

This source plugin is useful for creating generated documentation based on your Prismic custom types.

Table of Contents

Features

  • Adds Prismic custom type schemas into Gatsby’s GraphQL store.
  • Supports custom types, tabs, Slice zones, and fields.
  • Creates linked fields between all connected data structures.

Install

npm install --save @walltowall/gatsby-source-prismic-schemas

How to use

// In your gatsby-config.js
plugins: [
  /**
   * Gatsby's data processing layer begins with "source" plugins. Here the site
   * sources its data from Prismic custom type schemas.
   */
  {
    resolve: '@walltowall/gatsby-source-prismic-schemas',
    options: {
      /**
       * Provide an object of Prismic custom type JSON schemas to load into
       * Gatsby. This is required.
       *
       * If you are using gatsby-source-prismic, this should be the same set of
       * schemas provided to that plugin.
       */
      schemas: {
        // Your custom types mapped to schemas
      },
    },
  },
]

Providing JSON schemas

In order for Gatsby to know about your Prismic custom types, you must provide the full JSON schema of each custom type. This is done via the plugin’s schemas option in gatsby-config.js.

The recommended approach is to create a schemas directory in your project and import them into your gatsby-config.js file.

// In your gatsby-config.js
plugins: [
  {
    resolve: 'gatsby-source-prismic-schemas',
    options: {
      // ...
      schemas: {
        page: require('./src/schemas/page.json'),
        blog_post: require('./src/schemas/blog_post.json'),
      },
      // ...
    },
  },
]

Each schema file should be populated with the contents of the “JSON editor” tab in the Prismic Custom Type editor.

Note: The names of your schemas in the schemas object should be exactly the same as your custom type’s API ID. For example, if your API ID is ”blog-post”, your key should be ”blog-post”, not ”blog_post“.

See the official docs for more details on version controlling your custom types: How to version custom types.

How to query

You can query nodes created from your Prismic schemas using GraphQL like the following:

Note: Learn to use the GraphQL tool and Ctrl+Spacebar at http://localhost:8000/___graphql to discover the types and properties of your GraphQL model.

{
  allPrismicSchemaCustomType {
    nodes {
      id
      name
    }
  }
}

All schemas are pulled from your plugin options and created as prismicSchema${nodeType} and allPrismicSchema${nodeType}, where ${nodeType} is one of the following:

  • CustomType
  • Tab
  • Field
  • SliceChoice

For example, if you want to get all Slice choices for a custom type with an API ID of blog_posts, you will be able to query for them like the following:

{
  allPrismicSchemaSliceChoice(
    filter: {
      sliceZone: { tab: { customType: { name: { eq: "blog_post" } } } }
    }
  ) {
    edges {
      node {
        id
        name
      }
    }
  }
}

Query Custom Types

Custom type schemas are the most top-level node. It contains a field to all of its tabs which can be used to query any of its fields or Slices.

The JSON schema is provided on the schema field. Note that this is a JSON field type and does not require querying for individual child fields.

{
  allPrismicSchemaCustomType {
    nodes {
      id
      tabs {
        name
      }
    }
  }
}

Query Tabs

When editing in Prismic, fields are grouped by tabs. You can query for tabs either through the custom type (as seen above) or directly as they are treated as their own nodes.

A tab’s fields are available on the contentFields field.

Tabs are allowed up to one Slice zone. You can query if a Slice zone is present using the hasSliceZone field and query its Slice choices on the sliceZone field.

Note: Gatsby reserves the field named field for internal extensions so contentFields had to be used instead.

{
  allPrismicSchemaTab {
    nodes {
      id
      name
      hasSliceZone
      sliceZone {
        name
      }
    }
  }
}

Query Slice Zones

Slice zones are queryable through tabs (as seen above) or through Slice choices (as seen below).

A Slice zone’s choices are available on the choices field.

The slice’s configuration options are available on the config field. Note that this is a JSON field type and does not require querying for individual child fields.

{
  allPrismicSchemaTab {
    nodes {
      sliceZone {
        id
        name
        description
        choices {
          id
          name
        }
      }
    }
  }
}

Query Slice Choices

Slice choices are queryable either through its Slice zone (as seen above) or directly as they are treated as their own nodes.

A Slice choice’s primary/non-repeat fields are available on the nonRepeatFields field. The choice’s items/repeat fields are available on the repeatFields field.

{
  allPrismicSliceChoice {
    nodes {
      id
      name
      description
      icon
      nonRepeatFields {
        id
        name
      }
    }
  }
}

Query Fields

All custom types are modeled around fields through tabs or Slice choices. All fields have the same set of fields available to you. Fields are queryable through tabs or slice choices or directly as they are treated as their own nodes.

Note that the choices field described in Query Slice Zones is only available for Slice zones (they are treated as fields).

If the field is a Group field, its child fields are available on the contentFields field.

The slice’s configuration options are available on the config field. Note that this is a JSON field type and does not require querying for individual child fields.

{
  allPrismicSchemaField {
    nodes {
      id
      name
      description
      type
    }
  }
}

Site’s gatsby-node.js example

const path = require('path')

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions

  const features = await graphql(`
    {
      allPrismicSchemaCustomType {
        nodes {
          id
          name
        }
      }
    }
  `)

  features.data.allPrismicSchemaCustomType.nodes.forEach(node => {
    createPage({
      path: `/custom-types/${node.name}`,
      component: path.resolve('./src/templates/customType.js'),
      context: {
        id: node.id,
      },
    })
  })
}