Post Output Formats ¶
markata-go can generate multiple output formats for each post beyond the standard HTML. This enables use cases like providing raw markdown for API consumers, plain text for accessibility, or generating social media preview cards.
Configuration ¶ #
Configure output formats in your markata-go.toml:
[markata-go.post_formats]
html = true # Standard HTML (default: true)
markdown = true # Raw markdown source (default: true)
text = true # Plain text output (default: true)
og = true # OpenGraph card HTML (default: true)
By default, all post formats are enabled. This allows standard web txt files like robots.txt, llms.txt, and humans.txt to work out of the box while also providing social sharing cards.
Available Formats ¶ #
HTML (default) ¶ #
The standard HTML output, generated by default.
Output: /your-post/index.html
[markata-go.post_formats]
html = true # This is the default
Markdown ¶ #
Outputs the raw markdown source with reconstructed frontmatter. Useful for:
- “View Source” links on your site
- API consumers who want raw content
- Copy-paste workflows
Output: /your-post.md (canonical) with redirect from /your-post/index.md
[markata-go.post_formats]
markdown = true # Enabled by default
The markdown output includes the original frontmatter:
---
title: "Your Post Title"
description: "Post description"
date: 2026-01-22
published: true
tags:
- example
---
Your original markdown content...
Plain Text ¶ #
Outputs a plain text version of the content, perfect for:
- Standard web txt files (robots.txt, llms.txt, humans.txt)
- Screen readers and accessibility tools
- Command-line readers (curl, wget)
- Low-bandwidth situations
- Text-based browsers
Output: /your-post.txt (canonical) with redirect from /your-post/index.txt
[markata-go.post_formats]
text = true # Enabled by default
The text output includes:
- Title (underlined with
=) - Description (if present)
- Date
- Raw markdown content
Example output:
My Post Title
=============
A description of the post.
Date: January 22, 2026
The actual content of the post in plain text form...
OpenGraph Card (OG) ¶ #
Generates a special HTML page optimized for screenshot tools to create social media preview images. The page is sized at 1200x630 pixels (standard OG image dimensions).
Output: /your-post/og/index.html
[markata-go.post_formats]
og = true
Using OG Cards for Social Images ¶ #
The OG card HTML is designed to be captured by screenshot tools like Puppeteer or Playwright:
// Example with Puppeteer
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1200, height: 630 });
await page.goto('https://yoursite.com/your-post/og/');
await page.screenshot({ path: 'og-image.png' });
The default OG card template includes:
- Post title (large, prominent)
- Author name and site URL
- Publication date
- Theme palette and background styling
You can customize the OG card appearance by providing your own post-og.html template.
If no post-specific OG template exists, og-card.html is used as a fallback.
Standard Web Txt Files ¶ #
markata-go supports generating standard web txt files at their expected canonical URLs:
| File | Purpose |
|---|---|
/robots.txt |
Robot exclusion standard for web crawlers |
/llms.txt |
AI/LLM guidance file for language models |
/humans.txt |
Human-readable site credits |
To create these, simply add markdown files with the appropriate slugs:
<!-- robots.md -->
---
title: "Robots"
slug: robots
published: true
---
User-agent: *
Allow: /
Disallow: /private/
<!-- llms.md -->
---
title: "LLMs"
slug: llms
published: true
---
# LLMs.txt
This site welcomes AI training on its content.
## Guidelines
- Attribution appreciated
- Commercial use allowed
With text format enabled (default), these generate:
/robots.txt- The canonical robots.txt file/robots/index.txt- Redirect for backwards compatibility/robots/index.txt/index.html- HTML redirect for static hosts/llms.txt- The canonical llms.txt file/llms/index.txt- Redirect for backwards compatibility/llms/index.txt/index.html- HTML redirect for static hosts
Reversed Redirects ¶ #
For .txt and .md formats, markata-go uses reversed redirects to ensure content is at the canonical URL:
| Canonical Location | Redirect From |
|---|---|
/my-post.md |
/my-post/index.md |
/my-post.txt |
/my-post/index.txt |
This is the opposite of HTML, which uses directory-based URLs:
| Canonical Location | Redirect From |
|---|---|
/my-post/index.html |
/my-post.html |
The reversed approach ensures standard web files like robots.txt work correctly while maintaining backwards compatibility with directory-based URLs.
Clean URLs ¶ #
markata-go generates both canonical files and redirects for maximum compatibility:
| User requests | Canonical file | Notes |
|---|---|---|
/my-post.md |
/my-post.md |
Direct access to canonical |
/my-post/index.md |
Redirects to /my-post.md |
Backwards compatibility |
/my-post.txt |
/my-post.txt |
Direct access to canonical |
/my-post/index.txt |
Redirects to /my-post.txt |
Backwards compatibility |
This means users can use either URL style:
# All of these work:
curl https://example.com/my-post.md # Canonical
curl https://example.com/my-post/index.md # Redirects to canonical
# Standard web txt files work at expected URLs:
curl https://example.com/robots.txt
curl https://example.com/llms.txt
The redirects use HTML meta refresh for maximum compatibility across browsers and HTTP clients.
Visible Format Links ¶ #
When you enable alternate formats, markata-go automatically displays format links on your posts and feeds. These appear in the post footer (for posts) or feed header (for feeds).
For posts with markdown, text, or og enabled, visitors see:
- View as: Markdown | Text | Card
For feeds, visitors see subscription options:
- Subscribe: RSS | Atom | JSON | Markdown | Text
Content Negotiation ¶ #
markata-go’s canonical short URLs (/slug.md, /slug.txt) plus HTML directory pages (/slug/index.html) enable server-side content negotiation. This allows clients to request their preferred format using HTTP Accept headers.
How It Works ¶ #
Instead of requesting a specific file, clients request the directory URL:
GET /my-post/
Accept: text/plain
The server returns the appropriate format based on the Accept header.
Nginx Configuration ¶ #
server {
listen 80;
server_name example.com;
root /var/www/html;
# MIME types for txt/md files
location ~ \.(txt|md)$ {
default_type text/plain;
charset utf-8;
}
location / {
# Try exact file first (for /robots.txt), then negotiate by Accept header
try_files $uri $uri/index.html @negotiate;
}
location @negotiate {
# Map Accept header to file extension
set $ext "html";
if ($http_accept ~* "text/plain") {
set $ext "txt";
}
if ($http_accept ~* "text/markdown") {
set $ext "md";
}
# Strip trailing slash for canonical format files
set $base $uri;
if ($base ~ "^(.+)/$") {
set $base $1;
}
# Try the negotiated format, falling back to index.html
try_files $base.$ext $uri/index.html =404;
}
}
Note: The try_files order is important. Files like /robots.txt are served directly because $uri matches the exact file before falling back to content negotiation.
Caddy Configuration ¶ #
example.com {
root * /var/www/html
file_server
# MIME types for txt/md files
@txtmd path *.txt *.md
header @txtmd Content-Type "text/plain; charset=utf-8"
@wantsText {
header Accept *text/plain*
}
@wantsMarkdown {
header Accept *text/markdown*
}
# Rewrite to plain text when requested
handle @wantsText {
uri strip_suffix /
rewrite * {path}.txt
}
# Rewrite to markdown when requested
handle @wantsMarkdown {
uri strip_suffix /
rewrite * {path}.md
}
# Try exact file first (for /robots.txt), then index.html
try_files {path} {path}/index.html {path}.html
}
Note: Caddy’s file_server naturally serves exact files first, so /robots.txt works correctly without additional configuration.
Apache Configuration ¶ #
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
# Enable content negotiation
Options +MultiViews
# Define type mappings
AddType text/html .html
AddType text/markdown .md
AddType text/plain .txt
# Set charset for text files
AddDefaultCharset UTF-8
# Prefer HTML by default
DirectoryIndex index.html index.md index.txt
# Ensure exact files are served first (for /robots.txt)
<Directory /var/www/html>
RewriteEngine On
# If the exact file exists, serve it directly
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Otherwise fall through to MultiViews negotiation
</Directory>
</VirtualHost>
Note: The RewriteCond %{REQUEST_FILENAME} -f rule ensures that canonical files like /robots.txt are served directly before MultiViews content negotiation kicks in.
Testing Content Negotiation ¶ #
Use curl to test different formats:
# Request HTML (default)
curl https://example.com/my-post/
# Request plain text
curl -H "Accept: text/plain" https://example.com/my-post/
# Request markdown
curl -H "Accept: text/markdown" https://example.com/my-post/
# Request with quality values
curl -H "Accept: text/plain;q=0.9, text/html;q=0.8" https://example.com/my-post/
Homepage with index.md ¶ #
markata-go provides special handling for index.md files to create homepages and directory-based URLs:
| File Path | Generated URL |
|---|---|
./index.md |
/ (homepage) |
docs/index.md |
/docs/ |
blog/guides/index.md |
/blog/guides/ |
Creating a Homepage ¶ #
Simply create an index.md file in your content root:
---
title: "Welcome to My Site"
description: "A personal blog about programming"
published: true
template: home.html
---
# Welcome
This is my homepage content...
This generates /index.html as your site’s homepage, allowing custom content instead of requiring a feed with empty slug.
Directory Index Pages ¶ #
Create index.md files in subdirectories for section landing pages:
docs/
index.md -> /docs/
getting-started.md -> /docs/getting-started/
guides/
index.md -> /docs/guides/
advanced.md -> /docs/guides/advanced/
Example Configuration ¶ #
A typical configuration enabling all formats:
[markata-go]
url = "https://example.com"
title = "My Site"
[markata-go.post_formats]
html = true # Standard pages
markdown = true # View source support
text = true # Plain text for accessibility
og = true # Social card generation
Automation Example ¶ #
Here’s a complete workflow for generating social images:
-
Enable OG format in your config:
[markata-go.post_formats] og = true -
Build your site:
markata-go build -
Generate screenshots with a script:
#!/bin/bash for og_page in output/*/og/index.html; do post_dir=$(dirname $(dirname "$og_page")) slug=$(basename "$post_dir") npx puppeteer screenshot \ --viewport 1200x630 \ "file://$og_page" \ "$post_dir/og-image.png" done -
Reference in templates:
<meta property="og:image" content="{{ config.url }}{{ post.href }}og-image.png">
See Also ¶ #
- Configuration Guide - Full configuration reference
- Templates Guide - Customizing templates including og.html
- Deployment Guide - Deploying your generated site