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:
| Type | SQLite Column | Description |
|---|---|---|
string | TEXT | Entrada de texto curto |
text | TEXT | Texto multilinha |
url | TEXT | Valor de URL |
number | REAL | Número decimal |
integer | INTEGER | Número inteiro |
boolean | INTEGER | Verdadeiro/falso |
datetime | TEXT | Data e hora |
select | TEXT | Escolha única entre opções |
multiSelect | JSON | Escolhas múltiplas |
portableText | JSON | Conteúdo de rich text |
image | TEXT | Referência de imagem |
file | TEXT | Referência de arquivo |
reference | none | Liga entradas de outra coleção |
json | JSON | Dados JSON arbitrários |
slug | TEXT | Identificador seguro para URL |
repeater | JSON | Grupo de campos repetível |
blocks | JSON | Composiçã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 caracteresmaxLength— Contagem máxima de caracterespattern— 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 caracteresmaxLength— Contagem máxima de caracterespattern— 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ínimomax— 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ínimomax— 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 comtargetCollection, 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 derelationesta 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 exigeslug,labeletype; também pode definirrequired. Um subcamposelectfornece suas escolhas por meio deoptions.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 queminItems.
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:
| Property | Type | Description |
|---|---|---|
slug | string | Identificador único (obrigatório) |
label | string | Nome de exibição (obrigatório) |
type | FieldType | Tipo de campo (obrigatório) |
required | boolean | Exigir um valor (padrão: false) |
unique | boolean | Impor unicidade (padrão: false) |
searchable | boolean | Incluir o campo na busca de texto completo (padrão: false) |
indexed | boolean | Habilitar ordenação/filtragem indexada |
translatable | boolean | Armazenar um valor por locale (padrão: true) |
defaultValue | unknown | Valor padrão para novas entradas |
validation | object | Regras de validação específicas do tipo |
widget | string | Substituição de widget personalizado |
options | object | Configuração do widget |
sortOrder | number | Ordem 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:
idslugstatusauthor_idprimary_byline_idcreated_atupdated_atpublished_atscheduled_atdeleted_atversionlive_revision_iddraft_revision_idtermsbylinesbyline
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",
];