Slug

A slug is a unique string (typically a normalized version of title or other representative string), often used as part of a URL. The input form will render an error message if the current slug field not unique (see note on uniqueness below).

Properties

  • typestring

    Value must be set to slug.

Options

  • sourcestring

    The name of the field which the slug value is derived from. You can supply a function, instead of a string. If so, the source function is called with two parameters: doc (object - the current document) and options (object - with parentPath key for easy access of siblings).

  • maxLengthnumber

    Maximum number of characters the slug may contain. Defaults to 200

  • slugifyfunction

    Supply a custom override function which handles string normalization. slugify is called with two parameters: input (string) and type (object - schema type). If slugify is set, the maxLength option is ignored.

  • isUniquefunction

    Supply a custom function which checks whether or not the slug is unique. Receives the proposed slug as the first argument and an options object.

Validation

  • required()function

    Ensures that this field exists.

  • custom(fn)function

    Creates a custom validation rule.

By default, the slug input will check for uniqueness based on the document type and the path to the slug field. For instance, a document of type article and a document of type product can have the same slug. You can customize this behavior by defining an isUnique function in the field options.

The value of the slug field is stored on the current property. The reason for this is that we will soon implement a history property which will store all changes made to the slug value.

Input

{
  title: 'Slug',
  name: 'slug',
  type: 'slug',
  options: {
    source: 'title',
    maxLength: 200, // will be ignored if slugify is set
    slugify: input => input
                         .toLowerCase()
                         .replace(/\s+/g, '-')
                         .slice(0, 200)
  }
}

Output

{
  "_type": "slug",
  "current": "this-is-the-title"
}

Custom slugify function

import sanityClient from 'part:@sanity/base/client'
import slugify from 'some-off-the-shelf-slugifier'

function myAsyncSlugifier(input, type) {
  const slug = slugify(input)
  const query = 'count(*[_type=="movie" && slug.current == $slug]{_id})'
  const params = {slug: slug}
  return sanityClient.fetch(query, params).then(count => {
    console.log('Movies with identical slug', count)
    return `${slug}-${count + 1}`
  })
}

//…
// schema field
{
  title: 'Slug',
  name: 'slug',
  type: 'slug',
  options: {
    source: 'title',
    slugify: myAsyncSlugifier
  }
}

Custom isUnique function

By default the isUnique function checks for uniqueness across all documents of the same type. Here's an example of a isUnique function that checks for uniqueness across all documents in your dataset:


import client from 'part:@sanity/base/client'

// Note: this assumes that every document that has a slug field
// have it on the `slug` field at the root
function isUnique(slug, options) {
  const client = require('part:@sanity/base/client')
  const {document} = options

  const id = document._id.replace(/^drafts\./, '')
  const params = {
    draft: `drafts.${id}`,
    published: id,
    slug
  }

  const query = `!defined(*[!(_id in [$draft, $published]) && slug.current == $slug][0]._id)`

  return client.fetch(query, params)
}

Custom source function

It's also possible to provide source as a function, that will be called with an argument containing the whole document.

{
  title: 'Slug',
  name: 'slug',
  type: 'slug',
  options: {
    source: doc => `${doc.category}-${doc.title}`
  }
}

To query for a document with a given slug, make sure you put the constraint on the current key:

*[_type == "your-document-type" && slugFieldName.current == "your-slug"]