Frontmatter
Understanding YAML Frontmatter in GeoHazardWatch pages.
Table of Contents
- Overview
- What is Frontmatter?
- Structure and Syntax
- Required Fields
- Optional Fields
- How Frontmatter is Used
- Examples
- Best Practices
- Common Mistakes
- Technical Implementation
- Related Documentation
Overview
Frontmatter is a block of YAML metadata at the beginning of every page that contains essential information about the page such as its title, category, keywords, and more. It's fundamental to how GeoHazardWatch organizes, stores, and processes page content.
Key Points
- Format: YAML (YAML Ain't Markup Language)
- Location: Top of every
.mdfile - Delimiters: Enclosed between
---markers - Purpose: Store page metadata separately from content
- Processing: Parsed by the
gray-matterlibrary
What is Frontmatter?
Frontmatter is a metadata block that appears at the very beginning of a markdown file, before any actual content. It provides structured information about the page that the platform uses for:
- Page identification via UUID
- Storage location determination via system-category
- Search and discovery via title and keywords
- Organization and categorization
- Access control and permissions
- Version tracking and attribution
Visual Structure
┌─────────────────────────────────┐
│ --- │ ← Opening delimiter
│ title: Page Title │
│ uuid: 123e4567-e89b-12d3 │ ← YAML metadata
│ system-category: documentation │
│ user-keywords: │
│ - keyword1 │
│ - keyword2 │
│ --- │ ← Closing delimiter
│ │
│ # Page Content Starts Here │ ← Markdown content
│ │
│ Your page content... │
└─────────────────────────────────┘
Structure and Syntax
Basic Format
Frontmatter must:
- Start at the very beginning of the file (line 1)
- Begin with
---on its own line - Contain valid YAML key-value pairs
- End with
---on its own line - Be followed by markdown content
YAML Syntax Rules
---
# String values
title: Simple String
author: John Doe
# String with special characters (use quotes)
title: "String: with colons"
slug: "my-page-slug"
# Array/List values
user-keywords:
- keyword1
- keyword2
- keyword3
# Or inline array format
user-keywords: [keyword1, keyword2, keyword3]
# Date/timestamp (ISO 8601 format, quoted)
lastModified: '2025-10-20T10:47:21.921Z'
# UUID (lowercase, hyphenated)
uuid: 443c95f1-0b21-494a-b712-08ce0dc933e1
# Boolean values
published: true
draft: false
---
Required Fields
Every page must include these frontmatter fields:
title (Required)
Purpose: Human-readable name of the page
Format: String
Display: Used in navigation, search results, page headers, and links
Example:
title: Markdown Footnotes Guide
Rules:
- Must be unique on the platform
- Use clear, descriptive titles
- Avoid special characters that may cause URL encoding issues
- Recommended: 3-10 words
uuid (Required)
Purpose: Unique identifier for the page
Format: UUID v4 (lowercase, hyphenated)
Used for: Filename, internal references, version tracking
Example:
uuid: 443c95f1-0b21-494a-b712-08ce0dc933e1
Rules:
- Must be globally unique
- Lowercase letters only
- Hyphenated format (8-4-4-4-12)
- Auto-generated on page creation
- Never change after creation
Generation:
# On Unix/Mac
uuidgen | tr '[:upper:]' '[:lower:]'
# Output example
4a266851-f3cd-4ba6-bbbe-5a408f3adf72
system-category (Required)
Purpose: Determines storage location and access control
Format: String (must match a configured category)
Default: general if not specified
Example:
system-category: documentation
Available Categories:
| Category | Storage | Description | Access Level |
|---|---|---|---|
system | required-pages/ | System configuration pages | Admin only |
documentation | required-pages/ | Official documentation | Editor+ |
developer | required-pages/ | Developer docs | Developer+ |
general | pages/ | General content | All users |
user | pages/ | User-generated content | All users |
test | pages/ | Test/experimental pages | Editor+ |
Impact:
- Controls which directory the page is stored in
- Affects backup priority and frequency
- Determines edit and delete permissions
- Influences cache behavior
See also: Page Storage Guide
Optional Fields
These fields enhance page functionality but are not strictly required:
user-keywords (Recommended)
Purpose: Searchable tags for content discovery
Format: YAML array of strings
Example:
user-keywords:
- documentation
- examples
- markdown
- formatting
Best Practices:
- Use 3-5 relevant keywords
- Choose specific, searchable terms
- Include synonyms users might search for
- Avoid generic terms like "page" or "wiki"
- Use lowercase for consistency
slug (Optional)
Purpose: URL-friendly version of the title
Format: Lowercase string with hyphens
Auto-generated: From title if not provided
Example:
title: Markdown Footnotes Guide
slug: markdown-footnotes-guide
Rules:
- Lowercase letters, numbers, hyphens only
- No spaces or special characters
- Should reflect the page title
- Used in URL:
/view/markdown-footnotes-guide
author (Optional)
Purpose: Track page creator or maintainer
Format: String (username or full name)
Example:
author: ngdpbase Team
author: john.doe
author: Jane Smith
Display: Shown in page metadata sidebar
lastModified (Automatic)
Purpose: Track when page was last edited
Format: ISO 8601 timestamp (quoted string)
Managed by: System automatically updates on save
Example:
lastModified: '2025-10-20T10:47:21.921Z'
Note: You typically don't need to manually set this field
How Frontmatter is Used
1. Storage Location Routing
When you save a page:
Page Save
↓
Read frontmatter.system-category
↓
Lookup category in config
↓
Check storageLocation property
↓
Route to correct directory
↓
Save as {uuid}.md
Example:
system-category: documentation # → storageLocation: "required"
Result: Page saved to required-pages/4a266851-f3cd-4ba6-bbbe-5a408f3adf72.md
2. Page Identification
ngdpbase uses a three-level identification system:
1. UUID (Primary)
└─→ Filename: {uuid}.md
└─→ Internal references
└─→ Never changes
2. Title (Human-readable)
└─→ Display name
└─→ Search results
└─→ Can change without breaking links
3. Slug (URL-friendly)
└─→ Web URL: /view/{slug}
└─→ Generated from title
└─→ Can be customized
3. Search and Discovery
Frontmatter fields power the search system:
title: Markdown Footnotes Guide # Primary search field
user-keywords: # Secondary search terms
- footnotes
- markdown
- references
- citations
system-category: documentation # Category filter
Search Behavior:
- Title matches rank highest
- Keywords provide additional matching
- Category allows filtered searches
- Author enables "find by creator"
4. Access Control
The system-category field integrates with the access control system:
system-category: system
↓
Lookup access policy
↓
Check user role
↓
Grant/Deny permissions
Example Access Matrix:
| Category | View | Edit | Delete |
|---|---|---|---|
| system | All | Admin | Admin |
| documentation | All | Editor+ | Admin |
| general | All | Contributor+ | Editor+ |
5. Cache Management
Different categories have different cache strategies:
// System pages (high priority)
system-category: system
→ cacheTTL: 3600 seconds
→ preload: true
→ priority: high
// User pages (standard)
system-category: general
→ cacheTTL: 300 seconds
→ preload: false
→ priority: normal
Examples
Example 1: Documentation Page
---
title: Markdown Footnotes Guide
uuid: 443c95f1-0b21-494a-b712-08ce0dc933e1
system-category: documentation
user-keywords:
- documentation
- markdown
- footnotes
- examples
slug: markdown-footnotes-guide
author: ngdpbase Team
lastModified: '2025-10-16T19:56:00.000Z'
---
# Markdown Footnotes Guide
This guide explains how to use footnotes in ngdpbase...
Result:
- Stored in:
required-pages/443c95f1-0b21-494a-b712-08ce0dc933e1.md - URL:
/view/markdown-footnotes-guide - Searchable by: Title, keywords
- Editable by: Editor+ roles
- Cache: High priority, 1 hour TTL
Example 2: User Content Page
---
title: My Project Notes
uuid: 7a8b9c0d-1e2f-3g4h-5i6j-7k8l9m0n1o2p
system-category: user
user-keywords:
- project
- notes
- development
- planning
slug: my-project-notes
author: jane.smith
lastModified: '2025-10-20T10:30:00.000Z'
---
# My Project Notes
These are my notes for the Q4 project...
Result:
- Stored in:
pages/7a8b9c0d-1e2f-3g4h-5i6j-7k8l9m0n1o2p.md - URL:
/view/my-project-notes - Editable by: Owner + Editor+
- Cache: Standard priority, 5 minutes TTL
Example 3: System Page
---
title: LeftMenu
uuid: 110fc9ee-90ca-4e6d-b6fa-334ce3074205
system-category: system
user-keywords: []
slug: leftmenu
author: ngdpbase Team
lastModified: '2025-10-20T08:15:00.000Z'
---
[{TableOfContents}]
* [User Documentation]
* [Recent Changes]
* [SystemInfo]
Result:
- Stored in:
required-pages/110fc9ee-90ca-4e6d-b6fa-334ce3074205.md - URL:
/view/leftmenu - Editable by: Admin only
- Protected: Cannot be accidentally deleted
- Cache: Preloaded at startup
Example 4: Minimal Valid Frontmatter
---
title: Simple Page
uuid: 1a2b3c4d-5e6f-7890-1234-567890abcdef
system-category: general
user-keywords: []
---
# Simple Page
Just the required fields. The system will auto-generate other values.
Best Practices
✅ DO
Use descriptive, unique titles
title: API Authentication Guide # Good
title: Guide # Bad - too generic
Include relevant keywords
user-keywords:
- api
- authentication
- oauth
- security
Choose the appropriate category
# Official documentation
system-category: documentation
# Personal notes
system-category: user
Use proper YAML syntax
# Correct
title: "Title: With Colon"
lastModified: '2025-10-20T10:00:00.000Z'
# Incorrect
title: Title: With Colon # Will cause parsing error
Keep keywords specific and relevant
user-keywords:
- javascript # Good
- node.js # Good
- programming # Too broad
- stuff # Too vague
❌ DON'T
Don't use uppercase in UUIDs
uuid: 4A266851-F3CD-4BA6-BBBE-5A408F3ADF72 # Wrong
uuid: 4a266851-f3cd-4ba6-bbbe-5a408f3adf72 # Correct
Don't manually change lastModified
lastModified: '2025-10-20T10:00:00.000Z' # Let system handle this
Don't use non-existent categories
system-category: my-custom-category # Will default to 'general'
Don't forget the closing ---
---
title: My Page
uuid: 123e4567-e89b-12d3
system-category: general
# Missing closing --- will break parsing!
Don't put content before frontmatter
# My Page ← Wrong! Content before frontmatter
---
title: My Page
---
Common Mistakes
Mistake 1: Missing Closing Delimiter
Wrong:
---
title: My Page
uuid: 123e4567-e89b-12d3
# Forgot closing ---
# Page Content
Error: Entire page treated as frontmatter
Fix: Always include closing ---
Mistake 2: Invalid YAML Syntax
Wrong:
---
title: Error: This won't parse
user-keywords: keyword1, keyword2 # Wrong array format
---
Error: YAML parsing failure
Fix:
---
title: "Error: This will parse"
user-keywords:
- keyword1
- keyword2
---
Mistake 3: Uppercase UUID
Wrong:
uuid: 4A266851-F3CD-4BA6-BBBE-5A408F3ADF72
Problem: File lookup may fail
Fix: Always use lowercase
uuid: 4a266851-f3cd-4ba6-bbbe-5a408f3adf72
Mistake 4: Wrong Category Name
Wrong:
system-category: Documentation # Capital D
system-category: docs # Abbreviated
Problem: Will default to 'general', page goes to wrong directory
Fix: Use exact category name from config
system-category: documentation
Mistake 5: Content Before Frontmatter
Wrong:
This is my page about widgets.
---
title: Widgets
uuid: 123e4567-e89b-12d3
---
Problem: Frontmatter must be at line 1
Fix: Always start with frontmatter
---
title: Widgets
uuid: 123e4567-e89b-12d3
---
This is my page about widgets.
Technical Implementation
Parsing Library
ngdpbase uses gray-matter for frontmatter parsing:
const matter = require('gray-matter');
// Parse a markdown file
const fileContent = fs.readFileSync('page.md', 'utf-8');
const parsed = matter(fileContent);
// Access frontmatter
console.log(parsed.data.title); // "My Page"
console.log(parsed.data.uuid); // "123e4567..."
console.log(parsed.data['system-category']); // "documentation"
// Access content
console.log(parsed.content); // Markdown content without frontmatter
See: /Volumes/hd3/GitHub/ngdpbase/src/providers/FileSystemProvider.js:4
Processing Flow
1. Page Load Request
↓
2. Read file: {uuid}.md
↓
3. Parse with gray-matter
↓
4. Extract frontmatter (parsed.data)
↓
5. Extract content (parsed.content)
↓
6. Validate required fields
↓
7. Add to cache
↓
8. Return page object
Validation
The ValidationManager checks frontmatter:
// Required fields check
const requiredFields = ['title', 'uuid', 'system-category'];
// Format validation
if (!/^[a-f0-9-]{36}$/.test(uuid)) {
throw new Error('Invalid UUID format');
}
// Category validation
const validCategories = config.get('ngdpbase.system-category');
if (!validCategories[systemCategory]) {
console.warn(`Unknown category: ${systemCategory}, using default`);
}
See: /Volumes/hd3/GitHub/ngdpbase/src/managers/ValidationManager.js
Automatic Field Generation
When fields are missing:
// Auto-generate UUID if missing
if (!frontmatter.uuid) {
frontmatter.uuid = uuidv4().toLowerCase();
}
// Auto-generate slug if missing
if (!frontmatter.slug) {
frontmatter.slug = slugify(frontmatter.title);
}
// Set default category if missing
if (!frontmatter['system-category']) {
frontmatter['system-category'] = 'general';
}
// Update lastModified on save
frontmatter.lastModified = new Date().toISOString();
Related Documentation
- Page Storage Guide - How pages are stored and organized
- CONTRIBUTING.md - Frontmatter requirements
- System Categories Configuration - Available categories
- ValidationManager Documentation - Metadata validation
Quick Reference Card
---
# Required Fields
title: Page Title # Display name
uuid: 4a266851-f3cd-4ba6-bbbe-5a408f3adf72 # Unique ID (lowercase)
system-category: documentation # Storage location
# Recommended Fields
user-keywords: # Search tags
- keyword1
- keyword2
# Optional Fields
slug: page-title # URL-friendly name
author: Username # Creator
# Automatic Fields
lastModified: '2025-10-20T10:00:00.000Z' # System-managed
---
# Page Content Starts Here
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2025-10-20 | Initial documentation |
Questions or Issues?
- Check the Common Mistakes section
- Review YAML Syntax
- See Page Storage Guide for category details
Last Updated: 2025-10-20
Maintained By: ngdpbase Documentation Team
Status: Current ✅
No comments yet.