Adding a mailto reference in markdown/BlockContent in Sanity.io

17 replies
Last updated: Jun 16, 2022
Is there a way to add a
mailto:
reference in markdown/BlockContent? I tried the following, to no avail:
[myEmail](mailto:myEmail)

AI Update

Yes, you can add mailto: links in Portable Text (BlockContent)! The issue is that by default, the url field type only validates http and https schemes. To support mailto: links, you need to customize the validation in your block content schema.

Here's how to configure it in your blockContent schema:

export default {
  title: 'Block Content',
  name: 'blockContent',
  type: 'array',
  of: [
    {
      title: 'Block',
      type: 'block',
      marks: {
        decorators: [
          {title: 'Strong', value: 'strong'},
          {title: 'Emphasis', value: 'em'},
        ],
        annotations: [
          {
            title: 'URL',
            name: 'link',
            type: 'object',
            fields: [
              {
                title: 'URL',
                name: 'href',
                type: 'url',
                validation: Rule => Rule.uri({
                  scheme: ['http', 'https', 'mailto']
                })
              },
            ],
          },
        ],
      },
    },
  ],
}

The key is adding the validation rule to your URL field with Rule.uri() and specifying the allowed schemes. This tells Sanity to accept mailto: links in addition to standard http and https URLs. You can see more details in the URL type documentation.

If you want separate fields for email and web links (which can provide a better editor experience), you could create two different annotation types:

annotations: [
  {
    title: 'External Link',
    name: 'link',
    type: 'object',
    fields: [
      {
        title: 'URL',
        name: 'href',
        type: 'url',
        validation: Rule => Rule.uri({
          scheme: ['http', 'https']
        })
      },
    ],
  },
  {
    title: 'Email Link',
    name: 'emailLink',
    type: 'object',
    fields: [
      {
        title: 'Email',
        name: 'href',
        type: 'url',
        validation: Rule => Rule.uri({
          scheme: ['mailto']
        })
      },
    ],
  },
]

On your frontend, you'll need to render these annotations as links. The annotation data will be available in the markDefs array of your Portable Text blocks, and you can use @portabletext/react (or the appropriate package for your framework) to serialize them into clickable links. The newer @portabletext/react package has replaced the deprecated @sanity/block-content-to-react library.

url won’t validate a mailto automatically, you could use a string and create a custom validation rule
I need this to be markdown unfortunately, as this piece of formatted text content must feature an email that users can click on.
What do you mean by custom validation rule?
You need to implicitly add
mailto
in the options
Awesome I didn’t know about that
as this piece of formatted text content must feature an email that users can click on.
on the front end?
Using the annotation (as you’ve done) in Studio will allow you to make it a link in the front-end
I'm assuming you mean to add this as an option within my
blockContent
schema , not in this particular document's schema, right?
as in, in here? (near the bottom)

export default {
  title: 'Block Content',
  name: 'blockContent',
  type: 'array',
  of: [
    {
      title: 'Block',
      type: 'block',     
      styles: [
        {title: 'Normal', value: 'normal'},
        {title: 'H1', value: 'h1'},
        {title: 'H2', value: 'h2'},
        {title: 'H3', value: 'h3'},
        {title: 'H4', value: 'h4'},
        {title: 'Quote', value: 'blockquote'},
      ],
      lists: [{title: 'Bullet', value: 'bullet'}],
  
      marks: {
        decorators: [
          {title: 'Strong', value: 'strong'},
          {title: 'Emphasis', value: 'em'},
        ],
        annotations: [
          {
            title: 'URL',
            name: 'link',
            type: 'object',
            fields: [
              {
                title: 'URL',
                name: 'href',
                type: 'url',
              },
            ],
          },
        ],
      },
    },
    {
      type: 'image',
      options: {hotspot: true},
    },
  ],
}
yeah, here
annotations: [
          {
            title: 'URL',
            name: 'link',
            type: 'object',
            fields: [
              {
                title: 'URL',
                name: 'href',
                type: 'url',
validation: Rule => Rule.uri({
    scheme: ['http', 'https', 'mailto']
  })
              },
            ],
          },
        ],
If it’s just email addresses, you could rename it
{
                title: 'Email address',
                name: 'email',
                type: 'url',
validation: Rule => Rule.uri({
    scheme: ['mailto']
})
}

it should be also usable for external links
Let me check if this worked 🙂
btw I think you mean
Rule.url
not .uri correct?
Worked! Thanks so much 🙂

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?