How to Setup Your Own Blog with Zola - Zero to Published

I wanted to start a blog. Looked at WordPress - too complicated, needs hosting, plugins, security updates. Looked at Medium - don't own your content. Looked at Substack - locked into their platform.

I kept seeing developers with clean, fast blogs. No ads, no tracking, just text and code. Asked around. Most of them used static site generators.

That seemed complicated too. Until I tried Zola.

The problem with common blogging platforms

When people think "blog," they think WordPress. Install on a server, configure MySQL, manage plugins, fight spam, update constantly to avoid security holes.

Or they think Medium. Write in their editor, publish, done. But Medium owns your content. They can paywall your posts. Your blog lives on their domain.

WordPress:

  • Needs hosting (monthly cost)
  • Database setup
  • Plugin management
  • Security updates
  • Backup handling
  • Slow page loads

Medium/Substack:

  • Don't own your content
  • Can't customize design
  • Their domain, not yours
  • They control monetization
  • Platform lock-in

Ghost/other CMSs:

  • Still need hosting
  • Still need database
  • Monthly fees add up

I wanted something simpler. Write markdown files, run one command, get a website. No server, no database, no monthly bills.

What makes Zola different

Zola is a static site generator. You write content in markdown files, run zola build, and get static HTML files. Upload those files anywhere - Netlify, GitHub Pages, your own server. No backend needed.

Here's what actually matters:

Single binary: Download one file, that's it. No dependencies, no Python environment, no Node.js modules. Just one executable.

Fast: Written in Rust. Builds in milliseconds, not seconds. I have 20+ blog posts, Zola builds the entire site in under 200ms.

No JavaScript required: Your site works without JavaScript. Actual HTML pages, not a SPA that needs to load before showing content.

Free hosting: Netlify free tier works perfectly. Push to GitHub, Netlify builds and deploys automatically. Zero hosting cost.

The trade-off: no admin panel. You edit markdown files in a text editor and use git. If you're comfortable with that, Zola is simple.

Installing Zola

Windows:

choco install zola

If you don't have Chocolatey, install it first or download Zola directly from their GitHub releases.

macOS:

brew install zola

Linux:

snap install --edge zola

Verify it works:

zola --version
# Should show: zola 0.18.0 or newer

Takes 30 seconds total.

Understanding the structure

Every Zola site follows the same structure. Here's mine:

my-blog/
├── config.toml          # Site settings
├── content/             # Your writing (markdown)
│   └── blog/
│       └── my-post.md
├── templates/           # HTML layouts
├── sass/                # Styles
└── static/              # Images, files

content/ is where you write. Everything else sets up how it looks.

You don't need to understand templates or sass to start. Just write markdown in content/, Zola handles the rest.

Creating your first site

zola init my-blog
cd my-blog

Zola asks a few questions:

  • What is the URL? (you can change later)
  • Enable syntax highlighting? (yes if you post code)
  • Enable search? (no for now, add later)

Creates the folder structure. That's it.

Writing your first post

Create a file: content/blog/my-first-post.md

+++
title = "My First Post"
date = 2025-12-07
+++

This is my first blog post written in markdown.

## I can use headings

And **bold text** and *italic text*.

Lists work too:
- First item
- Second item

Code blocks:
```python
def hello():
    print("Hello world")

The `+++` section at the top is metadata. Title shows as the page heading. Date is used for sorting posts.

## Previewing locally

```bash
zola serve

Opens at http://127.0.0.1:1111

Change a file, save it - the page refreshes automatically. Write your entire post while seeing live updates.

When I write, I keep zola serve running in one terminal, my editor in another window. Every save updates the preview instantly.

Customizing the look

Zola uses templates. The default is functional but plain. You can:

Option 1: Use a theme from zola-themes.org

Download, put in themes/, edit config.toml to use it.

Option 2: Write your own templates

Takes longer but you control everything. I did this. My site has 200 lines of HTML total across all templates.

Option 3: Start with a theme, modify it

Good middle ground. Most themes are simple enough to understand and tweak.

For my blog, I wanted minimal black and white design. No sidebar, no widgets, just text. Wrote custom templates in about two hours.

The config file - what matters

Open config.toml. Most of it you can ignore at first. The important parts:

base_url = "https://yourdomain.com"
title = "Your Blog Name"

# Build settings
compile_sass = true
minify_html = true

# Enable tags
taxonomies = [
    {name = "tags", feed = true}
]

# RSS feed
generate_feeds = true

That's 90% of what you need. Everything else is optional.

Adding tags to posts

Tags help organize posts. In your markdown frontmatter:

+++
title = "Post About Python"
date = 2025-12-07

[taxonomies]
tags = ["python", "programming", "tutorial"]
+++

Zola automatically creates:

  • /tags/ - lists all tags
  • /tags/python/ - shows all posts with "python" tag

No code required. Just add tags to your posts.

Deploying to Netlify

This is where it gets good. Free hosting with automatic deploys.

1. Push your site to GitHub

git init
git add .
git commit -m "Initial commit"
git push origin main

2. Connect Netlify

  • Go to netlify.com
  • Click "Add new site"
  • Choose "Import from Git"
  • Select your GitHub repo
  • Build command: zola build
  • Publish directory: public
  • Click deploy

3. Netlify builds your site

Every time you push to GitHub, Netlify:

  • Pulls latest code
  • Runs zola build
  • Publishes the result

Takes 30 seconds from push to live.

4. Add your domain (optional)

Netlify gives you a subdomain: yoursite.netlify.app

To use your own domain:

  • Buy a domain (I use Namecheap, about $10/year)
  • In Netlify: Domain settings → Add custom domain
  • Update DNS records (they give you instructions)
  • HTTPS works automatically (Let's Encrypt)

I did this for quoc.app. Whole process took 10 minutes.

My actual workflow

Writing a new post:

# Create file
touch content/blog/new-post-title.md

# Add frontmatter
+++
title = "Post Title"
date = 2025-12-07
[taxonomies]
tags = ["tag1", "tag2"]
+++

# Write content in markdown

# Preview while writing
zola serve  # Running in background

# When done
git add content/blog/new-post-title.md
git commit -m "Add new post: Post Title"
git push

Push to GitHub. Netlify builds and deploys. Post is live in 30 seconds.

No logging into WordPress. No clicking through admin panels. Just text files and git.

Handling images

Save images to static/images/

Reference in markdown:

![Description of image](/images/photo.jpg)

When Zola builds, it copies everything in static/ to the output. Your image ends up at yoursite.com/images/photo.jpg

I keep images under 200KB. Run them through TinyPNG first. Smaller images = faster page loads.

What I wish I knew earlier

Drafts: Put drafts in a separate folder like content/blog/drafts/. Add to config:

ignored_content = ["*/drafts/*"]

Zola won't build anything in drafts. Move files out when ready to publish.

Date formatting: You can format dates in templates:

{{ page.date | date(format="%Y-%m-%d") }}

But I just use the default. Dates work fine as-is.

Pagination: If you'll have many posts, add to content/blog/_index.md:

+++
paginate_by = 10
sort_by = "date"
+++

Zola automatically creates /blog/page/2/, /blog/page/3/, etc.

RSS: People still use RSS. Zola generates it automatically at /rss.xml if you enable it in config. I get a few subscribers who prefer reading via RSS reader.

Syntax highlighting: Works out of the box. Just specify language:

```python
def hello():
    print("world")
```

Choose a theme in config.toml:

[markdown]
highlight_theme = "base16-ocean-dark"

Preview themes at zola-themes.org

When Zola doesn't make sense

Zola is not for everyone.

Don't use Zola if you:

  • Need comments (no built-in support, would need external service)
  • Want a visual editor (it's markdown files only)
  • Need complex user accounts or authentication
  • Don't use git or don't want to learn
  • Need frequent non-technical contributors

Use WordPress or Ghost instead if:

  • You need a full CMS with admin panel
  • Non-technical people need to edit content
  • You want plugins for everything
  • Comments and user accounts are essential

I tried WordPress first. Spent two days setting up, configuring plugins, tweaking themes. Then I still had to update it weekly.

With Zola, I spent two hours total on setup. Haven't touched the config since. Just write and push.

Costs breakdown

My setup:

  • Domain: $12/year (quoc.app)
  • Hosting: $0 (Netlify free tier)
  • SSL certificate: $0 (Let's Encrypt via Netlify)
  • Total: $12/year

Compared to WordPress:

  • Shared hosting: $60-120/year
  • Domain: $12/year
  • Premium theme: $60 one-time
  • Plugins: varies
  • Total: $132+/year

I write 2-3 posts per month. Netlify's free tier handles thousands of visitors easily.

Common mistakes I made

Using relative paths for images:

Bad:  ![alt](images/photo.jpg)
Good: ![alt](/images/photo.jpg)

The slash at the start matters. Without it, images break on different pages.

Forgetting to add frontmatter:

Every markdown file needs the +++ section. Without it, Zola ignores the file.

Not testing locally first:

Always run zola serve and check your post before pushing. Catches markdown formatting issues and broken links.

Overcomplicating templates:

My first attempt had 15 template files. Realized I only needed 4. Start simple, add complexity if you actually need it.

Setting up from my blog

My blog is open source: github.com/quocnguyen/quoc-app

You can:

  1. Clone it
  2. Change config.toml (update base_url and title)
  3. Delete my posts in content/blog/
  4. Write your own posts
  5. Deploy

Takes the guesswork out of template design. Use mine as-is or modify it.

Tools I use with Zola

Writing: Obsidian for markdown editing. VS Code works too.

Images: TinyPNG for compression before uploading.

Analytics: Netlify Analytics (paid) or Plausible (privacy-focused). I don't use Google Analytics.

Version control: GitHub for code and content.

That's it. No WordPress plugins, no complicated stack.

Speed comparison

I tested page load times:

This Zola blog:

  • Time to first byte: 180ms
  • Full page load: 420ms
  • No JavaScript needed

Average WordPress blog:

  • Time to first byte: 800ms-2s
  • Full page load: 3-5s
  • Requires JavaScript for most features

Static HTML is just faster. No database queries, no PHP processing. Server sends HTML, browser displays it.

SEO works fine

People worry that static sites have SEO issues. Not true.

Zola generates:

  • Clean URLs: /blog/post-title/
  • Proper meta tags (if you add them to templates)
  • Sitemap at /sitemap.xml
  • RSS feed at /rss.xml

Google indexes my posts fine. Some rank on first page for their keywords.

The content matters more than the platform.

Bottom line

I wanted a blog without the overhead. No server to maintain, no security updates, no monthly hosting bills.

Zola gave me that. One command builds the entire site. Free hosting on Netlify. Push to publish in 30 seconds.

It's not as simple as clicking "New Post" in WordPress. You write markdown files and use git. But that trade-off means no maintenance, no costs, full control.

If you're comfortable with text files and the command line, Zola makes blogging simple. Install it, write markdown, push to deploy. That's the whole workflow.

Start here:

  1. Install Zola: choco install zola (Windows) or brew install zola (Mac)
  2. Create site: zola init my-blog
  3. Write first post in content/blog/first-post.md
  4. Preview: zola serve
  5. Push to GitHub and connect Netlify

From zero to published blog in under an hour.