Ways to reduce impact on Sanity API requests when setting initial values for fields.

3 replies
Last updated: Aug 19, 2021
Hey help community, I'm wondering if there's a way to set an initial value on a doc field using
client.fetch
without having that query fire every time the dashboard loads.
If I set the following on a field, this triggers the fetch multiple times for each field in my schema on studio load and a couple more times on loading/creating a document that contains the field:

name: 'regions',
type: 'array',
initialValue: async () =>
  await client.fetch(
    `*[_type == 'region'] { "_ref": _id, "_type": reference }`
  )
If I set the following on a document, it triggers the fetch once per field in my schema on studio load and a bunch of times on loading/creating this document:

title: 'Post',
type: 'document',
initialValue: async () => ({
  regions: await client.fetch(
    `*[_type == 'region'] { "_ref": _id, "_type": reference }`
  ),
}),
My biggest concern is eating into Sanity API request quota as it would hit the API several times just to navigate around let alone create/manage docs containing this initial value query.

Is there another way to do this without burning through my API request quota? Is there a better way to do this period? Or cache the results until reloading the studio?
Aug 19, 2021, 2:36 AM
Not sure what your use case is, but I have done something similar. Instead of using initial value fields I used initial value templates:
import T from '@sanity/base/initial-value-template-builder'
import sanityClient from 'part:@sanity/base/client'
import { IoIosDesktop } from 'react-icons/io'

const query = '*[_type == "pageTemplates" && title == $title]'
const getTemplate = async (templateTitle: string) => {
  const template = await sanityClient.fetch(
    query,
    { title: templateTitle },
  );
  const {
    title,
    header,
    sections,
    footer,
    parentPage,
  } = template[0]
  return {
    title,
    header,
    sections,
    footer,
    parentPage,
  }
}
export default [
  ...T.defaults(),
  T.template({
    id: 'page-lander-course',
    title: 'Course Lander',
    schemaType: 'pages',
    icon: IoIosDesktop,
    value: async () => await getTemplate('Course Lander'),
  }),
  T.template({
    id: 'page-lander-event',
    title: 'Event Lander',
    schemaType: 'pages',
    icon: IoIosDesktop,
    value: async () => await getTemplate('Event Lander'),
  }),
]
Therefore the template documents are only called once when the page is being created.
https://www.sanity.io/docs/initial-value-templates
Not sure if this works for you.
Aug 19, 2021, 2:59 AM
user V
Thanks for that. Yes, this does help reduce the impact on API requests. I ended up following this path pretty quickly after posting that message and it seems to work well.
I'm wondering still if there's a way to do this without hitting the API more than once per studio load as our "region" data is rarely going to change. Perhaps once or twice over the course of a year or two. Curious, mostly, if there's a way to cache these results somewhere—perhaps the solution is to use something like localstorage?
Aug 19, 2021, 5:22 PM
user M
That's a great idea. I'll take a deeper look into that. That also seems like a great way to that in sync as regions are added and the "defaults" are still set. Wonderful. I'll take a look 🙂
Aug 19, 2021, 6:58 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?