How Can I Set a Document Type to Be Created With a Sub-Path for the Document ID?

9 replies
Last updated: Mar 8, 2022
Hey there! How can I set a document type to be created with a sub-path for the document ID (i.e. -
private.document-xxxxx
)?
AI Update

Based on the documentation I reviewed, I need to give you an important heads-up about using dots in document IDs like private.document-xxxxx:

Documents with dots in their IDs become private and only accessible via authenticated requests. This is a critical limitation that fundamentally changes how your content works in Sanity.

The Reality of Custom Document IDs

While you can technically create documents with custom IDs like private.document-xxxxx, the official documentation actually recommends against using custom IDs for most use cases. Instead, they suggest creating a custom field in your schema to store identifiers.

Here's why: once you set a document ID with a dot pattern, that document won't be publicly queryable without authentication. This might be what you want, but it's often an unexpected side effect.

If You Still Need Custom IDs

If you genuinely need custom document IDs with dots, here are the legitimate ways to create them:

1. Via the API (Most Common)

import {createClient} from '@sanity/client'

const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  token: 'your-token', // Required for write operations
  apiVersion: '2025-01-01'
})

await client.create({
  _id: 'private.document-xxxxx',
  _type: 'yourDocumentType',
  // ... other fields
})

2. Via the CLI

sanity documents create --id 'private.document-xxxxx'

3. In Studio URL (When Creating New Documents)

Append ;desiredId to the Studio URL when creating a new document:

http://localhost:3333/structure/yourDocumentType;private.document-xxxxx

What About Initial Value Templates?

Initial Value Templates are configured in sanity.config.ts using document.newDocumentOptions, and while the documentation shows they can set initial values, they cannot reliably set custom _id values with dots because:

  1. The Studio's auto-generation may override your custom ID
  2. The privacy implications of dot-prefixed IDs aren't surfaced to editors
  3. It's not the intended use case for templates

Initial Value Templates are better suited for setting field values, not document IDs.

Better Alternatives

Instead of custom IDs with dots, consider:

Option 1: Use a custom field

defineField({
  name: 'customIdentifier',
  type: 'string',
  validation: Rule => Rule.required()
})

Then query by this field instead of _id.

Option 2: Use a naming convention without dots Use underscores or hyphens instead: private_document-xxxxx or private-document-xxxxx. These won't trigger the privacy behavior.

Option 3: Use proper access control If you need private documents, use Sanity's access control features rather than relying on ID patterns.

Important Notes About Document IDs

  • Valid characters: a-zA-Z0-9._- (up to 128 characters)
  • Once set, _id never changes
  • The drafts. prefix is reserved by Sanity
  • Dots in IDs make documents private - this is not just a naming convention, it's a security boundary

The bottom line: if you're just looking for a way to organize or identify documents, use a custom field instead. Custom IDs with dots should only be used when you specifically need the privacy behavior they provide.

user M
yea I had tried that with the initial values template too šŸ˜… but noticed it was striping it
I also tried a custom action that just patched the _id, but apparently that’s immutable so that’s a no-go as well
not sure exactly how to mimic the above with a create intent though šŸ¤”
I'm not sure, either. It would take some playing around on my part to be able to give better direction šŸ˜… . I'm also not sure if the path being stripped is intended functionality, so I'm asking around with the Studio team.
One thing that occurs to me it that I
believe that the Document Internationalization plugin uses subpaths in the ids it creates . It might be worth it to dig around in there and see how they're doing it.
lovely! yea let me know about the stripping of the sub-path, I’ll look into this plugin’s imlementation in the meantime šŸ™‚
Will do!
user M
little update! It looks like the internationalization plugin uses the HTTP API to create duplicate documents with the desired ID and then deletes the original. I can replicate this in a custom document action, that basically creates a new document with the desired ID and then deletes the current one. It’s not the prettiest, since it requires a two step process, so if you find anything out about how to do this more naturally within the studio that would be so rad! šŸ™
user M
kinda digging this solution actually, check it out:
Ah! That's SO COOL! Definitely recommend publishing this to the exchange.
Still haven't heard back re: intended functionality in the Studio, but I'll share this and follow up!

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?