Page Metadata Documentation
This document defines all metadata fields used in GeoHazardWatch page frontmatter (YAML header), designed for full Schema.org WebPage compliance to ensure optimal SEO and semantic web integration.
Schema.org WebPage Alignment
GeoHazardWatch metadata fields directly map to Schema.org WebPage properties for maximum semantic web compatibility and search engine optimization.
Required Fields (Schema.org Core Properties)
name (mapped to title)
- Schema.org Property:
name - Purpose: Display name for the page (Schema.org: "The name of the item")
- Format: String
- Rules:
- REQUIRED on all pages
- Used in navigation and page headers
- Should be descriptive and unique
- Schema.org Type: Text
headline (mapped to title)
- Schema.org Property:
headline - Purpose: Headline of the webpage (Schema.org: "Headline of the article")
- Format: String
- Rules:
- Auto-generated from
titlefield - Used for structured data markup
- Auto-generated from
- Schema.org Type: Text
identifier (mapped to uuid)
- Schema.org Property:
identifier - Purpose: Unique identifier for the page
- Format: UUID v4 format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
- Rules:
- REQUIRED on all pages
- Auto-generated at page creation
- Should NOT be manually edited
- Used for internal page tracking
- Schema.org Type: PropertyValue, Text, or URL
dateModified (mapped to lastModified)
- Schema.org Property:
dateModified - Purpose: Date on which the CreativeWork was most recently modified
- Format: ISO 8601 date string
- Rules:
- REQUIRED on all pages
- Auto-updated on page save
- Format:
YYYY-MM-DDTHH:mm:ss.sssZ
- Schema.org Type: Date or DateTime
url (auto-generated)
- Schema.org Property:
url - Purpose: URL of the item
- Format: URL string
- Rules:
- Auto-generated from page title and base URL
- Used in structured data markup
- Schema.org Type: URL
Extended Required Fields (ngdpbase-Specific)
pageType
- Purpose: Operational classification for upgrade safety and content management
- Format: Enum:
"system"|"user"|"documentation" - Rules:
- REQUIRED on all pages
- Determines upgrade behavior and management policy
system: App-managed, can be replaced during upgradesuser: User-managed, always preserved during upgradesdocumentation: Developer-managed, versioned with app
- Examples:
system- Categories, PageIndex, SystemInfouser- Welcome, project pages, personal contentdocumentation- API docs, user guides, developer docs
- Schema.org Mapping: Used internally, enhances
additionalType
category (storage-based classification)
system-category are assigned by Admin
keywords (mapped to user-keywords)
User Keywords defines keywords that are set by users
System Keywords
System Keywords are assigned by the system.
Currently the only value is "general"
Optional Fields (Schema.org Enhanced Properties)
about (mapped to categories)
- Schema.org Property:
about - Purpose: The subject matter of the content
- Format: Array of strings
- Rules:
- MAXIMUM of 3 categories
- System-level classification for advanced organization
- Maps to DefinedTerm objects in Schema.org output
- Example:
[System, Documentation] - Schema.org Type: Thing (specifically DefinedTerm)
dateCreated
- Schema.org Property:
dateCreated - Purpose: Date on which the content was created
- Format: ISO 8601 date string
- Rules:
- OPTIONAL (auto-generated if not provided)
- Set at page creation
- Format:
YYYY-MM-DDTHH:mm:ss.sssZ
- Schema.org Type: Date or DateTime
author (auto-generated)
- Schema.org Property:
author - Purpose: The author of this content
- Format: Schema.org Person or Organization object
- Rules:
- Auto-generated from system configuration
- References ngdpbase Platform or specific user
- Schema.org Type: Organization or Person
isPartOf (auto-generated)
- Schema.org Property:
isPartOf - Purpose: Indicates this page is part of the ngdpbase website
- Format: Schema.org WebSite object
- Rules:
- Auto-generated for all pages
- References the parent ngdpbase website
- Schema.org Type: WebSite
breadcrumb (auto-generated from categories)
- Schema.org Property:
breadcrumb - Purpose: Navigation breadcrumb trail
- Format: Schema.org BreadcrumbList
- Rules:
- Auto-generated from
categoriesarray (not hierarchical category field) - Creates logical navigation path from most general to most specific
- Uses predefined category relationships for optimal breadcrumb ordering
- Auto-generated from
- Example:
categories: [Documentation, Developer, API]generates breadcrumb: Documentation → Developer → API - Schema.org Type: BreadcrumbList or Text
mainContentOfPage (auto-generated)
- Schema.org Property:
mainContentOfPage - Purpose: Indicates the main content element of the page
- Format: Schema.org WebPageElement
- Rules:
- Auto-generated with CSS selector
.wiki-content - Used for accessibility and content identification
- Auto-generated with CSS selector
- Schema.org Type: WebPageElement
significantLink (contextual)
- Schema.org Property:
significantLink - Purpose: Significant URLs on the page for navigation
- Format: Array of URLs
- Rules:
- Auto-generated based on page type and category
- System pages get links to Categories, User-Keywords, Welcome
- Schema.org Type: URL
documentationType
- Purpose: Documentation audience and type classification
- Format: Enum:
"user"|"developer"|"api" - Rules:
- OPTIONAL (required for pageType: "documentation")
- Defines target audience for documentation pages
user: End-user documentation and tutorialsdeveloper: Technical implementation guidesapi: API reference and integration docs
- Example:
developer - Schema.org Mapping: Enhances
audienceproperty
isProtected
- Purpose: Prevents user modification of system content
- Format: Boolean
- Rules:
- OPTIONAL (defaults to false)
true: Read-only for users, system-managedfalse: User-editable content- Usually
truefor pageType: "system" - Integrates with UserManager role permissions and ACLManager page-level controls
- Example:
true - Schema.org Mapping: Maps to
DigitalDocumentPermissionobjects for machine-readable access control - Access Control Integration:
- Role-Based: Works with UserManager permissions (
page:edit,admin:system) - Page-Level ACLs: Can be overridden by embedded `` syntax
- Storage-Based: Aligns with category-based storage locations
- Role-Based: Works with UserManager permissions (
- Schema.org DigitalDocumentPermission Generation:
- Protected Content: Generates ReadPermission for public, WritePermission/DeletePermission for admins only
- User Content: Generates ReadPermission for public, WritePermission/CreatePermission for owner/editors, DeletePermission for owner/admins
- System Content: Generates ReadPermission for public, AdministerPermission for system admins only
- Developer Content: Generates ReadPermission for public, WritePermission/CreatePermission for developers/admins
- Comment System: Generates CommentPermission based on page category and user roles
- File Management: Generates UploadPermission for contributors and above, DownloadPermission for all readers
inLanguage (auto-generated)
- Schema.org Property:
inLanguage - Purpose: The language of the content
- Format: Language code string
- Rules:
- Auto-generated as "en-US" for all pages
- Can be overridden for multilingual content
- Schema.org Type: Language or Text
license (auto-generated)
- Schema.org Property:
license - Purpose: License document that applies to this content
- Format: URL or CreativeWork
- Rules:
- Auto-generated from site configuration
- Typically points to site-wide license terms
- Schema.org Type: CreativeWork or URL
publisher (auto-generated)
- Schema.org Property:
publisher - Purpose: Publisher of the content
- Format: Schema.org Organization object
- Rules:
- Auto-generated from site configuration
- References the ngdpbase platform organization
- Schema.org Type: Organization or Person
Complete Schema.org WebPage Example
---
# Required Schema.org WebPage Properties
title: "API Documentation" # → name, headline
pageType: "documentation" # → additionalType (ngdpbase-specific)
category: "Developer" # → about (DefinedTerm) - storage-based
uuid: "api-docs-v1-uuid" # → identifier
lastModified: "2025-09-10T10:00:00.000Z" # → dateModified
# Optional Schema.org Enhanced Properties
user-keywords: [api, reference, integration] # → keywords
categories: [Developer, API] # → about (multiple DefinedTerms) - detailed classification
documentationType: "api" # → audience enhancement
dateCreated: "2025-09-01T10:00:00.000Z" # → dateCreated
isProtected: true # → access control (not Schema.org)
# Auto-generated Schema.org Properties (not in frontmatter):
# url: "https://example.com/view/API Documentation"
# author: { "@type": "Organization", "name": "ngdpbase Platform" }
# publisher: { "@type": "Organization", "name": "ngdpbase Platform" }
# isPartOf: { "@type": "WebSite", "name": "ngdpbase Platform", "url": "/" }
# breadcrumb: { "@type": "BreadcrumbList", ... } (from categories array)
# mainContentOfPage: { "@type": "WebPageElement", "cssSelector": ".wiki-content" }
# inLanguage: "en-US"
# license: "https://example.com/terms"
---
Schema.org JSON-LD Output Example
The above metadata generates this Schema.org JSON-LD:
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "API Documentation",
"headline": "API Documentation",
"url": "https://example.com/view/API%20Documentation",
"identifier": "api-docs-v1-uuid",
"dateModified": "2025-09-10T10:00:00.000Z",
"dateCreated": "2025-09-01T10:00:00.000Z",
"inLanguage": "en-US",
"keywords": "api, reference, integration",
"about": [
{
"@type": "DefinedTerm",
"name": "Developer",
"inDefinedTermSet": {
"@type": "DefinedTermSet",
"name": "ngdpbase Categories"
}
},
{
"@type": "DefinedTerm",
"name": "API",
"inDefinedTermSet": {
"@type": "DefinedTermSet",
"name": "ngdpbase Categories"
}
}
],
"breadcrumb": {
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Developer",
"item": "https://example.com/category/Developer"
},
{
"@type": "ListItem",
"position": 2,
"name": "API",
"item": "https://example.com/category/API"
}
]
},
"mainContentOfPage": {
"@type": "WebPageElement",
"cssSelector": ".wiki-content"
},
"isPartOf": {
"@type": "WebSite",
"name": "ngdpbase Platform",
"url": "https://example.com/"
},
"author": {
"@type": "Organization",
"name": "ngdpbase Platform"
},
"publisher": {
"@type": "Organization",
"name": "ngdpbase Platform"
},
"hasDigitalDocumentPermission": [
{
"@type": "DigitalDocumentPermission",
"permissionType": "ReadPermission",
"grantee": {
"@type": "Audience",
"audienceType": "public"
}
},
{
"@type": "DigitalDocumentPermission",
"permissionType": "WritePermission",
"grantee": {
"@type": "Audience",
"audienceType": "developer"
}
},
{
"@type": "DigitalDocumentPermission",
"permissionType": "CreatePermission",
"grantee": {
"@type": "Audience",
"audienceType": "developer"
}
},
{
"@type": "DigitalDocumentPermission",
"permissionType": "DeletePermission",
"grantee": {
"@type": "Person",
"name": "admin"
}
},
{
"@type": "DigitalDocumentPermission",
"permissionType": "UploadPermission",
"grantee": {
"@type": "Audience",
"audienceType": "contributor"
}
},
{
"@type": "DigitalDocumentPermission",
"permissionType": "CommentPermission",
"grantee": {
"@type": "Audience",
"audienceType": "authenticated"
}
}
]
}
Schema.org WebPage Field Mapping Summary
| ngdpbase Field | Schema.org Property | Required | Type | Max Values | Auto-Generated |
|---|---|---|---|---|---|
title | name, headline | ✅ Yes | Text | 1 | No |
uuid | identifier | ✅ Yes | PropertyValue/Text | 1 | Yes |
lastModified | dateModified | ✅ Yes | DateTime | 1 | Yes |
pageType | additionalType | ✅ Yes | Text | 1 | No |
category | about (DefinedTerm) | ✅ Yes | DefinedTerm | 1 | No |
user-keywords | keywords | ❌ No | Text | 3 | No |
categories | about (multiple) | ❌ No | DefinedTerm | 3 | No |
dateCreated | dateCreated | ❌ No | DateTime | 1 | Optional |
documentationType | audience (enhanced) | ❌ No | Text | 1 | No |
isProtected | hasDigitalDocumentPermission | ❌ No | DigitalDocumentPermission | Multiple | Yes |
| (auto) | url | ✅ Yes | URL | 1 | Yes |
| (auto) | author | ✅ Yes | Organization | 1 | Yes |
| (auto) | publisher | ✅ Yes | Organization | 1 | Yes |
| (auto) | isPartOf | ✅ Yes | WebSite | 1 | Yes |
| (auto) | breadcrumb | ❌ No | BreadcrumbList | 1 | Yes |
| (auto) | mainContentOfPage | ❌ No | WebPageElement | 1 | Yes |
| (auto) | inLanguage | ✅ Yes | Language | 1 | Yes |
| (auto) | license | ❌ No | URL/CreativeWork | 1 | Yes |
Schema.org WebPage Benefits
SEO Optimization
- Rich Snippets: Enhanced search result displays with structured data
- Knowledge Graphs: Integration with Google's knowledge graph system
- Breadcrumb Navigation: Search engines understand page hierarchy
- Content Classification: Better content understanding and indexing
Semantic Web Integration
- Linked Data: Full RDF/JSON-LD compatibility for data exchange
- API Integration: Machine-readable content structure for APIs
- Accessibility: Improved screen reader and assistive technology support
- Cross-Platform: Content works across different platforms and services
Technical Advantages
- Future-Proof: Based on W3C and major search engine standards
- Extensible: Easy to add new Schema.org properties as needed
- Validated: Schema.org provides official validation tools
- Compatible: Works with existing SEO and analytics tools
Usage Guidelines
For Content Creators
- Always provide a clear, descriptive
title(maps to Schema.orgname) - Choose appropriate
pageTypefor operational requirements:userfor personal/project content (preserved during upgrades)documentationfor user guides and tutorials
- Select the most appropriate hierarchical
category(maps to Schema.orgabout) - Add up to 3 relevant
user-keywordsfrom the merged available list:- Base keywords: Provided by app in
/required-pages/User Keywords.md - User extensions: Added by users, stored in
/users/user-keywords.json - Edit interface: Shows combined list automatically
- Base keywords: Provided by app in
- Do NOT manually edit
uuidorlastModifiedfields
User Keywords Storage Architecture
Problem Statement
User keywords need to be:
- Extendable by users during normal operation
- Preserved during app upgrades
- Merged with new base keywords from app updates
- Validated to prevent duplicates and maintain consistency
Hybrid Storage Solution
Primary Storage Locations
| Storage Location | Purpose | Upgrade Behavior | Content Type |
|---|---|---|---|
/required-pages/User Keywords.md | **Base Keywords** | Replaced | App-provided defaults |
/users/user-keywords.json | **User Extensions** | Preserved | User-added keywords |
| Runtime Merge | **Combined List** | Automatic | Base + User extensions |
Base Keywords (/required-pages/User Keywords.md)
---
title: User Keywords
pageType: system
isProtected: true
---
# User Keywords
## Base System Keywords
- documentation
- test
- system
- template
- security
- api
- reference
- integration
User Extensions (/users/user-keywords.json)
{
"userDefinedKeywords": [
"geology",
"medicine",
"psychology",
"project-planning",
"personal"
],
"lastModified": "2025-09-10T10:00:00.000Z",
"addedBy": {
"admin": ["geology", "medicine"],
"user1": ["psychology"],
"user2": ["project-planning", "personal"]
}
}
Runtime Merging Process
- Load Base: Read keywords from
/required-pages/User Keywords.md - Load Extensions: Read user keywords from
/users/user-keywords.json - Merge & Deduplicate: Combine arrays, remove duplicates (case-insensitive)
- Sort & Present: Alphabetical order for consistency
- Validate Selection: Ensure max 3 keywords per page
Upgrade Safety Workflow
During App Upgrade
# 1. Backup user extensions (automatic)
cp /users/user-keywords.json /users/user-keywords.backup.json
# 2. Replace base keywords (app-managed)
# /required-pages/User Keywords.md gets new app defaults
# 3. Merge user extensions (automatic)
# System reads both files and merges at runtime
# 4. Validate & clean (post-upgrade)
# Remove any invalid keywords, update JSON format if needed
User Interface Behavior
- Edit Page: Shows merged list (base + user extensions)
- Add New Keyword: Gets added to
/users/user-keywords.json - Remove Keyword:
- If base keyword: Hidden from user interface
- If user keyword: Removed from
/users/user-keywords.json
Implementation Requirements
KeywordManager Component
class KeywordManager {
async getAvailableKeywords() {
const baseKeywords = await this.loadBaseKeywords();
const userKeywords = await this.loadUserKeywords();
return this.mergeAndDeduplicate(baseKeywords, userKeywords);
}
async addUserKeyword(keyword, userId) {
// Add to /users/user-keywords.json
// Validate against existing keywords
// Track who added it for audit
}
async removeUserKeyword(keyword, userId) {
// Remove from /users/user-keywords.json only
// Cannot remove base keywords
}
}
Validation Rules
- Case Insensitive: "Test" and "test" are duplicates
- Length Limits: Keywords must be 2-20 characters
- Character Restrictions: Alphanumeric, hyphens, underscores only
- Reserved Words: Cannot conflict with system categories
- Maximum Total: 50 combined keywords (base + user)
Migration Strategy
Phase 1: Consolidate Existing Files
- Audit Current Keywords: Extract all unique keywords from existing pages
- Classify Keywords:
- Common/system keywords → Base keywords
- User-specific keywords → User extensions
- Create Base File: New
/required-pages/User Keywords.mdwith system defaults - Create Extensions File: New
/users/user-keywords.jsonwith user additions
Phase 2: Update References
- Update Documentation: All references point to new hybrid system
- Update Page Validation: Use merged keyword list for validation
- Update Edit Interface: Show merged list, track additions properly
Phase 3: Test Upgrade Process
- Simulate Upgrade: Replace base keywords, verify user extensions preserved
- Test Merging: Ensure no duplicates, proper sorting
- Validate Pages: All existing
user-keywordsstill valid after merge
Benefits
✅ Upgrade Safety: User keywords never lost during app updates
✅ Extensibility: Users can add keywords without editing system files
✅ Consistency: Base keywords ensure common vocabulary across installations
✅ Audit Trail: Track who added which keywords for management
✅ Performance: Merging happens at edit time, not page load time
✅ Backup: User extensions automatically preserved and trackable
For Developers
- Use
pageType: "documentation"for all developer docs - Set appropriate
documentationTypefor target audience - Ensure SchemaGenerator.js properly maps metadata to Schema.org properties
- Validate JSON-LD output meets Schema.org WebPage specification
- Auto-generate required Schema.org properties like
url,author,publisher - Test structured data with validation tools regularly
Schema.org WebPage Validation
Required Schema.org Properties (Auto-Generated)
✅ @context: "https://schema.org"
✅ @type: "WebPage"
✅ name: From title field
✅ url: Auto-generated from base URL + page title
✅ dateModified: From lastModified field
Enhanced Schema.org Properties (Context-Dependent)
🔄 headline: From title field
🔄 identifier: From uuid field
🔄 keywords: From user-keywords array
🔄 about: From category and categories fields as DefinedTerms
🔄 breadcrumb: Auto-generated from hierarchical categories
🔄 author: Auto-generated Organization object
🔄 publisher: Auto-generated Organization object
🔄 isPartOf: Auto-generated WebSite object
🔄 mainContentOfPage: Auto-generated WebPageElement
🔄 inLanguage: Auto-generated "en-US"
Validation Tools
File System Organization
Storage Strategy by Category
| Category | Storage Location | Upgrade Behavior | Management | Purpose |
|---|---|---|---|---|
General | /pages/ | Always Preserved | User | User-generated content |
System | /required-pages/ | May be Replaced | App | Required system pages |
Documentation | /required-pages/ | Updated with App | App | User documentation |
Developer | /docs/ | Versioned | Developer | Technical documentation |
Storage Examples by Category
/pages/ (General Category)
- Welcome.md -
category: "General" - MyProject.md -
category: "General", user-keywords: [project] - MeetingNotes-2025.md -
category: "General", user-keywords: [meeting, planning]
/required-pages/ (System Category)
- Categories.md -
category: "System" - PageIndex.md -
category: "System", isProtected: true - User-Keywords.md -
category: "System", isProtected: true
/required-pages/ (Documentation Category)
- Documentation.md -
category: "Documentation" - User-Guide.md -
category: "Documentation", user-keywords: [tutorial] - FAQ.md -
category: "Documentation", user-keywords: [reference]
/docs/ (Developer Category)
- API.md -
category: "Developer", user-keywords: [api, reference] - CONTRIBUTING.md -
category: "Developer", user-keywords: [guide] - Architecture.md -
category: "Developer", user-keywords: [design]
Content Classification Strategy
Primary: Storage-based categories determine file location and upgrade behavior
Secondary: User-keywords provide detailed content classification and filtering
This approach separates operational concerns (where files live) from content concerns (what they contain).
Schema.org WebPage Entity Strategy
ngdpbase uses Schema.org WebPage as the primary entity type for full compliance with web standards and optimal SEO performance.
Why Schema.org WebPage?
Schema.org WebPage is the most appropriate entity type for page content because:
- W3C Standard: Official web standard supported by all major search engines
- Rich Properties: Comprehensive property set including
breadcrumb,mainContentOfPage,significantLink - SEO Optimized: Directly supports Google Rich Snippets and Knowledge Graph integration
- Semantic Web: Full RDF/JSON-LD compatibility for linked data applications
- Accessibility: Enhanced support for screen readers and assistive technologies
- Navigation-Aware: Built-in support for hierarchical content organization
Schema.org Type Selection by Page Category
| Page Category | Schema.org Type | Primary Reasoning | Additional Properties |
|---|---|---|---|
| **All Pages** | **WebPage** | Universal web standard | breadcrumb, mainContentOfPage |
| System/* | **WebPage** | Navigation-heavy reference pages | significantLink array |
| Documentation | **WebPage** + TechArticle | Technical content with web navigation | about with DefinedTerm |
| Project | **WebPage** + CreativeWork | Planning docs with collaboration | author, contributor |
| Meeting Notes | **WebPage** + Article | Time-based collaborative content | dateCreated, dateModified |
| General | **WebPage** | Standard page structure | Core WebPage properties |
Note: GeoHazardWatch defaults to WebPage for all content, with additional types layered on through additionalType or about properties when appropriate.
Schema.org WebPage Property Coverage
Core Properties (Always Present)
- ✅
@context: "https://schema.org" - ✅
@type: "WebPage" - ✅
name: Page title - ✅
url: Full page URL - ✅
dateModified: Last modification timestamp
Enhanced Properties (Context-Dependent)
- 🔄
headline: Page title (for article-like content) - 🔄
identifier: Unique UUID - 🔄
keywords: User-defined tags - 🔄
about: Categories as DefinedTerm objects - 🔄
breadcrumb: Hierarchical navigation - 🔄
mainContentOfPage: Main content element - 🔄
significantLink: Important page links - 🔄
isPartOf: Parent website reference
Organizational Properties (Auto-Generated)
- 🔄
author: Content author (Organization or Person) - 🔄
publisher: Publishing organization - 🔄
inLanguage: Content language - 🔄
license: Content license information
Validation and Testing
All GeoHazardWatch pages generate Schema.org WebPage JSON-LD that validates against:
- Google Rich Results Test: Rich snippet validation
- Schema.org Validator: Official schema validation
- Google Structured Data Testing Tool: Comprehensive testing
- W3C RDF Validator: RDF/linked data validation
See system-category for category configuration, System Keywords and User Keywords for keyword management, and User Documentation for related guides.
No comments yet.