How to Add Internal Links to Top Level Singletons

4 replies
Last updated: Mar 28, 2022
What is the best way to add internal links to my top level singletons using this same cta object?

export default {
  title: "Call to action",
  name: "cta",
  type: "object",
  validation: (Rule) =>
    Rule.custom(
      (fields = {}) =>
        !<http://fields.post|fields.post> || !fields.link || "Only one link type is allowed"
    ),
  fieldsets: [
    {
      title: "Link",
      name: "link",
    },
  ],
  fields: [
    {
      title: "Title",
      name: "title",
      type: "string",
    },
    {
      name: "show",
      title: "Show (leave unchecked to hide CTA)",
      type: "boolean",
    },
    {
      title: "Internal link",
      description: "Use this to link between pages on the website",
      name: "post",
      type: "reference",
      to: [{ type: "post" },{ type: "project" }],
      fieldset: "link",
    },
    {
      title: "External link",
      name: "link",
      type: "url",
      fieldset: "link",
    },
  ],
AI Update

Based on your CTA object schema, you can easily add references to singleton documents by including them in the to array of your post field. Here's how to modify your existing schema:

{
  title: "Internal link",
  description: "Use this to link between pages on the website",
  name: "post",
  type: "reference",
  to: [
    { type: "post" },
    { type: "project" },
    { type: "settings" },      // Add your singleton types here
    { type: "homePage" },
    { type: "aboutPage" },
    // ... any other singleton document types
  ],
  fieldset: "link",
}

The key is that singleton documents are still regular document types in your schema—they just have special configuration to ensure only one instance exists. The reference field works the same way with singletons as it does with regular documents.

Important consideration: Since singletons typically only have one instance, when editors select them in the reference field, they'll see just that single document to choose from. This is actually perfect for your use case—for example, if you have a singleton "Home" page, editors can reference it directly without confusion about which home page to link to.

If you want to make the reference picker clearer for editors, you can add a filter or customize the reference options:

{
  title: "Internal link",
  name: "post",
  type: "reference",
  to: [
    { type: "post" },
    { type: "project" },
    { type: "settings" },
  ],
  options: {
    filter: '_type in $types',
    filterParams: {
      types: ['post', 'project', 'settings']
    }
  },
  fieldset: "link",
}

Your existing validation logic will continue to work perfectly—it ensures editors can only choose either an internal reference (including singletons) OR an external URL, but not both.

Typically I include the singletons in the reference array and deal with handling the slugs in groq.

{
  title: "Internal link",
  description: "Use this to link between pages on the website",
  name: "post",
  type: "reference",
  to: [
    { type: 'home' },
    { type: 'about' },
    { type: 'info' },
    { type: "post" },
    { type: "project" }
  ],
  fieldset: "link",
},
Then something like this in groq:

/* groq */`
  title,
  link,
  post->_type == "project" => {
    "link": "/project/" + post->slug.current
  },
  post->_type == "post" => {
    "link": "/post/" + post->slug.current
  },
  post->_type == "about" => {
    "link": "/about
  }
`
Thanks
user J
user B
Hello .What do you use for coding ? React ?
I'm trying to find a way to add intrenal link in my own website ( not between sanity post ) but couldn't find something working so far with my nextJs project .Thanks
ok find a way with this
  const serializers = {
    marks: {
      link: ({ children, value }) =>
        value.blank === false ? (
          <Link href={value.href}>
            <a className={styles["internal-link"]}>{children}</a>
          </Link>
        ) : (
          <>
            <a
              className={styles["external-link"]}
              href={value.href}
              target="_blank"
              rel="noopener noreferrer"
            >
              {`${children}↗`}
            </a>{" "}
          </>
        ),
    },
Still try to understand how to do link in a post for another post .
Thanks

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?