tl;dr: This is placeholder content. Delete it once you’ve used it to learn how the theme handles images, GIFs, and video.
Welcome to the DataKnife blog. This post exists so you have a working example to copy: real frontmatter, headings, and — most importantly — every way this theme lets you embed media.
Images
Drop files in public/assets/img/<year>/<slug>/ and reference them with a normal Markdown image. Paths are absolute from public/:

When you need styling control, use raw HTML instead:
Animations
For short, looping animations this theme uses animated GIFs, embedded exactly like an image — there are no .mp4/.webm files in the original site, just GIFs. The clip below is a placeholder; swap in your own:

To record terminal/UI GIFs, tools like Kap, Gifski, or ffmpeg work well. Keep them under a few MB so pages stay fast.
Video
For longer clips, embed a YouTube video with the theme’s shortcode — put it on its own line (placeholder video below):
{% youtube https://www.youtube.com/watch?v=dQw4w9WgXcQ %}
In .mdx posts you can also use the <TwitterEmbed /> and <YouTubeEmbed /> components directly.
Code blocks
Inline code such as pnpm run build uses single backticks. For anything longer, use a fenced block with a language hint — the theme highlights it with Shiki (min-light in light mode, night-owl in dark mode) and wraps long lines instead of scrolling sideways.
Shell:
# Install dependencies and build the static site
pnpm install
pnpm run build # → dist/ (also builds the Pagefind search index)
TypeScript:
type Dataset = { id: string; rows: number };
async function loadDataset(path: string): Promise<Dataset> {
const res = await fetch(path);
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
return (await res.json()) as Dataset;
}
Python:
from dataclasses import dataclass
@dataclass
class Result:
name: str
score: float
def top(results: list[Result], n: int = 3) -> list[Result]:
"""Return the n highest-scoring results."""
return sorted(results, key=lambda r: r.score, reverse=True)[:n]
Rust:
fn main() {
let numbers = [3, 1, 4, 1, 5, 9, 2, 6];
let sum: i32 = numbers.iter().sum();
println!("sum = {sum}, max = {}", numbers.iter().max().unwrap());
}
SQL:
select customer_id, sum(amount) as total
from orders
where created_at >= date '2026-01-01'
group by customer_id
order by total desc
limit 10;
JSON:
{
"name": "DataKnife",
"tagline": "We don't provide a service. We provide a result.",
"stack": ["astro", "react", "tailwindcss"]
}
Writing posts
- Posts live in
src/content/blog/and can be organized in year folders (e.g.2026/). - Frontmatter (
title,pubDatetime,description,tags) is validated insrc/content.config.ts. - Set
draft: truein the frontmatter to hide a post while you work on it.
That’s it — duplicate this file, change the frontmatter, and start writing.1
Footnotes
-
All copy here is placeholder text matching the original theme’s formatting. The colors, logo, avatar, and images come from the DataKnife brand kit. ↩