Creating new document types

Creating new document types (with routes or not)

When creating new document types, rely on tinloof-remix CLI to scaffold the necessary files for you by running npm run cli:

Running 'tinloof-remix createDocument' in the terminal
? What do you want to do? Create new document (createDocument)
? Document name (ex: "caseStudy") Only letters and dots are allowed newDocument
? Editor-friendly title (ex: "Case Study") New Document
? Has routes in the front-end? Yes
 Created a template in /app/components/templates/NewDocumentTemplate.tsx
 Returned the template in /app/routing/resolveRouteTemplate.ts
 Created a query in /app/queries/route.queries.ts
 Returned route data using this query in /app/routing/resolveRouteData.ts
 Created a TS definition in /app/types/route.types.ts
 Document schema created at /app/sanity/schemas/documents/newDocument.ts
 Document schema included in the studio at /app/sanity/schemas/documents/index.ts
 
 
💡 Go through each of the files above and follow the @TODOs specified in them

What the command does

Creates a new document schema

The schema defines how the documents of this type will be edited in the Sanity Studio.

💡

If you're unfamiliar with Sanity schemas, check out the official documentation (opens in a new tab).

app/sanity/schemas/documents/${newDocumentType}.ts
import { DocumentIcon } from '@sanity/icons'
import { documentSchema } from '../documentSchema'
 
export const caseStudy = documentSchema({
  name: 'caseStudy',
  title: 'Case Study',
  type: 'document',
  // @TODO: replace with descriptive icon
  icon: DocumentIcon,
  custom: {
    // @TODO: validate configuration
    localized: true,
    orderable: false,
    abTest: false,
    hasRoutes: false,
    allowCreation: true,
 
    // @TODO: populate backlinks, if applicable
    backlinks: undefined,
  },
  fields: [
    // @TODO: populate document's schema
    {
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: (Rule) => Rule.required(),
    },
  ],
})

Adds the document to Sanity's schema

The new document type is added to the documents array in app/sanity/schemas/documents/index.ts, so it can be used in the Studio:

app/sanity/schemas/documents/index.ts
// ...
import { newDocumentType } from './newDocumentType'
// %CLI/INJECT-IMPORT%
 
const documents = [
  // ...
  newDocumentType,
  // %CLI/INJECT-VARIABLE%
]

Creates a React component for rendering the document type in the front-end

If the document type has routes in the front-end, the CLI will create a template component for it. This component will be used to render the document type in the front-end.

app/components/templates/NewDocumentTemplate.tsx
import { GlobalLayout } from '~/components/GlobalLayout'
import type { NewDocumentData } from '~/types'
 
const NewDocumentTemplate = (props: NewDocumentData) => {
  return (
    <GlobalLayout {...props}>
      {/* @TODO write template component */}
    </GlobalLayout>
  )
}
 
export default NewDocumentTemplate

Sets-up this component as the default template for the document type in resolveRouteTemplate

app/routing/resolveRouteTemplate.ts
export function resolveRouteTemplate(data) {
  // ...
 
  switch (data?.routeData?._type) {
    // ...
    case 'newDocument':
      // @TODO: review template resolving
      return NewDocumentTemplate
  }
}

Create query to fetch the document type's data in queries/route.queries.ts

app/queries/route.queries.ts
// @TODO: write the query
export const NEW_DOCUMENT_QUERY = /* groq */ `
  ..., // your query here
`

Set-up this query as the way to fetch data for this type's routes in resolveRouteData

app/routing/resolveRouteData.ts
export async function resolveRouteData(doc, context) {
  // ...
 
  switch (_type) {
    // ...
    case 'newDocument':
      // @TODO: make sure to return the data you need for your template
      return configuredQuery({
        query: NEW_DOCUMENT_QUERY,
      })
  }
}

Create Typescript definitions for the route data

By writing TS definitions of your route's data, you make it easier to write and maintain the React components that tap into it. By default, the template will already use the route's data type.

app/types/route.types.ts
export type NewDocumentData = RouteData<{
  localized: true
  DocData: {
    // @TODO: write the TS definitions of this route's data
  }
}>

If the document has no routes: adds the document type to the desk structure

The new document type is added to the items array in app/sanity/deskStructure.ts:

app/sanity/deskStructure.ts
// ...
 
export const deskStructure = buildStructure({
  // ...
  items: [
    // ...
    // %CLI/INJECT-NEW-DOC%
    // @TODO: position and configure New Document Type in desk structure
    { itemType: 'collection', schemaType: 'newDocType' },
  ],
})