How to add static text to Sanity document without user input field?

6 replies
Last updated: May 30, 2020
Okay I am certain this has asked before, so sorry for (probably) bringing up an "old question", but how would I add some text into a document without giving the user a field to fill in? I want to add something like:
Hello!

This is
__ page, where you can edit __
AI Update

No worries about asking an "old question" – this comes up fairly often! The solution is to create a custom input component that displays static text without actually rendering an editable field.

The approach from that linked answer page is still valid. Here's the basic idea:

1. Create a custom input component that just displays your text:

// components/IntroTextComponent.js
import React from 'react'
import {Card, Text} from '@sanity/ui'

export default function IntroText(props) {
  const {type} = props
  const {intro} = type.options || {}
  
  return (
    <Card padding={3} radius={2} shadow={1}>
      <Text>{intro}</Text>
    </Card>
  )
}

2. Add it to your schema with the text you want to display:

import IntroTextComponent from './components/IntroTextComponent'

export default {
  name: 'myDocument',
  type: 'document',
  fields: [
    {
      name: 'welcomeText',
      title: 'Welcome',
      type: 'string',
      components: {
        input: IntroTextComponent
      },
      options: {
        intro: 'Hello!\n\nThis is the homepage, where you can edit the main content.'
      },
      hidden: true // Optional: hides it from the field list
    },
    // ... your other fields
  ]
}

Note for Studio v3: The syntax has changed slightly from the old answer. You now use components: { input: YourComponent } instead of inputComponent.

You can make this more sophisticated by:

  • Using Portable Text in the intro option for formatted text
  • Adding dynamic values from the document using props.value or other field values
  • Styling it with Sanity UI components to match your Studio theme

If you want the text to appear but not take up space in the document data, you can also set hidden: true on the field, or use readOnly: true with an initialValue if you need it stored but not editable.

Show original thread
6 replies
This is not as straightforward as it might seem, because you’re looking to use variables in there, for example. You could create a custom input component for this though, one that doesn’t actually show a field 🙂
Have a look at this thread for a general direction and code examples of how to achieve it. You probably won’t need things like the Link import, but the overall principle is the same.


https://sanity-io-land.slack.com/archives/C9Z7RC3V1/p1585700114481400
Let me know if that helps.
This is not as straightforward as it might seem, because you’re looking to use variables in there, for example. You could create a custom input component for this though, one that doesn’t actually show a field 🙂
Have a look at this thread for a general direction and code examples of how to achieve it. You probably won’t need things like the Link import, but the overall principle is the same.


https://sanity-io-land.slack.com/archives/C9Z7RC3V1/p1585700114481400
Let me know if that helps.
It won't let me access posts prior to April 3rd 😕
That must have fallen off the 10k limit cliff just now - I could access it when posting half an hour ago. Sorry about that. I’ll find a way to dig this up for you in about an hour 🙂
No sweat! Highly appreciated! ❤️
Hi again Per after a long hour 😉
So what you could do is create a custom component for this (rough idea):

// myIntroTextComponent.js
import React from 'react'
import PropTypes from 'prop-types'
import FormField from 'part:@sanity/components/formfields/default'

export default class IntroText extends React.Component {
  static propTypes = {
    type: PropTypes.shape({
      title: PropTypes.string,
      options: PropTypes.shape({
        intro: PropTypes.string.isRequired
      }).isRequired
    }).isRequired
  }

  render() {
    const {type} = this.props
    const {intro} = type.options

    return (
      <FormField label={type.title}>
        {intro}
      </FormField>
    )
  }
}
And then include it in your schema as follows:

import MyIntroTextComponent from '../components/myIntroTextComponent'
...
    {
      name: 'hello',
      title: 'Hello!',
      type: 'string',
      inputComponent: MyIntroTextComponent,
      options: {
        intro: 'This is some page, where you can edit something'
      }
    }
...
You can make the above more flexible and add extra options, import a Link component (
import {Link} from 'part:@sanity/base/router'
), or whatever you need, but hopefully the above helps lay the foundation.

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?