Referência de tipos de campo

Nesta página

O EmDash oferece 17 tipos de campo para definir esquemas de conteúdo. Cada tipo corresponde a um tipo de coluna SQLite e fornece a UI de administração adequada.

Visão geral

A tabela a seguir lista cada tipo de campo e sua coluna SQLite:

TypeSQLite ColumnDescription
stringTEXTEntrada de texto curto
textTEXTTexto multilinha
urlTEXTValor de URL
numberREALNúmero decimal
integerINTEGERNúmero inteiro
booleanINTEGERVerdadeiro/falso
datetimeTEXTData e hora
selectTEXTEscolha única entre opções
multiSelectJSONEscolhas múltiplas
portableTextJSONConteúdo de rich text
imageTEXTReferência de imagem
fileTEXTReferência de arquivo
referencenoneLiga entradas de outra coleção
jsonJSONDados JSON arbitrários
slugTEXTIdentificador seguro para URL
repeaterJSONGrupo de campos repetível
blocksJSONComposição de página tipada

Tipos de texto

string

Texto curto de uma linha. Use para títulos, nomes e valores curtos.

{
  slug: "title",
  label: "Title",
  type: "string",
  required: true,
  validation: {
    minLength: 1,
    maxLength: 200,
  },
}

Opções de validação:

  • minLength — Contagem mínima de caracteres
  • maxLength — Contagem máxima de caracteres
  • pattern — Expressão regular que o valor deve corresponder

O editor limita a entrada a maxLength e mostra uma contagem de caracteres ao vivo em relação às regras de comprimento.

Opções do widget:

  • Nenhuma específica

text

Texto simples multilinha. Use para descrições, trechos e texto simples mais longo.

{
  slug: "excerpt",
  label: "Excerpt",
  type: "text",
  options: {
    rows: 3,
  },
}

Opções de validação:

  • minLength — Contagem mínima de caracteres
  • maxLength — Contagem máxima de caracteres
  • pattern — Expressão regular que o valor deve corresponder

O editor limita a entrada a maxLength e mostra uma contagem de caracteres ao vivo em relação às regras de comprimento.

Opções do widget:

  • rows — Número de linhas no textarea (padrão: 3)

url

Um endereço web. A API de conteúdo rejeita valores que não são URLs válidas.

{
  slug: "website",
  label: "Website",
  type: "url",
  required: true,
}

Campos URL são armazenados como texto. Use um campo string quando o valor puder ser um caminho relativo como /about, porque caminhos relativos não são valores válidos para um campo url.

slug

Texto destinado a conter um valor semelhante a slug. Este tipo de campo personalizado não gera nem sanitiza seu valor.

{
  slug: "legacy_slug",
  label: "Legacy Slug",
  type: "slug",
  required: true,
  unique: true,
}

Toda entrada de conteúdo já tem um slug de sistema reservado, que o EmDash gerencia separadamente para URLs públicas. Use um campo slug personalizado apenas quando o modelo de conteúdo precisar de outro valor semelhante a slug armazenado.

Tipos numéricos

number

Número decimal. Use para preços, avaliações e medidas.

{
  slug: "price",
  label: "Price",
  type: "number",
  required: true,
  validation: {
    min: 0,
    max: 999999.99,
  },
}

Opções de validação:

  • min — Valor mínimo
  • max — Valor máximo

O editor define min e max na entrada numérica e mostra o intervalo permitido abaixo.

Armazenado como SQLite REAL (ponto flutuante de 64 bits).

integer

Número inteiro. Use para quantidades, contagens e valores de ordem.

{
  slug: "quantity",
  label: "Quantity",
  type: "integer",
  defaultValue: 1,
  validation: {
    min: 0,
    max: 1000,
  },
}

Opções de validação:

  • min — Valor mínimo
  • max — Valor máximo

O editor define min e max na entrada numérica e mostra o intervalo permitido abaixo.

Armazenado como SQLite INTEGER.

boolean

Verdadeiro ou falso. Use para interruptores e flags.

{
  slug: "featured",
  label: "Featured",
  type: "boolean",
  defaultValue: false,
}

Armazenado como SQLite INTEGER (0 ou 1).

Data e hora

datetime

Um instante no tempo. Escritas de API, MCP e CLI devem incluir Z ou um deslocamento UTC explícito. A administração interpreta seu seletor de data e hora no fuso horário configurado em Settings → General.

{
  slug: "publishedAt",
  label: "Published At",
  type: "datetime",
}

Formato de armazenamento: 2025-01-24T12:00:00.000Z

O EmDash converte a entrada aceita para UTC com milissegundos de três dígitos antes de armazená-la. Por exemplo, 2025-01-24T21:00:00+09:00 é armazenado como 2025-01-24T12:00:00.000Z. Use um campo string quando o valor for uma data de calendário ou horário local de relógio de parede em vez de um instante.

Tipos de seleção

select

Seleção única entre opções predefinidas.

{
  slug: "status",
  label: "Status",
  type: "select",
  required: true,
  defaultValue: "draft",
  validation: {
    options: ["draft", "published", "archived"],
  },
}

Opções de validação:

  • options — Array opcional de valores permitidos. Forneça-o para apresentar escolhas predefinidas e rejeitar outras strings; sem ele, a validação aceita qualquer string.

Armazenado como TEXT contendo o valor selecionado.

multiSelect

Seleções múltiplas entre opções predefinidas.

{
  slug: "tags",
  label: "Tags",
  type: "multiSelect",
  validation: {
    options: ["news", "tutorial", "review", "opinion"],
  },
}

Opções de validação:

  • options — Array opcional de valores permitidos. Forneça-o para apresentar escolhas predefinidas e rejeitar outras strings; sem ele, a validação aceita qualquer array de strings.

Armazenado como array JSON: ["news", "tutorial"]

Conteúdo rico

portableText

Conteúdo de rich text no formato Portable Text. Suporta títulos, listas, links, imagens e blocos personalizados.

{
  slug: "content",
  label: "Content",
  type: "portableText",
  required: true,
}

O valor é armazenado como um array JSON de blocos Portable Text, por exemplo:

[
	{
		"_type": "block",
		"style": "normal",
		"children": [{ "_type": "span", "text": "Hello world" }]
	}
]

Plugins podem adicionar tipos de bloco personalizados (embeds, widgets etc.) ao editor. Eles aparecem no menu de comandos slash. Renderizar o bloco salvo no site público requer um componente Astro de um plugin nativo ou pacote companion. Veja Componentes de renderização Portable Text.

Tipos de mídia

image

Referência a uma imagem enviada. Inclui metadados como dimensões e texto alternativo.

{
  slug: "featuredImage",
  label: "Featured Image",
  type: "image",
  validation: {
    allowedMimeTypes: ["image/jpeg", "image/png"],
  },
  options: {
    darkVariant: true,
  },
}

Opções do widget:

  • darkVariant — Oferece aos editores um segundo espaço para uma imagem mostrada em esquemas de cores escuros (padrão: false). Veja Dark Mode.

Opções de validação:

  • allowedMimeTypes — Lista não vazia de tipos MIME exatos aceitos para a mídia selecionada

O valor é armazenado como um objeto com a referência de mídia e seus metadados:

{
	"id": "01HXK5MZSN...",
	"src": "/_emdash/api/media/file/01HXK5MZSN...",
	"alt": "Description",
	"width": 1920,
	"height": 1080,
	"provider": "local",
	"meta": {
		"storageKey": "01HXK5MZSN....jpg"
	}
}

Com darkVariant habilitado, o valor pode carregar a contraparte escura sob darkVariant, no mesmo formato:

{
	"id": "01HXK5MZSN...",
	"alt": "Architecture diagram",
	"width": 1920,
	"height": 1080,
	"darkVariant": {
		"id": "01HXK5N2QT...",
		"width": 1920,
		"height": 1080
	}
}

file

Referência a um arquivo enviado, como um documento ou PDF.

{
  slug: "document",
  label: "Document",
  type: "file",
  validation: {
    allowedMimeTypes: ["application/pdf"],
  },
}

Opções de validação:

  • allowedMimeTypes — Lista não vazia de tipos MIME exatos aceitos para a mídia selecionada

O valor é armazenado como uma referência de provedor com metadados em cache:

{
	"id": "01HXK5MZSN...",
	"provider": "local",
	"filename": "report.pdf",
	"mimeType": "application/pdf",
	"meta": {
		"storageKey": "01HXK5MZSN....pdf"
	}
}

url e size, como os outros campos de metadados em cache, são opcionais. Consultas de conteúdo retornam o valor persistido como está e não o hidratam da biblioteca de mídia. Veja Valores de arquivo e metadados atuais para as APIs de consulta canônicas quando precisar de metadados atualizados ou de uma URL específica do provedor.

Tipos relacionais

reference

Liga uma entrada a entradas de outra coleção e aparece como um seletor de entradas na administração. Seus links pertencem a uma relação: um objeto de esquema que une duas coleções, nomeia cada lado e limita quantas entradas cada lado pode ligar. Relations cobre o fluxo de trabalho do editor e da administração.

O campo a seguir liga uma publicação a uma entrada da coleção authors:

{
  slug: "author",
  label: "Author",
  type: "reference",
  required: true,
  validation: {
    targetCollection: "authors",
    multiple: false,
  },
}

Validação:

  • targetCollection — Slug da coleção à qual este campo liga. Criar o campo cria uma relação para ele.
  • multiple — Permitir mais de uma entrada ligada (padrão: false). Leia apenas junto com targetCollection, porque o limite então pertence à nova relação.
  • relation — Slug de uma relação existente à qual se vincular em vez de criar uma.
  • relationSide — Em qual extremo de relation esta coleção fica, "parent" ou "child". Defina apenas para uma relação cujos dois extremos são a mesma coleção, onde ambos os extremos coincidem.

Informe targetCollection ou relation. Um campo criado a partir de targetCollection torna-se o extremo pai de uma relação chamada {collection}_{field}, cujo lado filho toma o rótulo do campo e mantém uma entrada a menos que multiple esteja definido. Um campo criado a partir de relation vê essa relação a partir do extremo em que sua coleção fica, e a coleção no outro extremo é o destino do campo. Uma relação aceita um campo por extremo, então um segundo campo sobre o mesmo extremo é rejeitado. Ambas as formas armazenam relation, relationSide e targetCollection no campo criado, e a coleção destino fica fixa daí em diante: para alterá-la, exclua o campo e adicione um novo. Renomear o campo renomeia o lado da relação que ele vê.

Um campo de referência não adiciona nenhuma coluna à tabela da coleção. Seus links vivem em _emdash_content_references, indexados pelo grupo de tradução de cada entrada, de modo que uma seleção é compartilhada entre as traduções de uma entrada em vez de definida por locale. Leituras de conteúdo retornam as entradas ligadas sob references, indexadas pelo slug do campo, em vez de em data. Em um template, peça o campo pelo nome — veja Ler campos de referência.

Um campo vinculado a uma relação não pode definir indexed, porque não armazena coluna para indexar, e a busca do site não o cobre.

Campos sem relação

Um campo de referência que não nomeia nem uma relação nem uma coleção destino mantém uma coluna TEXT e guarda nela um ID de entrada:

"01HXK5MZSN..."

Um campo cujo options.allowMultiple está definido guarda um array JSON de IDs de entrada na mesma coluna:

["01HXK5MZSN...", "01HXK6NATS..."]

A coluna é lida e escrita como qualquer outra coluna de texto, o esquema da coleção valida o valor como string, e o campo pode definir indexed e atuar como filtro de lista de conteúdo. É renderizado como uma caixa de texto em vez de um seletor.

Para transformá-lo em um seletor, abra o campo em Content Types e escolha uma coleção referenciada. O EmDash cria a relação, copia os IDs de entrada da coluna como links e limpa os flags searchable e indexed do campo, de modo que filtros de lista de conteúdo e busca do site deixam de cobri-lo. A coluna permanece no lugar e deixa de ser escrita. Relations cobre o mesmo passo do lado do editor.

Um site atualizado de uma versão anterior pode manter campos nesse estado. Veja Campos de referência vinculam-se a relações para o que a atualização vincula e o que deixa para você vincular.

Tipos flexíveis

json

Dados JSON arbitrários. Use para estruturas aninhadas complexas, integrações de terceiros ou dados sem um esquema fixo.

{
  slug: "metadata",
  label: "Metadata",
  type: "json",
}

Armazenado como está em uma coluna JSON do SQLite.

repeater

Uma lista repetível de linhas estruturadas. Defina pelo menos um subcampo em validation.subFields; os editores podem então adicionar, remover, reordenar e editar linhas sem inserir JSON bruto.

O campo a seguir armazena uma lista de especificações de produto:

{
  slug: "specifications",
  label: "Specifications",
  type: "repeater",
  validation: {
    minItems: 1,
    maxItems: 12,
    subFields: [
      { slug: "label", label: "Label", type: "string", required: true },
      { slug: "value", label: "Value", type: "text", required: true },
      { slug: "source", label: "Source", type: "url" },
    ],
  },
}

Valores de repeater são armazenados como um array de objetos:

[
	{
		"label": "Weight",
		"value": "1.2 kg",
		"source": "https://example.com/specifications"
	}
]

Os tipos de subcampo permitidos são string, text, url, number, integer, boolean, datetime, select e image. Repeaters não podem conter outro repeater nem um campo complexo como portableText, reference ou file.

A validação de repeater aceita estas propriedades:

  • subFields — Uma ou mais definições de subcampo. Cada definição exige slug, label e type; também pode definir required. Um subcampo select fornece suas escolhas por meio de options.
  • minItems — Número mínimo de linhas. Deve ser zero ou maior.
  • maxItems — Número máximo de linhas. Deve ser um ou maior e não pode ser menor que minItems.

blocks

Uma lista ordenada de blocos de conteúdo tipados. Cada tipo de bloco tem seus próprios campos e mantém versões numeradas. Defina os tipos de bloco pela API de esquema, MCP ou um arquivo seed antes de adicioná-los a um campo de coleção.

O campo a seguir permite que editores componham uma página a partir de blocos hero e call-to-action:

{
  slug: "layout",
  label: "Layout",
  type: "blocks",
  validation: {
    allowedTypes: ["hero", "call_to_action"],
    maxItems: 20,
  },
}

Todo bloco armazenado carrega seu tipo, versão e chave estável junto com os campos declarados por essa versão:

[
	{
		"_type": "hero",
		"_version": 1,
		"_key": "01K5AB3F7M9QZ2X8W4V6T1R0YH",
		"heading": "Bread made slowly, by hand."
	}
]

A validação de blocks aceita estas propriedades:

  • allowedTypes — Slugs de tipos de bloco ordenados disponíveis para novos blocos.
  • retiredTypes — Tipos de bloco gerenciados pelo servidor retidos para conteúdo armazenado, mas indisponíveis para novos blocos.
  • minItems — Número mínimo de blocos. Aumentá-lo acima de zero em uma coleção populada exige uma migração de conteúdo.
  • maxItems — Número máximo de blocos, até 100.

Um campo blocks é opcional e tem como padrão um array vazio. Não pode ser required, unique, searchable, indexed nem renderizado por um widget de campo personalizado. Definições de bloco podem usar campos escalares, de texto, de seleção, Portable Text, imagem, arquivo e repeater. Não podem conter referências, JSON, slugs ou blocks aninhados.

Renderize o array armazenado com <Blocks value components fallback> de emdash/ui. Veja Criar páginas com blocks para exemplos de seed, mapa de componentes, renderer ausente, ativação e migração.

Propriedades de campo

Todos os campos suportam estas propriedades comuns:

PropertyTypeDescription
slugstringIdentificador único (obrigatório)
labelstringNome de exibição (obrigatório)
typeFieldTypeTipo de campo (obrigatório)
requiredbooleanExigir um valor (padrão: false)
uniquebooleanImpor unicidade (padrão: false)
searchablebooleanIncluir o campo na busca de texto completo (padrão: false)
indexedbooleanHabilitar ordenação/filtragem indexada
translatablebooleanArmazenar um valor por locale (padrão: true)
defaultValueunknownValor padrão para novas entradas
validationobjectRegras de validação específicas do tipo
widgetstringSubstituição de widget personalizado
optionsobjectConfiguração do widget
sortOrdernumberOrdem de exibição na administração

indexed está disponível para campos escalares: string, url, number, integer, boolean, datetime, select, reference e slug. Um campo indexado pode ser passado como o campo orderBy ou usado em fieldFilters nas consultas de lista de conteúdo. Evite indexar campos que não são usados para ordenar ou filtrar porque cada índice adiciona sobrecarga de armazenamento e gravação.

searchable adiciona o texto do campo ao índice de busca de texto completo da coleção. Defina translatable: false para identificadores, preços, flags e outros valores que devem permanecer iguais em todas as traduções de uma entrada; quando um locale altera um campo não traduzível, o EmDash sincroniza o valor com suas entradas traduzidas.

O tipo blocks usa apenas slug, label, type, translatable, validation e sortOrder deste conjunto comum. Seu array nunca é obrigatório em nível de coluna e sempre tem como padrão [].

Slugs de campo reservados

Estes slugs são reservados e não podem ser usados:

  • id
  • slug
  • status
  • author_id
  • primary_byline_id
  • created_at
  • updated_at
  • published_at
  • scheduled_at
  • deleted_at
  • version
  • live_revision_id
  • draft_revision_id
  • terms
  • bylines
  • byline

Tipos TypeScript

Importe as definições de tipos de campo para uso programático:

import type { FieldType, Field, CreateFieldInput } from "emdash";

const fieldTypes: FieldType[] = [
	"string",
	"text",
	"url",
	"number",
	"integer",
	"boolean",
	"datetime",
	"select",
	"multiSelect",
	"portableText",
	"image",
	"file",
	"reference",
	"json",
	"slug",
	"repeater",
	"blocks",
];