Build a blog
Create a blog from scratch with posts, tags, pagination, custom themes, and deployment.
What your blog will look like after this guide.
Initialize the project #
Scaffold a new blog with the blog template:
zorto init --template blog my-blog cd my-blog
This creates a site with an Atom feed, code highlighting, and two example posts. Start the dev server:
zorto preview --open
Your blog is live at http://localhost:1111.
Understand the structure #
The generated config.toml looks like this:
base_url = "http://localhost:1111" title = "My Blog" theme = "default" generate_feed = true [markdown] highlight_code = true [extra] copyright_html = '<a href="/">My Blog</a> by Author via <a href="https://zorto.dev" target="_blank" rel="noopener">Zorto</a>'
The homepage (content/_index.md) is a section that sorts by date and paginates:
+++ title = "Home" sort_by = "date" paginate_by = 10 +++
The posts section (content/posts/_index.md) lists all blog posts:
+++ title = "Posts" sort_by = "date" +++
Write a new post #
Create content/posts/my-new-post.md:
+++ title = "My new post" date = "2026-04-04" description = "A short description for SEO and feeds." tags = ["tutorial"] +++ A short summary of the post appears here. <!-- more --> The full content continues after the "more" marker. Everything above it becomes the summary shown on listing pages and in the Atom feed. ## A heading in the post Regular markdown works: **bold**, *italic*, `code`, [links](https://example.com), and images.
The date field determines sort order (newest first) and inclusion in the Atom feed. The <!-- more --> marker splits the summary from the full content.
Enable tags #
Add a taxonomy to config.toml:
[[taxonomies]] name = "tags"
Then assign tags in each postβs frontmatter:
+++ title = "My new post" date = "2026-04-04" tags = ["tutorial", "rust"] +++
Zorto automatically generates:
/tags/β list of all tags/tags/tutorial/β all posts tagged βtutorialβ/tags/rust/β all posts tagged βrustβ
Add categories too #
You can define multiple taxonomies:
[[taxonomies]] name = "tags" [[taxonomies]] name = "categories"
Then use both in frontmatter:
+++ title = "My new post" date = "2026-04-04" tags = ["tutorial"] categories = ["tech"] +++
Configure pagination #
Control how many posts appear per page in the sectionβs _index.md:
+++ title = "Posts" sort_by = "date" paginate_by = 5 +++
Zorto generates paginated pages: /posts/, /posts/page/2/, /posts/page/3/, and so on.
Choose a theme #
Change the theme in config.toml:
theme = "ocean"
Available themes: zorto, dkdc, default, ember, forest, ocean, rose, slate, midnight, sunset, mint, plum, sand, arctic, lime, charcoal. All support light and dark mode.
Preview different themes by changing the value and checking the dev server β live reload picks up config changes.
Customize colors #
Override CSS variables without changing the theme. Create sass/custom.scss:
:root { --accent: #e74c3c; --background: #1a1a2e; --max-width: 800px; }
Then load it via the extra_head block. Create templates/base.html:
{% extends "base.html" %} {% block extra_head %} <link rel="stylesheet" href="/custom.css"> {% endblock %}
Zorto compiles SCSS to CSS at build time β sass/custom.scss becomes /custom.css in the output.
Add an about page #
Create content/about.md:
+++ title = "About" +++ This is my blog about Rust, static sites, and building things.
This creates a standalone page at /about/ β it is not part of any section.
Set up multiple authors #
If your blog has multiple authors, add an authors taxonomy:
# config.toml [[taxonomies]] name = "authors"
Then use it in each post:
+++ title = "Guest post" date = "2026-04-04" authors = ["Alice"] +++
Zorto generates /authors/ and /authors/alice/ automatically.
Use drafts #
Mark a post as a draft to exclude it from production builds:
+++ title = "Work in progress" date = "2026-04-04" draft = true +++
Preview drafts locally:
zorto preview --drafts
Drafts are excluded from zorto build output and the Atom feed.
Add co-located images #
For posts with images, use a directory instead of a single file:
mkdir -p content/posts/photo-gallery
Create content/posts/photo-gallery/index.md:
+++ title = "Photo gallery" date = "2026-04-04" +++ 
Place sunset.jpg alongside index.md. Zorto copies the image to the output directory, preserving the relative path.
Set the base URL for production #
Before deploying, update base_url in config.toml:
base_url = "https://myblog.com"
This affects permalinks, the Atom feed URL, sitemaps, and Open Graph tags. The dev server overrides it to localhost automatically.
Deploy #
Build the site:
zorto build
The output goes to public/. Deploy it to any static host. For Netlify, create netlify.toml:
[build] command = "curl -LsSf https://dkdc.sh/zorto/install.sh | sh && zorto build" publish = "public"
See Deploy your site for GitHub Pages, Vercel, and Cloudflare Pages instructions.
Related guides #
- Add a blog β quick reference for blog sections, tags, feeds, and drafts
- Blog, events, and more β how sections and pagination work under the hood
- Customize your theme β override templates, styles, and shortcodes
- Customize styles β CSS variables, light/dark mode, fonts
- Set up multiple authors β taxonomies for author pages