Using an external JSON file to define options for a list in a Sanity schema file

23 replies
Last updated: Feb 12, 2023
Hello, hope everyone is having a nice day!
I’ve got a schema set up for an array of strings, and I’d like to use a list to create checkboxes for entry. Is it possible to import an external JSON file to define the options for the list rather than listing them in my schema file?

bkgd: I’m using 11ty for my front end and have the options defined in a _data file that I want to use for Sanity so the list is in one place only!
AI Update

Good news – yes, you can absolutely import an external JSON file to define options for your schema! This is a common pattern and keeps your configuration DRY.

Since your schema files are just JavaScript/TypeScript modules, you can import JSON files directly at the top of your schema file and use that data to populate the options.list property. Here's how:

1. Import your JSON file:

import { defineField, defineType } from 'sanity'
import myOptions from '../path/to/your-11ty-data-file.json'

2. Use it in your schema:

export default defineType({
  name: 'myDocument',
  type: 'document',
  fields: [
    defineField({
      name: 'tags',
      type: 'array',
      of: [{ type: 'string' }],
      options: {
        layout: 'checkbox',
        list: myOptions.map(option => ({
          title: option.label, // or whatever your JSON structure uses
          value: option.value
        }))
      }
    })
  ]
})

Important notes:

  • The options.list array expects objects with title and value properties
  • If your JSON is already in that format, you can use it directly: list: myOptions
  • If it's just an array of strings, you can map it: list: myOptions.map(opt => ({ title: opt, value: opt }))
  • Make sure your JSON file is in a location that your Sanity Studio build process can access

For the checkbox layout specifically, set layout: 'checkbox' in the options (as shown above). This works great for arrays of strings where you want multiple selections displayed as checkboxes rather than a dropdown or tags input.

This approach keeps your options in one place (your 11ty _data file), and both your frontend and Sanity Studio will reference the same source of truth. Just remember that if you update the JSON file, you'll need to restart your Studio dev server to see the changes reflected.

There's a Sanity Answers thread that discusses this exact use case if you want to see more examples!

Assuming you are using Sanity V3, I do something similar.
The schema files are basically JavaScript. In theory, you could import the json object and then loop over it to create my schema programatically. Just have to make sure you include all of the required fields.
It could get a bit complicated when you start trying to add validation rules or use keys that have callback function.
Yes, that sounds like exactly what I need to do. I don’t need any validation or callbacks so I can keep it simple.
You would also need to be cautious about removing fields.
the “looping over it” is the part where i need help, and how to set up the 11ty data file to export
In the studio, if fields are removed from the schema users will be prompted to remove data that doesn't have a corresponding field in the schema.
I'm not familiar with 11ty, sorry I can't help there.
ok, so my data file looks like
module.exports = [ item, item, …]
but when I try to import in my sanity with
import skills from '../../web/src/_data/skills';
it gives me an error that
"default" is not exported by "../web/src/_data/skills.js", imported by "schemas/project.ts".
That looks like an import / export issue.Maybe try importing as a named export like...


import { skills } from '../../
This could all be impacted by whether you are using JS or TS and what you TS Config looks like. I can point you in the right direction, but you'll have to do a little digging. I'm finding ChatGPT to be really handy with some of these questions BTW 🙂
I’m using TS, what is ChatGPT?
my tsconfig.json file looks like this:
{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": ["**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
I ask it questions all the time like... "remind me how to use default exports with module.exports in typescript "
thank you for that tip! in this case I think I need a little more human help! lol
user M
do you have any advice based on my TS Config?
Honestly... I just have to muddle through it. It's not likely that your tsconfig is causing the problem here. But here's mine for comparison...

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "esnext",    
    "outDir": "dist", 
    "jsx": "preserve",
    "lib": ["es6", "dom", "es2015", "es2017"],
    "strict": true, 
    "isolatedModules": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
  },
  "include": ["**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules", "sanity.cli.ts", "sanity.config.ts"]
}
My module and target are differrent
Why I love ChatGPT Sometimes. Here's a nice exchange....

Hey GPT, do I have to set module to commonjs to use default and named imports and exports?

FROM GPT
No, you do not have to set the module option to commonjs in order to use default and named imports and exports.

ES6 module syntax (import and export) can be used with other module formats as well, such as amd, umd, and system. However, in order to use ES6 module syntax with Node.js, you'll need to transpile the <https://www.sanity.io/typescript-guide/typescript-vs-javascript|typescript> code into a format that's compatible with Node.js, such as CommonJS. This is why setting the module option to commonjs is a common practice when developing Node.js applications with <https://www.sanity.io/typescript-guide/typescript-vs-javascript|typescript>.

In general, you can choose the module format that works best for your specific use case, and configure the module option in <https://www.sanity.io/typescript-guide/typescript-vs-javascript|typescript> accordingly. Just keep in mind that the output JavaScript code needs to be compatible with the module format that you choose.
thank you
user M
I will continue to try to work with ChatGPT, so far its not my best friend, lol
If it was perfect we might not have a job 🙂
So I think I boiled down the problem is that 11ty needs the file to be a CommonJS export, and the Sanity schema file needs ECMAScript import.
Any chance you have advice on how to solve this problem?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?