Content
Write blog posts and product pages in plain Markdown. No coding required.
How content works
Velat uses Markdown for long-form content. Every blog post and every product is a single .md file inside the data/ folder.
data/
├── blog/
│ ├── index.json → blog page settings (title, desc, perPage)
│ ├── my-first-post.md
│ └── another-post.md
└── products/
├── index.json → products page settings
├── my-product.md
└── another-product.mdWhy Markdown?
- ―Write in plain text — no HTML, no code
- ―Format with simple symbols (
**bold**,# Heading) - ―One file per post, easy to find and edit
- ―Works with any text editor (Notepad, VS Code, etc.)
Write a blog post
Step 1: Create the file
Inside data/blog/, create a new file. The filename becomes the URL slug.
Example: my-first-post.md → /blog/my-first-post
Use lowercase letters and hyphens. No spaces.
Step 2: Add frontmatter
Every post starts with a frontmatter block between `` lines:
title: "My First Post"
date: "2026-10-12"
author: "Your Name"
category: "Engineering"
description: "A short summary that appears on the blog list page."
readingTime: "5 min"
image: "https://images.unsplash.com/photo-xxx?w=1200"
Field reference:
| Field | Required | What it does |
|---|---|---|
title | Yes | Post title, shown on list and detail pages |
date | Yes | Sort order — newest first |
author | Yes | Shown on list and detail pages |
category | Yes | Used for filtering on /blog |
description | Yes | Short summary on the blog card |
readingTime | No | Defaults to "4 min" |
image | No | Cover image (URL or local path) |
Step 3: Write the body
Below the frontmatter, write your content in Markdown:
title: "My First Post"
date: "2026-10-12"
author: "Your Name"
category: "Engineering"
description: "A short summary."
readingTime: "5 min"
## Introduction
This is a paragraph. You can write normally.
## Main section
You can use **bold text**, *italic text*, and `inline code`.
- Bullet list item one
- Bullet list item two
- Bullet list item three
### Sub-section
Blockquotes look like this:
> A quote from someone important.
Code blocks:
npm install
Links look like [this](https://example.com).Step 4: Save and view
Save the file. Open /blog in your browser. Your new post appears automatically.
Write a product page
Products use the same structure as blog posts, but with different frontmatter fields.
Step 1: Create the file
Inside data/products/, create a new .md file.
Example: my-product.md → /products/my-product
Step 2: Add frontmatter
title: "My Product"
slug: "my-product"
price: 29
category: "Automation"
description: "Full product description for the detail page."
shortDesc: "Short summary for the card."
image: "https://images.unsplash.com/photo-xxx?w=1200"
features:
- "First feature"
- "Second feature"
- "Third feature"
- "Fourth feature"
Field reference:
| Field | Required | What it does |
|---|---|---|
title | Yes | Product name |
slug | No | URL slug — defaults to filename |
price | Yes | Number only, no $ sign |
category | Yes | Used for filtering |
description | Yes | Long description on detail page |
shortDesc | Yes | Short summary on card |
image | No | Product image |
features | Yes | List of features shown as checklist |
Step 3: Write the body
Below the frontmatter, add the detailed content:
title: "My Product"
price: 29
category: "Automation"
description: "Full description."
shortDesc: "Short summary."
features:
- "First feature"
- "Second feature"
## Overview
Explain what the product does.
## How it works
Describe the mechanism.
## Pricing
Details about the price.Markdown cheat sheet
| Syntax | Result |
|---|---|
# Heading 1 | Large heading |
## Heading 2 | Medium heading (appears in Table of Contents) |
### Heading 3 | Small heading (appears in Table of Contents) |
**bold** | bold |
*italic* | italic |
` code ` | code |
- item | Bullet list |
> quote | Blockquote |
[text](url) | Link |
| Triple backticks | Code block |
Change blog list settings
Open data/blog/index.json:
{
"seo": {
"title": "Journal — Your Brand",
"description": "Notes on building AI products."
},
"eyebrow": "Editorial Journal",
"title": "Journal",
"desc": "Notes on building AI products that ship.",
"perPage": 6,
"categoryAll": "All"
}| Field | What it does |
|---|---|
seo | Browser tab and Google description |
eyebrow | Small text above the title |
title | Large heading on /blog |
desc | Subtitle below the heading |
perPage | How many posts show per page |
categoryAll | Label for the "show all" filter button |
Change product list settings
Open data/products/index.json:
{
"seo": {
"title": "Products — Your Brand",
"description": "Browse our products."
},
"eyebrow": "Product Catalog",
"title": "Sections that convert",
"desc": "Each block is designed to move visitors to action.",
"perPage": 6,
"searchPlaceholder": "Search tools...",
"cardLabels": {
"priceSuffix": "/ mo",
"footerLeft": "Spec details",
"footerLink": "View documentation"
},
"categoryAll": "All"
}Same as blog, plus:
- ―
searchPlaceholder— text inside the search input - ―
cardLabels— labels shown on each product card
Images
Local images
1. Save the image inside public/images/
2. Reference it as /images/your-file.avif
image: "/images/product-cover.avif"Remote images (Unsplash, etc.)
Use the full URL:
image: "https://images.unsplash.com/photo-xxx?w=1200"You must whitelist the domain in next.config.js:
images: {
remotePatterns: [
{ protocol: "https", hostname: "images.unsplash.com", pathname: "/**" }
]
}No image
If you skip the image field, the card shows a gradient placeholder with the category name.
Categories
Categories come from the category field in each post or product. They appear automatically as filter buttons.
Best practice: stick to 3–5 categories. More than that clutters the filter bar.
To add a new category, just write it in a post's frontmatter. It appears on the next refresh.
Troubleshooting
Post doesn't appear on `/blog`
Check that:
- ―The file is inside
data/blog/ - ―It ends with
.md - ―The frontmatter has `
on the first line and a closing` - ―
titleanddateare present
Image doesn't load
- ―If using a remote URL, make sure the domain is whitelisted in
next.config.js - ―If local, check the file exists in
public/images/
Formatting looks wrong
- ―Blank line required between paragraphs
- ―Blank line required before and after headings
- ―List items start with
-(dash + space)
Special characters break YAML
If your title contains : or ", wrap it in quotes:
title: "My Post: A Story"