next.jssanity

in sanity schema type definition how can you define a field of unknown properties?


I am integrating sanity to a NextJS app. Now when i am defining the schema type of a project i run into an error. I want to define a field called features. Features are unique in that i dont know apriori what the features are. For example i want the editor to be able to add key value pairs like

bedrooms -> 2
floors -> 4
length -> 40m

but remember i dont know what those features are so i cant use the object type.

I tried using the object type but that required me to predefine the required fields which obviously didnt seem to work for me.

What data type should i use to achieve the desired functionality or how would you approach such a problem in next js and sanity?

Here is the schema file if you might need it.

export const project: SchemaTypeDefinition = {
  name: "project",
  title: "Project",
  type: "document",
  fields: [
    {
      name: "title",
      title: "Title",
      type: "string",
      description: "Title of the project",
      validation: (Rule) => Rule.required(),
    },
    {
      name: "slug",
      title: "Slug",
      type: "slug",
      options: { source: "title" },
      validation: (Rule) => Rule.required(),
    },
    {
      name: "excerpt",
      title: "Excerpt",
      type: "string",
      description: "a short two sentence description of the project",
      validation: (Rule) => Rule.required(),
    },
    {
      name: "price",
      title: "Price",
      type: "number",
      description: "the price of the project in USD",
    },
    {
      name: "mainImage",
      title: "Main image",
      type: "image",
      description:
        "The face of the project. This image will appear in socials, the shop and more",
      validation: (Rule) => Rule.required(),
    },
    {
      name: "images",
      title: "Images",
      type: "array",
      description: "all other images of the project.",
      of: [
        {
          type: "image",
          fields: [
            {
              name: "alt",
              title: "Alt",
              type: "string",
            },
          ],
        },
      ],
      validation: (Rule) => Rule.required(),
    },
    {
      name: "isPortfolio",
      title: "is portfolio?",
      type: "boolean",
      description:
        "check this if the projects is a portfolio project meaning it can`t be bought.",
    },
    {
      name: "content",
      title: "Content",
      type: "array",
      of: [{ type: "block" }],
      validation: (Rule) => Rule.required(),
      description:
        "use this to create content for your project. Explain what the project is in depth.The better you are at explaining the higher the conversion rate",
    },
    {
      name: "clientDeliverables",
      title: "Client Deliverables",
      type: "array",
      of: [
        {
          type: "file",
          options: {
            accept: ".pdf",
          },
        },
      ],
      description:
        "client deliverables are pdf files the user will download after paying.",
    },
    {
      name: "schematicFile",
      title: "Schematic Drawing File",
      type: "file",
      description:
        "upload the schematic file. remember this file the user will download for free.",
      options: {
        accept: ".pdf",
      },
    },
  ],
};

Solution

  • You should use an array, something like this:

    {
        name: 'features',
        type: 'array',
        title: 'Features',
        of: [
            {
                type: 'object',
                fields: [
                    {
                        name: 'key',
                        title: 'Key',
                        type: 'string',
                    },
                    {
                        name: 'value',
                        title: 'Value',
                        type: 'string',
                    }
                ],
                preview: {
                    ...
                    },
                }
            }
        ],
    },