Building Your Personal Site with Zola & Cloudflare Pages (It’s Really Simple)

When I first decided to build a personal website and blog to showcase my skills, I felt overwhelmed by the huge number of options.
Frameworks, hosting, deployment pipelines — it seemed like a complex road just to put some information about myself online.
I spent days researching, getting lost in configurations, and feeling like I needed to become a DevOps expert overnight.
That initial struggle taught me a valuable lesson: building an effective online presence doesn’t have to be complicated.
By focusing on the right tools and understanding a few core principles, you can create a fast, robust, and easy-to-manage static site that truly represents you.
Why Static Sites? Speed, Security, and Simplicity
In a world of complex web applications, why go back to basics with a static site?
- Really Fast Performance: Static sites serve pre-built HTML files directly, making them incredibly fast compared to dynamic sites that generate content on the fly. Great for user experience and SEO.
- Enhanced Security: With no databases or server-side processing for content generation, static sites have a much smaller attack surface.
- Simplified Hosting: Static sites can be hosted on incredibly affordable (often free for personal use) and high-performance platforms like Cloudflare Pages.
- Developer Friendly:Using a static site generator allows you to write content in Markdown and use templating for consistent design, without the complexity of a full backend.
The Power Duo: Zola and Cloudflare Pages
For my personal site, I chose a combination that offers simplicity and power:
- Zola:A fast, static site generator written in Rust. It’s a single binary, easy to install, and uses Tera templates, which are intuitive and flexible. Zola takes your content written in Markdown and your templates, and compiles them into a complete static website.
- Cloudflare Pages:A JAMstack platform for frontend developers. It connects directly to your Git repository, automatically builds your site whenever you push changes, and deploys it globally on Cloudflare’s edge network for incredible speed and reliability. And for personal projects, it’s free!
Building the Foundation: Structure and Content
The first step was setting up the project structure. Zola uses a convention-over-configuration approach, which simplifies things.
For My site, I needed a main landing page with sections about my skills and projects, and a separate section for my blog posts.
config.toml
: The main configuration file for the Zola project.content/
: This directory holds all your Markdown content.content/_index.md
: The content for the main landing page.content/blog/
: A directory for all blog posts. Each post is a.md
file inside here.templates/
: This directory holds your HTML templates using the Tera templating engine.templates/base.html
: The base template for the overall site structure (header, footer, etc.).templates/index.html
: The template for the main landing page (_index.md
).templates/section.html
: The template for listing content within a section (used for the blog list page).templates/page.html
: The template for individual content pages (used for individual blog posts).static/
: This directory is for static assets like CSS files, images, and JavaScript.static/style.css
: Your main stylesheet.static/script.js
: Your main JavaScript file (optional).
Crafting the Content: About, Skills, Projects, and Contact
Let’s see how I structured the key sections of my content/_index.md
to tell my story and showcase my expertise:
+++
title = "Arash Hadad - Portfolio"
template = "index.html"
transparent = true
+++
<section id="hero">
<div class="hero-content">
<h1>Arash Hadadsoleymani</h1>
<p class="subtitle">Python | Machine Learning | Data Science | Full-Stack Development</p>
<p>Transforming data into powerful solutions and building robust web applications.</p>
</div>
</section>
<section id="about">
<h2>About Me</h2>
<div class="about-content">
<div class="about-text">
<p>With 3 years immersed in the dynamic world of Python, Machine Learning, and Data Science, I'm a 27-year-old developer driven by a passion for extracting insights from data and building intelligent systems. My journey has taken me through diverse projects, ranging from fundamental data preprocessing and visualization to sophisticated web scraping and automation techniques.</p>
<p>I have hands-on experience developing and managing complex systems, including a 24/7 crypto trading bot. My skill set is further complemented by a strong understanding of Linux server management and cybersecurity principles, allowing me to build secure and scalable full-stack solutions.</p>
</div>
</div>
</section>
<section id="skills">
<h2>Skills & Expertise</h2>
<div class="skills-grid">
<div class="skill-item">
<h3>Core Languages</h3>
<p>Python, HTML, CSS</p>
</div>
<div class="skill-item">
<h3>Backend</h3>
<p>Python, Linux Server Management</p>
</div>
<div class="skill-item">
<h3>Frontend</h3>
<p>HTML, CSS, Web App Development</p>
</div>
<div class="skill-item">
<h3>Data Science & ML</h3>
<p>scikit-learn, pandas, numpy</p>
</div>
<div class="skill-item">
<h3>Web Scraping & Automation</h3>
<p>Selenium, Scrapy, BeautifulSoup, requests, xpath</p>
</div>
<div class="skill-item">
<h3>Trading Systems</h3>
<p>Freqtrade (Crypto Trading Bot), Telegram Bot</p>
</div>
<div class="skill-item">
<h3>Cybersecurity & Systems</h3>
<p>Linux Server Management, Static IP VPNs</p>
}
</div>
</section>
<section id="projects">
<h2>Featured Projects</h2>
<div class="projects-list">
<div class="project-item">
<h3>Automated Crypto Trading Bot</h3>
<p>Developed and deployed a sophisticated 24/7 trading bot using Freqtrade, designed to execute strategies autonomously in the cryptocurrency markets.</p>
</div>
<div class="project-item">
<h3>Comprehensive Data Solutions</h3>
<p>Executed end-to-end data science projects, from initial preprocessing and cleaning to advanced visualization and analysis for actionable insights.</p>
</div>
<div class="project-item">
<h3>Web Scraping & Data Extraction</h3>
<p>Built robust web scraping tools using libraries like Scrapy and BeautifulSoup to efficiently collect data from various online sources.</p>
</div>
<div class="project-item">
<h3>Full-Stack Web Applications</h3>
<p>Designed and developed complete web applications, handling both backend logic and frontend presentation.</p>
</div>
<div class="project-item">
<h3>Linux Server & Security Management</h3>
<p>Configured and managed Linux servers, implementing security measures and creating network solutions like static IP VPNs.</p>
</div>
<div class="project-item">
<h3>Telegram Bot Development</h3>
<p>Created interactive Telegram bots for various applications, including integrating with trading platforms and providing real-time information.</p>
</div>
</div>
<p class="section-description">These projects highlight my ability to apply technical skills to solve real-world problems and build functional systems.</p>
</section>
<section id="contact">
<h2>Get in Touch</h2>
<p>I'm always eager to connect with fellow professionals, discuss potential collaborations, or explore new opportunities. Feel free to reach out through my social profiles:</p>
<div class="social-links">
<a href="YOUR_LINKEDIN_URL" target="_blank" class="social-button linkedin">LinkedIn</a>
<a href="YOUR_MEDIUM_URL" target="_blank" class="social-button medium">Medium</a>
</div>
<p class="generous-message">Looking forward to connecting and discussing how my skills can contribute to your next project!</p>
</section>
Bringing it to Life: Templates and Styling
Zola uses Tera templates to define the structure of your pages. base.html
provides the common elements, while index.html
extends it for the main page layout.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% if page.title %}{{ config.title }} - {{ page.title }}{% else %}{{ config.title }}{% endif %}</title>
<link rel="stylesheet" href="{{ get_url(path="style.css") }}">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<header>
<nav>
<ul>
{% for item in config.extra.menu %}
<li><a href="{{ get_url(path=item.url) }}">{{ item.name }}</a></li>
{% endfor %}
</ul>
</nav>
</header>
<main>
{% block content %}
{% endblock content %}
</main>
<footer>
<p>© {{ now() | date(format="%Y") }} Arash Hadad. All rights reserved.</p>
</footer>
</body>
</html>
```html
{% extends "base.html" %}
{% block content %}
{{ section.content | safe }}
{% endblock content %}
To get that distinct black and yellow vibe, CSS is essential. Here’s a snippet of the style.css
focusing on the color scheme and basic layout:
/* General Styles */
body {
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
background-color: #121212; /* Dark background */
color: #e0e0e0; /* Light grey text */
line-height: 1.7;
scroll-behavior: smooth;
}
/* Typography */
h1, h2, h3, h4, h5, h6 {
color: #ffcc00; /* Bitcoin yellow */
font-weight: 700;
}
h2::after {
content: '';
display: block;
width: 60px;
height: 4px;
background-color: #ffcc00;
margin: 10px auto 0;
border-radius: 2px;
}
/* Header and Navigation */
header {
background-color: #0d0d0d; /* Very dark header */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.6);
}
nav a {
color: #ffcc00;
border-bottom: 2px solid transparent;
}
nav a:hover {
color: #fff;
border-bottom-color: #ffcc00;
}
/* Sections */
section:nth-of-type(odd) {
background-color: #1a1a1a;
}
section:nth-of-type(even) {
background-color: #121212;
}
/* Skill and Project Cards */
.skill-item, .project-item {
background-color: #2a2a2a; /* Darker background for cards */
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.5);
border: 1px solid #333;
}
.skill-item:hover, .project-item:hover {
transform: translateY(-8px);
background-color: #3a3a3a;
}
.skill-item h3, .project-item h3 {
color: #ffcc00;
}
/* Social Buttons */
.social-button {
border: 2px solid #ffcc00;
color: #ffcc00;
}
.social-button:hover {
background-color: #ffcc00;
color: #121212;
}
/* Footer */
footer {
background-color: #0d0d0d;
color: #bdbdbd;
}
Deployment with Cloudflare Pages
The moment your Zola site is ready, deploying with Cloudflare Pages is incredibly straightforward:
- Push your code to a Git repository (GitHub, GitLab, Bitbucket).
- Connect your repository to Cloudflare Pages.
- Cloudflare automatically detects Zola and sets the build command (
zola build
) and publish directory (public
). - Deploy! Any future pushes to your connected branch trigger an automatic build and deployment.
The Result: A Fast, Styled, and Informative Site
By combining Zola’s build speed and templating power with Cloudflare Pages’ free and performant hosting, you have a static site that’s easy to maintain, fast for visitors, and effectively showcases your skills and projects. The black and yellow theme adds a distinct, memorable touch.
This journey to a deployed site show us that with the right tools and a clear approach, building your online presence is not just achievable, but surprisingly simple and rewarding.
Ready to Build Your Own?
The full code for the templates and CSS, along with instructions on setting up Zola and Cloudflare Pages, can guide you through creating your own personal site.
Connect With Me
Building in public and sharing knowledge is key!
You can fuel my next data science deep dive by buying me a coffee ☕!