Documentation Index
Fetch the complete documentation index at: https://mintlify.com/buttondown/cli/llms.txt
Use this file to discover all available pages before exploring further.
The snippets module handles synchronization of reusable content snippets between the Buttondown API and local markdown files.
Overview
Snippets are stored locally as markdown files with YAML frontmatter in the snippets/ directory. Each snippet is identified by a unique identifier used as the filename.
Types
Snippet
Based on the Buttondown API Snippet schema from OpenAPI specification.
type Snippet = components["schemas"]["Snippet"]
Typically includes:
id - Unique identifier
identifier - User-defined identifier (used in templates)
name - Human-readable name
content - The snippet content (HTML/markdown)
FrontMatterFields
Fields extracted to YAML frontmatter:
type FrontMatterFields = Pick<Snippet, "id" | "name">
Serialization Functions
deserialize()
Parses markdown content with YAML frontmatter into a snippet object.
function deserialize(content: string): {
snippet: Partial<Snippet>;
isValid: boolean;
error?: string;
}
Markdown content with YAML frontmatter delimited by ---
Parsed snippet object with frontmatter fields and content
Whether the content was successfully parsed with valid frontmatter
Error message if parsing failed (“Invalid format (missing frontmatter)“)
Expected format:
---
id: snippet_id
name: Snippet Name
---
Snippet content goes here
Behavior
- Splits content on
--- delimiters
- Requires at least 3 parts (empty, frontmatter, content)
- Parses frontmatter as YAML
- Extracts
id and name fields
- Stores everything after second
--- as content
- Trims whitespace from content
Example
const result = deserialize(`---
id: snip_123
name: Email Footer
---
Thanks for reading!
Unsubscribe: {{unsubscribe_url}}`);
if (result.isValid) {
console.log(result.snippet.name); // "Email Footer"
console.log(result.snippet.content); // "Thanks for reading!\nUnsubscribe: {{unsubscribe_url}}"
}
serialize()
Converts a snippet object into markdown content with YAML frontmatter.
function serialize(snippet: Partial<Snippet>): string
Snippet object containing content and frontmatter fields
Formatted markdown with YAML frontmatter
Behavior
- Separates
content from other fields
- Only includes non-null, non-undefined, non-empty frontmatter fields
- Only includes fields defined in
FRONT_MATTER_FIELDS (id, name)
- Formats YAML with 2-space indentation
- Returns format:
---\n{yaml}\n---\n\n{content}
Example
const markdown = serialize({
id: "snip_123",
name: "Email Footer",
content: "Thanks for reading!\nUnsubscribe: {{unsubscribe_url}}"
});
console.log(markdown);
// ---
// id: snip_123
// name: Email Footer
// ---
//
// Thanks for reading!
// Unsubscribe: {{unsubscribe_url}}
Resource Objects
REMOTE_SNIPPETS_RESOURCE
Handles snippet operations with the Buttondown API.
const REMOTE_SNIPPETS_RESOURCE: Resource<Snippet[], Snippet[]>
Methods
get(configuration)
Fetches all snippets from the API with pagination.
async get(configuration: Configuration): Promise<Snippet[]>
Configuration with API credentials
Array of all snippets from the API
- Automatically handles pagination (100 items per page)
- Continues fetching until all snippets are retrieved
set(value, configuration)
Creates or updates snippets via the API.
async set(
value: Snippet[],
configuration: Configuration
): Promise<OperationResult>
Array of snippets to create or update
Configuration with API credentials
Counts of created, updated, deleted, and failed operations
Behavior
- Updates snippets that have an
id field (PATCH /snippets/{id})
- Creates new snippets without an
id field (POST /snippets)
- For new snippets, requires
identifier, name, and content fields
- Returns operation counts (updated, created, deleted, failed)
Example
const snippets = [
{
id: "snip_123",
identifier: "footer",
name: "Email Footer",
content: "Updated content"
},
{
identifier: "header",
name: "Email Header",
content: "New snippet content"
}
];
const result = await REMOTE_SNIPPETS_RESOURCE.set(snippets, config);
console.log(`Updated: ${result.updated}, Created: ${result.created}`);
// Updated: 1, Created: 1
LOCAL_SNIPPETS_RESOURCE
Handles snippet operations with local markdown files.
const LOCAL_SNIPPETS_RESOURCE: Resource<Snippet[], string[]>
Methods
get(configuration)
Reads all snippets from the snippets/ directory.
async get(configuration: Configuration): Promise<Snippet[]>
Configuration with directory path
Array of all valid snippets from markdown files
Behavior
- Searches for all
.md files in snippets/ directory
- Parses each file using
deserialize()
- Extracts
identifier from filename (without .md extension)
- Skips invalid files
- Returns array of snippet objects with
identifier field added
Example
const snippets = await LOCAL_SNIPPETS_RESOURCE.get(config);
// Reads files like:
// - snippets/footer.md
// - snippets/header.md
// Returns snippets with identifier from filename
set(value, configuration)
Writes snippets as markdown files to the snippets/ directory.
async set(
value: Snippet[],
configuration: Configuration
): Promise<OperationResult>
Array of snippets to write
Configuration with directory path
Operation result with updated count
Behavior
- Creates
snippets/ directory if it doesn’t exist
- Uses snippet’s
identifier field as filename
- Format:
snippets/{identifier}.md
- Overwrites existing files with same identifier
- Serializes each snippet to markdown with frontmatter
Example
const snippets = [
{
identifier: "footer",
name: "Email Footer",
content: "Thanks for reading!"
},
{
identifier: "cta-button",
name: "Call to Action",
content: "[Subscribe now]({{subscribe_url}})"
}
];
await LOCAL_SNIPPETS_RESOURCE.set(snippets, config);
// Creates:
// - snippets/footer.md
// - snippets/cta-button.md
SNIPPETS_RESOURCE
Combined resource group for snippet synchronization.
const SNIPPETS_RESOURCE: ResourceGroup<Snippet[], Snippet[], string[]>
Properties
Resource identifier: "snippets"
remote
Resource<Snippet[], Snippet[]>
Remote API resource handler
local
Resource<Snippet[], string[]>
Local filesystem resource handler
Usage Patterns
Sync Snippets from Remote to Local
import { SNIPPETS_RESOURCE } from "./sync/snippets.js";
const config = {
baseUrl: "https://api.buttondown.email/v1",
apiKey: "your-api-key",
directory: "./buttondown-data"
};
// Fetch all snippets from API
const remoteSnippets = await SNIPPETS_RESOURCE.remote.get(config);
console.log(`Found ${remoteSnippets.length} snippets`);
// Save to local markdown files
await SNIPPETS_RESOURCE.local.set(remoteSnippets, config);
console.log("Snippets synced to snippets/ directory");
Push Local Changes to Remote
// Read all local snippet files
const localSnippets = await SNIPPETS_RESOURCE.local.get(config);
// Push changes to API
const result = await SNIPPETS_RESOURCE.remote.set(
localSnippets,
config
);
console.log(
`Updated: ${result.updated}, Created: ${result.created}`
);
Working with Individual Snippet
import { serialize, deserialize } from "./sync/snippets.js";
import { readFile, writeFile } from "fs/promises";
// Read and parse snippet
const content = await readFile("snippets/footer.md", "utf8");
const result = deserialize(content);
if (result.isValid) {
const snippet = result.snippet;
// Modify content
snippet.content += "\n\nP.S. Check out our blog!";
// Save back to file
const updated = serialize(snippet);
await writeFile("snippets/footer.md", updated);
}
Constants
FRONT_MATTER_FIELDS
Array of field names included in YAML frontmatter:
const FRONT_MATTER_FIELDS: (keyof FrontMatterFields)[] = ["id", "name"]
Only these fields are extracted from YAML and included when serializing.