Home / Docs / Content Types

Content Types

Guides

Every Forge content type is a plain Go struct that embeds forge.Node. The embed provides UUID identity, a URL slug, and the full content lifecycle. Forge derives routing, storage, validation, and MCP schema directly from the struct — no separate configuration required.

forge.Node

Every content type embeds forge.Node as a value — not a pointer:

type BlogPost struct {
    forge.Node               // always embed this
    Title  string `forge:"required,min=3"`
    Body   string `forge:"required"`
    Tags   []string
}

forge.Node fields:

FieldTypeDescription
IDstringUUID v7 — immutable after creation
SlugstringURL-safe identifier, auto-generated
Statusforge.StatusDraft, Published, Scheduled, Archived
PublishedAttime.TimeZero until first publish
ScheduledAt*time.TimeNon-nil when Scheduled
CreatedAttime.TimeSet on insert
UpdatedAttime.TimeSet on every Save

Validation tags

Title  string `forge:"required,min=3,max=200"`
Body   string `forge:"required,min=50"`
Slug   string `forge:"slug"`
Email  string `forge:"required,email"`

For business-rule validation beyond tags, implement Validate() error:

func (p *Post) Validate() error {
    if p.Status == forge.Published && len(p.Tags) == 0 {
        return forge.Err("tags", "required when publishing")
    }
    return nil
}

Interfaces

InterfaceMethodPurpose
HeadableHead() forge.HeadSEO, OG, sitemap, AI metadata
MarkdownableMarkdown() stringtext/markdown negotiation, llms-full.txt
AIDocSummaryAISummary() string/llms.txt summary field
ValidatableValidate() errorBusiness-rule validation

Storage

// SQLite / PostgreSQL
repo := forge.NewSQLRepo[*Post](db)

// In-memory (tests and prototypes)
repo := forge.NewMemoryRepo[*Post]()

Table names are auto-derived from the type name: Post → posts, DocPage → doc_pages. Override with forge.Table("custom_name").

Field format hints for AI agents

Use forge_format and forge_description struct tags to tell AI agents what a field expects. These hints appear directly in MCP tool descriptions at the point of authoring — so any MCP-compatible agent knows whether to write Markdown, raw HTML, or something else without having to guess from the field name.

type DocPage struct {
    forge.Node
    Title string `forge:"required,min=3"`
    Body  string `forge:"required" forge_format:"markdown" forge_description:"Write content in Markdown. Supports headings, lists, and code blocks."`
    Embed string `forge_format:"html" forge_description:"Raw HTML only. Use for iframes and third-party embeds. Must be trusted content."`
}

Supported forge_format values:

ValueMeaning
markdownCommonMark/GFM markdown — also covers plain text
htmlTrusted raw HTML — caller is responsible for sanitisation

Fields without forge_format are unaffected. No validation is performed — the tags are hints only.