gatsby-source-sanity icon indicating copy to clipboard operation
gatsby-source-sanity copied to clipboard

Unable to add custom fields

Open ockam opened this issue 6 years ago • 14 comments
trafficstars

Using onCreateNode in gatsby-node, I’m trying to use a transformer to compile and denormalize some data and then add this new value to the node with createNodeField. The process work fine but the fields object is not appended on my graphql schema.

@rexxars told me (on the Slack channel) that this was intentional, but I really need the ability to transform data at compile time.

ockam avatar May 06 '19 17:05 ockam

+1 , with disabling the createNodefield( if it is intentional ) took away the quite a lot of the flexibility

marvinwu avatar Jul 30 '19 01:07 marvinwu

Any updates here? This doesn't seem to be fixed yet, making things more complicated than they could be.

zielinsm avatar Jan 02 '20 12:01 zielinsm

Just spent two hours this morning trying to debug my build, etc... until finally realizing that this was apparently an issue. I think that if this is an intentional decision it should at least be documented somewhere more obvious.

gristleism avatar Feb 27 '20 16:02 gristleism

You are completely correct @gristleism – we should document this limitation.

evenwestvang avatar Mar 05 '20 07:03 evenwestvang

Hi Sanity team, is there a specific reason for this restriction? As marvinwu and zielinsm pointed out this limits a lot of Gatsby’s awesome functionality.

Some of our projects make extensive use of Gatsby’s node system and Sanity would be an awesome fit with its dynamic content types. But not being able to actually work on top of the Sanity-created nodes lead to a lengthy debugging session and afterwards to strange workarounds in a test setup.

Any chance we can make the custom fields functionality work?

danieljb avatar Apr 02 '20 14:04 danieljb

To clarify: It's not intentional, we just haven't gotten around to fixing this yet. I've put it on the backlog of things to do. No ETA at the moment I'm afraid.

kmelve avatar Apr 11 '20 13:04 kmelve

I agree that this is confusing - especially that you get no error/warning. This is intentional from Gatsby, however: We're declaring the schema types up front - so when you want to only add the field on a single node, that doesn't necessarily make much sense - two nodes of the same type could have a field which returns very different data.

There is a newer API which you can use to add fields to a type, however:

// In your `gatsby-node.js`:
exports.createResolvers = ({createResolvers}) => {
  createResolvers({
    // `SanityBlogPost` being the type name you want to extend
    SanityBlogPost: {
      // `happiness` being the field name you want to add
      happiness: {
        // type is the _GraphQL_ type name, so you can do `String!` for "non-null string", `Int` for integer, `SanityCategory` for a document or object of type  `SanityCategory`.
        type: 'String',
        resolve(source, args, context, info) {
          return 'is customization through GraphQL'
        }
      }
    }
  })
}

There is more info on this API in the Gatsby docs

rexxars avatar Apr 12 '20 06:04 rexxars

Just ran into this issue.

@rexxars Thank you! I think that should be added to the docs since createNodeFields is very popular in a lot of Gatsby projects. Will create a PR when I have the time!

daydream05 avatar Apr 16 '20 18:04 daydream05

Per the Sanity Kitchen Sink, you can also use Gatsby's createSchemaCustomization API to add fields to Sanity types:

exports.createSchemaCustomization = ({ actions, schema }) => {
  actions.createTypes([
    schema.buildObjectType({
      name: "SanityPost",
      interfaces: ["Node"],
      fields: {
        isPublished: {
          type: "Boolean!",
          resolve: (source) => new Date(source.publishedAt) <= new Date(),
        },
      },
    }),
  ]);
};

This has the added benefit of giving you sort and filter functionality for your fields, which doesn't happen when you add them with createResolvers.

aaronadamsCA avatar Jul 14 '20 14:07 aaronadamsCA

I'm strugging with the same isssue and trying to find workarounds.

I'm running the website which should have either Sanity or other CMS integration, and need to unify data schema. Slug field is created using createNodeFiled() for second CMS, and I can't do the same for Sanity (as all other in the topic). I'm trying to map field created by createNodeFiled to something, and can't have access to source.fields object.

Have anyone tried to add a resolver where have access to source.fields object?

turistua avatar Aug 05 '20 16:08 turistua

@turistua If I'm understanding your question correctly, you can find document fields as properties of source in a custom resolver you provide using the createTypes or createResolvers API methods. Examples of both are above, and you'll find (somewhat outdated) Gatsby docs here:

  • https://www.gatsbyjs.org/docs/actions/#createTypes
  • https://www.gatsbyjs.org/docs/node-apis/#createResolvers

I use createTypes because I want to be able to filter/sort by the fields I create, which you won't get if you use createResolvers.

I've experienced some race conditions, however these may be a problem with this plugin as opposed to with Gatsby itself (#83), it's hard to say.

aaronadamsCA avatar Aug 06 '20 19:08 aaronadamsCA

Oh god! 5 hours working :( Wish I had seen this before

kelvinauta avatar Nov 11 '20 11:11 kelvinauta

Any updates on this? The above solutions using createSchemaCustomization or createResolvers wouldn't work for sanity reference fields, the source arg doesn't return the formatted reference field. check this for more info #146 Plus, Gatsby recommends using createNodeField rather than createSchemaCustomization or createResolvers here

AbdallahAbis avatar Feb 20 '22 12:02 AbdallahAbis

I believe setting infer to false (aka. @dontInfer) when creating the schema is the cause.

raae avatar Jun 16 '22 18:06 raae