How to refer to another field in another schema in Sanity.io

6 replies
Last updated: May 18, 2021
Is it possible to refer to another field in another schema? For example;

export default {
  name: 'referExample',
  title: 'A reference to another field in another schema',
  description: 'For example, to show an address on this page but have it editable on another document',
  type: 'document',
    {
      name: 'address',
      title: 'Address',
      type: 'text',
      readOnly: true,
      initialValue: REF_TO_FIELD_ID_OR_SOMETHING, // this would somehow reference the 'address' field from the 'settings' page
      description: 'This field is set on the settings page',
    },
  ],
};
May 12, 2021, 9:51 AM
The
initialValue
would reference a field from another schema, for example an address, and show it here as a
readOnly
field. This is just for transparency for the client so they can see the address field here too.
May 12, 2021, 9:54 AM
Just a further thought… it would be really cool if these settings could be edited two ways. For example, if I changed the data in the ‘findUs.js’ schema/page, it would update the data from ‘settings.js’ schema/page too
May 12, 2021, 10:57 AM
This could be done with a document Action overriding the document's publish action.
May 12, 2021, 12:10 PM
As for your original question, I think you might want to make an custom input--that will give you the flexibility that you need.
May 12, 2021, 12:13 PM
Hi User. Here’s an effort to get you started, though I can’t promise it’s the best approach to this. It also does not perform the update in reverse. There are two document types:
chrish.js
and
chrishResource.js
.

// chrishResource.js

export default {
  name: 'chrishResource',
  type: 'document',
  fields: [
    {
      name: 'address',
      title: 'Address',
      type: 'text',
    },
  ],
};

// chrish.js

import React, { useState, useEffect } from 'react';
import PatchEvent, { set } from 'part:@sanity/form-builder/patch-event';
import FormField from 'part:@sanity/components/formfields/default';
import { TextArea } from '@sanity/ui';
import sanityClient from 'part:@sanity/base/client';

const client = sanityClient.withConfig({ apiVersion: '2021-05-13' });

const AddressInput = React.forwardRef((props, ref) => {
  const { type, onChange } = props;
  const [address, setAddress] = useState();

  useEffect(() => {
    client.fetch(`*[_type == 'chrishResource'][0].address`).then((res) => setAddress(res));
  }, []);

  return (
    <FormField label={type.title} description={type.description}>
      <TextArea
        ref={ref}
        value={address ?? ''}
        readOnly
        rows={type.rows}
        onChange={(event) => {
          onChange(PatchEvent.from(set(event.target.value)));
        }}
      />
    </FormField>
  );
});

AddressInput.displayName = 'AddressInput';

export default {
  name: 'referExample',
  title: 'A reference to another field in another schema',
  type: 'document',
  fields: [
    {
      name: 'title',
      type: 'string',
    },
    {
      name: 'address',
      title: 'Address',
      type: 'text',
      rows: 4,
      inputComponent: AddressInput,
      description: 'This field is set on the settings page',
    },
  ],
};
The query you set in useEffect would dictate what address you get back.
May 13, 2021, 8:16 PM
Hey
user A
thanks so much for your reply. I didn’t see this until now but this is really helpful 🙂
May 18, 2021, 10:04 AM

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?