A field is one key in an entry’s frontmatter and the widget Emet shows for it. You declare them per section in admin/site.yaml, and the type decides the widget: a toggle for a boolean, a date picker for a date, the media library for an image. The setup wizard guesses a reasonable set from your existing content, and this page is the reference for tidying up what it wrote.
sections:
blog:
fields:
- name: title
type: string
required: true
- name: date
type: datetime
- name: tags
type: list
- name: cover
type: image
hint: Shown at the top of the post and in listingsFields appear in the frontmatter panel in the order you declare them. If you’d rather group them, field_groups on the section puts named, collapsible boxes around them; see Sections.
Keys in the file that you haven’t declared still show up, with a widget guessed from the value, and there’s an Add field row for adding new ones. Emet never drops a key it doesn’t know about. The system fields (slug, aliases, filename), inherited cascade values and the draft toggle are covered under Editing an entry.
Common options#
| Option | What it does |
|---|---|
name |
The frontmatter key. Required. |
type |
One of the types below. widget is accepted as an alias, so Netlify and Decap configs mostly drop in. Defaults to string. |
label |
What the form calls it. Defaults to the name with underscores and hyphens turned into spaces and each word capitalised, so featured_image becomes “Featured Image”. |
hint |
Help text under the widget. |
placeholder |
Placeholder text, for string, text, number and relation fields. |
required |
Adds an asterisk to the label. It doesn’t block saving, so treat it as a hint to editors rather than a rule. |
hidden |
true leaves the field out of the form while keeping the key in the file. |
condition, conditions |
Show the field only when another field has a given value; see below. |
validation.max_length |
Shows a character counter on string and text fields, which turns amber past the limit. Nothing stops you saving. |
A few options you might expect, or have seen in other CMS configs, exist in the config types but aren’t read by any widget: default (it’s only used for shortcode parameters; put defaults in the archetype instead), validation.min_length, validation.pattern and validation.min/max. They’re harmless but do nothing. The same goes for several per-type options noted below. Field names must be unique within a section; a duplicate logs a warning and the last one wins.
Conditional fields#
Show a field only when another field has a particular value:
- name: video_url
type: string
condition:
field: type
value: videoconditions takes a list that must all match, and condition.any takes a list of which one must match:
# all of these
conditions:
- field: type
value: video
- field: featured
value: true
# any of these
condition:
any:
- field: type
value: video
- field: type
value: podcastfield can be a dotted path into an object (author.role). Matching is forgiving: a list matches if it contains the value, "true" matches true, "1" matches 1, and an unset field counts as an empty string. While hidden, the field shows as a one-line note saying it’ll appear when its conditions are met, so editors know it exists. Inside an object or a list of objects, conditions see the parent frontmatter and the object’s own values together.
String#
A single-line text input.
- name: subtitle
type: string
placeholder: Optional
validation:
max_length: 100Fields named title, meta_title or seo_title get a counter against 60 characters without being asked, and description, meta_description and seo_description against 160, since those are the lengths search results truncate at.
Text#
A textarea, rows tall (default 3), with the same max_length counter.
- name: summary
type: text
rows: 4Markdown#
This type is listed in the config types but doesn’t do anything useful yet. A top-level markdown field is filtered out of the frontmatter panel entirely (the body is edited by the main editor, not a field), and inside an object or list it renders as a plain textarea. If you want Markdown in frontmatter, use text and accept that there’s no toolbar.
Number#
A text input whose value is parsed as a number on the way out. Anything that doesn’t parse, including an empty box, removes the key from the frontmatter rather than writing an empty string.
- name: rating
type: numbermin, max, step and value_type are accepted but not read: there’s no range enforcement and no integer-only mode.
Boolean#
A toggle. Don’t declare one for draft; that key is filtered out of the panel and handled by the Draft / Publish toggle in the panel header instead.
- name: featured
type: booleanDatetime#
A date-and-time picker with a Now button and a note showing which timezone the browser is in. What’s written to the file is UTC in ISO 8601 form, e.g. 2026-10-10T12:00:00.000Z, whatever you typed in locally. Hugo is fine with that; if you’d rather see local time in the file, you’ll have to edit it in Markdown mode.
- name: date
type: datetimeHalf-typed values the browser produces while you edit the year are ignored rather than written to the file. The format, display_format and time_format options aren’t read.
Date#
The same picker without the time. The value is stored exactly as the picker gives it, 2026-10-10, with no timezone conversion, so it can’t shift by a day.
- name: event_date
type: dateSelect#
A dropdown, with a blank Select… option at the top for “no value”. Options are either plain strings or value/label pairs:
- name: category
type: select
options:
- news
- tutorial
- name: status
type: select
options:
- value: wip
label: In progress
- value: done
label: FinishedWith multiple: true the dropdown becomes a group of checkboxes and the value is a list, written in the order the options are declared regardless of the order you ticked them, which keeps diffs quiet. A value that’s a comma-separated string in an old file is split into a list for you.
- name: platforms
type: select
multiple: true
options: [web, ios, android]List#
A list of items, each with a number, a remove button and an Add item button underneath.
- name: tags
type: listWithout items, or with items.type: string, each item is a text input and there’s a dashed quick-add box below the list: type comma-separated values and press Enter (or click away) to add them all at once. A plain string value in an old file is split on commas and written back as a list the next time you save.
For anything else, items is a full field definition, so a list of objects is:
- name: authors
type: list
items:
type: object
fields:
- name: name
type: string
- name: url
type: stringEach item renders with that field’s widget, labelled “Item 1”, “Item 2” and so on. min and max aren’t enforced.
The system aliases field is a string list with one extra: each alias is checked against Hugo’s rules (no whitespace, no Windows-reserved names or characters, must not resolve to the site root), and an invalid one blocks saving until you fix it. A section field named aliases gets the same treatment.
Object#
A collapsible group of nested fields, stored as a map.
- name: author
type: object
fields:
- name: name
type: string
- name: avatar
type: imageRelation#
A searchable dropdown of entries from another section, storing one value.
- name: series
type: relation
section: series
display_field: title
value_field: slugsection is the key of the section to list and is required. display_field and value_field can be title, slug, path or date (those are the only things Emet knows about an entry without opening it) and default to title and slug. The widget shows the current value’s title if it can find it, or the raw value if not, with a clear button. There’s no multi-select; for several related entries use a list of strings for now.
Image#
A path input with a Browse button that opens the media library, a clear button, and a thumbnail once there’s a value. You can also just type a path.
- name: cover
type: imageIf AI image generation is set up, the library’s Edit with AI button lets you regenerate the picked image and replace the file in place.
File#
The same as image but with a filename instead of a thumbnail. It opens the same media library, which only lists files matching media.accept, so to pick a PDF with it you’ll need to add .pdf to that list.
- name: attachment
type: fileCode#
A CodeMirror editor with syntax highlighting.
- name: custom_css
type: code
language: css
rows: 10language can be markdown, javascript, typescript, json, css or html, and defaults to json. yaml is accepted but highlighted as Markdown, since there’s no YAML grammar bundled. rows sets the height; rows: 1 also hides the line numbers for a single-line snippet.
Colour#
A native colour picker next to a text box for the hex value, with a swatch below.
- name: accent
type: colorOnly six-digit hex (#3b82f6) is recognised. Anything else is kept as typed and flagged with a warning, which is deliberate: it means a value like var(--brand) survives a round trip through the editor.
Hidden#
There’s no working hidden type; a field declared with type: hidden renders as “Unsupported field type”. What you want is the hidden: true option on whatever type the value really is:
- name: layout
type: string
hidden: trueThat keeps layout in the file without showing it. Since default isn’t applied to entries, a hidden field only has a value if the archetype (or an earlier edit) put one there.