Dyrecteddyrected
Core Concepts

Collections & Globals

The two building blocks of a Dyrected content model — when to use each and what they give you.

Every Dyrected project is made of two primitives: collections and globals. Together they define your content model, your database schema, your REST API, and your Admin UI — all from one config file.


Collections

A collection is for content that has more than one instance — blog posts, products, users, orders, form submissions. Each entry is a separate document with its own id.

export const Posts = defineCollection({
  slug: 'posts',
  fields: [
    { name: 'title', label: 'Title',  type: 'text',   required: true },
    { name: 'status', label: 'Status', type: 'select', options: ['draft', 'published'] },
  ],
})

Defining a collection gives you, automatically:

What you getDetail
List endpointGET /api/collections/posts — paginated, filterable, sortable
Single endpointGET /api/collections/posts/:id
Create endpointPOST /api/collections/posts
Update endpointPATCH /api/collections/posts/:id
Delete endpointDELETE /api/collections/posts/:id
List page in Admin UISearchable table with configurable columns
Edit page in Admin UIForm generated from your fields array
SDK methods.collection('posts').find(), .findOne(), .create(), .update(), .delete()

Globals

A global is for content that has exactly one instance — site settings, a navigation menu, a homepage hero, legal copy. There is no list; there is only one document, and it is always there.

export const SiteSettings = defineGlobal({
  slug: 'site-settings',
  fields: [
    { name: 'siteName', label: 'Site Name',    type: 'text' },
    { name: 'logoUrl', label: 'Logo Url',     type: 'url' },
    { name: 'primaryColor', label: 'Primary Color', type: 'text' },
  ],
})

Defining a global gives you:

What you getDetail
Get endpointGET /api/globals/site-settings
Update endpointPATCH /api/globals/site-settings
Edit page in Admin UISingle form — no list, no create button
SDK method.global('site-settings').get(), .update()

The decision rule

Does this content have more than one instance? — Yes → Collection — No → Global

When in doubt, apply it literally:

ContentTypeWhy
Blog postsCollectionMany posts
ProductsCollectionMany products
Users / membersCollectionMany users
OrdersCollectionMany orders
Contact form submissionsCollectionMany submissions
Site settingsGlobalOne set of settings
Navigation menuGlobalOne nav
Homepage heroGlobalOne hero section
Cookie policy textGlobalOne document
SEO defaultsGlobalOne set of defaults

If you think you need two globals for the same concept (e.g. "desktop nav" and "mobile nav"), that is usually a sign the nav structure should be a field on a single global, not two globals.


Both live in defineConfig

// dyrected.config.ts
import { defineConfig } from '@dyrected/core'

export default defineConfig({
  db: adapter,
  collections: [Posts, Products, Users],
  globals: [SiteSettings, Navigation],
})

The order of entries in each array controls the order they appear in the Admin UI sidebar.


What the slug controls

The slug is the identifier used everywhere — in API paths, SDK calls, and the Admin UI URL. It must be unique across all collections and globals, lowercase, and hyphenated.

// slug: 'site-settings'
// → API:   GET /api/globals/site-settings
// → SDK:   cms.global('site-settings').get()
// → Admin: /admin/globals/site-settings

Next steps

On this page