👀 Our most exciting product launch yet 🚀 Join us May 8th for Sanity Connect

Using locally scoped variables for objects and documents in Sanity schema files.

44 replies
Last updated: Feb 18, 2023
is there a way to define multiple objects and documents in the same file? without having to inform the config with new
schemaTypes
. like I want to create a document type and then use that document type in the same file for a field? is there a way to compile in place the document type and use that immediately or does sanity have to do that for every single object and document type individually first? I find it annoying that I have to update a gigantic array of documents and objects before I can use them.
Feb 18, 2023, 7:09 PM
like this should be allowed but its not.
Feb 18, 2023, 7:14 PM
 defineField({
      name: "sectionBlocks",
      type: "array",
      title: "Content Blocks",
      description: "Add, and edit section blocks",
      of: [
        {
          type: "reference",
          to: [
            { title: "Section Block", type: "sectionBlock" },
            { title: "Form", type: "form" },
            { title: "Tag Index", type: "tagIndex" }
          ],
        },
      ],
    }),
Feb 18, 2023, 7:28 PM
???
Feb 18, 2023, 7:28 PM
You want to reference an array of different types of references?
Feb 18, 2023, 7:29 PM
no
Feb 18, 2023, 7:29 PM
read that again and see my example
Feb 18, 2023, 7:29 PM
Ah... I see, you are creating multiple schema definitions in the same file.
Feb 18, 2023, 7:30 PM
I do keep my schema files separated so that they are easy to manage. However, I did find it annoying to keep adding references all the time to the main schema file so....
Feb 18, 2023, 7:31 PM
I do something like this in my main schema file....
Feb 18, 2023, 7:31 PM
/**
 * OBJECTS : Root
 * Re-usable objects to make life easier
 */
import * as objects from "./objects";
const allObjects = Object.values(objects).map((myObject) => {
  return { ...myObject };
});
Feb 18, 2023, 7:31 PM
mmmm
Feb 18, 2023, 7:32 PM
export default {
  types: [
    ...allDocuments,
    ...allConfigs,
    ...allObjects,
    ...allPlugs,
    ...allTagIndexTypes,
    ...allBlockTypeOptions,
    ...allMotionAnimationOptions
  ],
};
Feb 18, 2023, 7:32 PM
good idea
Feb 18, 2023, 7:32 PM
Note that I have an 'objects' folder where all of my object are.
Feb 18, 2023, 7:32 PM
I just wish I could do what I have in my example. thats how it works in literally every other schema / migration api out there.
Feb 18, 2023, 7:32 PM
I have an index.ts file that looks like this in my objects folder...
Feb 18, 2023, 7:32 PM
export { default as anchor } from './anchor'
export { default as animatedBLockConfig } from './animatedBlockConfig'
export { default as animatedLineConfig } from './animatedLineConfig'
export { default as animationKeysNumbers } from './animationKeysNumbers'
Feb 18, 2023, 7:33 PM
in that example, anchor, animatedBlockConfig, etc. are all their own files
Feb 18, 2023, 7:33 PM
I don't so much mind having it broken down into spearately managed files. But I tend to over document everything and take DRY as far as possible.
Feb 18, 2023, 7:35 PM
That being said... in v3, it is just a javascript file, so technically I suppose you could do what you're suggesting if you combine my approach and yours. Isn't is just named and default exports at the end of the day?
Feb 18, 2023, 7:36 PM
I dont want to export the named example. I want to use that one-off non-reusable object definition in the same file. its not something that will be used in any other schema definition. Like I said sanity is the snowflake here with how it works.
Feb 18, 2023, 7:40 PM
hmmmm... I see what your saying more clearly now. I have to try this. brb
Feb 18, 2023, 7:41 PM
Ha... i got it to work.
Feb 18, 2023, 7:46 PM
defined an object like this...
Feb 18, 2023, 7:47 PM
const wtf = defineType({
  name: "wtf",
  type: "object",
  title: "What the F",
  description:
    "So weird if this doesn't work",
  fields: [
    {
      name: "name",
      title: "Name",
      type: "string",
      description: "Internal Name for Reference Onl",
    }
  ]
})
Feb 18, 2023, 7:47 PM
then in the main schema...
Feb 18, 2023, 7:47 PM
fields []
Feb 18, 2023, 7:47 PM
fields: [
wtf,
defineField({....
]
Feb 18, 2023, 7:48 PM
hmm but what does that make? what if i want to use the document as an array item
Feb 18, 2023, 7:49 PM
hold on
Feb 18, 2023, 7:49 PM
let me try something
Feb 18, 2023, 7:49 PM
fundamentally, if you haven't added an object or document to the schema, you can't reference as if it has been.
Feb 18, 2023, 7:49 PM
ohhhh damn it totally does work
Feb 18, 2023, 7:50 PM
party
Feb 18, 2023, 7:50 PM
i can just do
of: [article]
instead of
of: [{type: article}]
Feb 18, 2023, 7:50 PM
weird, I’ll be damned if any documentation about that being a possibility exists
Feb 18, 2023, 7:51 PM
right... because of:[{type: article}] is trying to reference something that been added to the schema. But you haven't added it so it doesn't know what you're talking about.
Feb 18, 2023, 7:51 PM
damn thanks! this changes literally everything for me
Feb 18, 2023, 7:51 PM
but of: [article] is just basically using a locally scoped variable, sort of.
Feb 18, 2023, 7:52 PM
Cool, glad I could help. I earned good parking Karma for the day.
Feb 18, 2023, 7:52 PM
I see what you did there.
Feb 18, 2023, 7:52 PM
another gotcha is if I want to scope this to a field with its own name I had to do
defineField({
  ...brands,
  name: "field_name",
}),
they should really document this stuff in their schema docs.
Feb 18, 2023, 8:04 PM
More examples would be nice. I would like more examples for creating custom components and schema builder though. I think those things are really lacking.
Feb 18, 2023, 10:46 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?