The FrontMatterCache interface represents parsed YAML frontmatter from a markdown file. Obsidian provides utilities for working with frontmatter metadata.
Interface Definition
export interface FrontMatterCache {
[key: string]: any;
}
The FrontMatterCache is a dictionary-like object where keys are frontmatter property names and values can be any valid YAML type.
Common Frontmatter Properties
While frontmatter can contain any properties, some are commonly used in Obsidian:
Tags associated with the note. Can be a single tag or an array of tags.
Alternative names for the note. Used for linking and search.
CSS classes to apply to the note in reading mode.
Whether the note should be published (used by Obsidian Publish)
FrontMatterInfo
Provides detailed information about the frontmatter block in a file.
export interface FrontMatterInfo {
/** Whether this file has a frontmatter block */
exists: boolean;
/** String representation of the frontmatter */
frontmatter: string;
/** Start of the frontmatter contents (excluding the ---) */
from: number;
/** End of the frontmatter contents (excluding the ---) */
to: number;
/** Offset where the frontmatter block ends (including the ---) */
contentStart: number;
}
FrontmatterLinkCache
Available since version 1.4.0
Represents a link found in the frontmatter.
export interface FrontmatterLinkCache extends Reference {
key: string;
}
Utility Functions
getFrontMatterInfo
Given the contents of a file, get information about the frontmatter of the file, including whether there is a frontmatter block, the offsets of where it starts and ends, and the frontmatter text.
getFrontMatterInfo(content: string): FrontMatterInfo
The file content to parse
Returns: FrontMatterInfo - Information about the frontmatter block
parseYaml
Parse raw YAML into a JavaScript object.
parseYaml(yaml: string): any
Returns: any - The parsed object
stringifyYaml
Convert a JavaScript object into YAML string.
stringifyYaml(obj: any): string
The object to convert to YAML
Returns: string - The YAML string representation
Examples
Reading Frontmatter
const file = this.app.workspace.getActiveFile();
if (file) {
const cache = this.app.metadataCache.getFileCache(file);
if (cache?.frontmatter) {
// Access standard properties
const title = cache.frontmatter.title;
const tags = cache.frontmatter.tags;
const aliases = cache.frontmatter.aliases;
// Access custom properties
const customProp = cache.frontmatter['my-custom-property'];
console.log('Title:', title);
console.log('Tags:', tags);
}
}
Updating Frontmatter
import { parseYaml, stringifyYaml } from 'obsidian';
async function updateFrontmatter(file: TFile, updates: Record<string, any>) {
const content = await this.app.vault.read(file);
const frontmatter = this.app.metadataCache.getFileCache(file)?.frontmatter;
if (frontmatter) {
// Merge updates with existing frontmatter
const updated = { ...frontmatter, ...updates };
// Remove position property (added by Obsidian, not part of original frontmatter)
delete updated.position;
// Convert to YAML
const yaml = stringifyYaml(updated);
// Replace frontmatter in file
const newContent = content.replace(
/^---\n[\s\S]*?\n---/,
`---\n${yaml}---`
);
await this.app.vault.modify(file, newContent);
}
}
// Usage
await updateFrontmatter(file, {
title: 'New Title',
tags: ['tag1', 'tag2'],
'custom-property': 'value'
});
Adding Frontmatter to a File
import { stringifyYaml } from 'obsidian';
async function addFrontmatter(file: TFile, frontmatter: Record<string, any>) {
const content = await this.app.vault.read(file);
const yaml = stringifyYaml(frontmatter);
const newContent = `---\n${yaml}---\n\n${content}`;
await this.app.vault.modify(file, newContent);
}
// Usage
await addFrontmatter(file, {
title: 'My Note',
tags: ['important', 'project'],
created: new Date().toISOString()
});
Processing Frontmatter with FileManager
// Using FileManager.processFrontMatter for safer frontmatter updates
await this.app.fileManager.processFrontMatter(file, (frontmatter) => {
// Modify frontmatter object directly
frontmatter.title = 'Updated Title';
frontmatter.modified = new Date().toISOString();
// Add new property
frontmatter['custom-field'] = 'value';
// Update array property
if (!frontmatter.tags) {
frontmatter.tags = [];
}
frontmatter.tags.push('new-tag');
});
Checking for Frontmatter Existence
import { getFrontMatterInfo } from 'obsidian';
const file = this.app.workspace.getActiveFile();
if (file) {
const content = await this.app.vault.read(file);
const fmInfo = getFrontMatterInfo(content);
if (fmInfo.exists) {
console.log('Frontmatter found!');
console.log('Content:', fmInfo.frontmatter);
console.log('Starts at:', fmInfo.from);
console.log('Ends at:', fmInfo.to);
} else {
console.log('No frontmatter in this file');
}
}
import { getAllTags } from 'obsidian';
const file = this.app.workspace.getActiveFile();
if (file) {
const cache = this.app.metadataCache.getFileCache(file);
if (cache) {
// Gets tags from both frontmatter and content
const allTags = getAllTags(cache);
console.log('All tags:', allTags);
}
}
Frontmatter must be at the very beginning of a file and enclosed by triple dashes:
---
title: My Note
tags:
- project
- important
aliases:
- Alternative Name
created: 2024-01-15
custom-property: value
---
# Note Content
The rest of your note goes here...
Best Practices
-
Use FileManager.processFrontMatter: When modifying frontmatter, prefer using
FileManager.processFrontMatter() as it handles edge cases and preserves formatting.
-
Check for null values: Always check if frontmatter exists before accessing properties.
-
Handle array values: Frontmatter properties can be arrays or single values. Handle both cases:
const tags = cache.frontmatter?.tags;
const tagArray = Array.isArray(tags) ? tags : tags ? [tags] : [];
- Remove the position property: When stringifying frontmatter, remove the
position property that Obsidian adds to the cached metadata.