Contents

You have ideas. You want a place to publish them. With math. With 3D scenes. With interactive plots.

You do not want to pay 20 €/month to Squarespace for the privilege. πŸ™…

Good news. The full stack behind this site costs 0 € if you publish under myblog.pages.dev, or ~12 €/year if you want a custom domain like yourname.com. Hosting is free. SSL is free. Build is free. Domain is the only optional bill.

Here is the entire pipeline, start to finish. β˜•

hacker typing


The Idea in One Sentence

You write Markdown. AI fills in the hard parts. Git pushes it. Cloudflare publishes it.

That is the whole loop. Everything below is just plumbing.


The Stack

Icon Tool Layer Cost
Jekyll Jekyll 4 + Minima Static site engine Free
MathJax MathJax Math rendering Free
Plotly Plotly.js Interactive plots Free
Three.js Three.js 3D / WebGL Free
GitHub GitHub Source control Free
Cloudflare Pages Cloudflare Pages Hosting + CDN + SSL Free
Claude Code Claude Code AI co-author Free tier exists
πŸ’Έ Cloudflare Registrar / Namecheap Domain name ~10–15 €/year

One bill per year. That is it.


The Flow Diagram

   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  πŸ’‘ Idea     β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  ✍️  Write Markdown   β”‚ ◀───▢ β”‚  πŸ€– AI Helper    β”‚
   β”‚   in _posts/         β”‚       β”‚  (Claude Code)   β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  πŸ‘€ Preview locally  β”‚
   β”‚  jekyll serve        β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  πŸ“¦ git push         β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  ☁️  Cloudflare       β”‚
   β”‚  auto-builds + CDN   β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  🌍 yourname.com     β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Push code. Site updates. No FTP. No server. No drama.


Step 1 β€” Install Ruby + Jekyll (Windows)

Jekyll is the engine. Markdown goes in, HTML comes out.

  1. Grab Ruby+Devkit from rubyinstaller.org/downloads. Pick the version with => next to it.
  2. End of installer runs ridk install. Choose options 1, 2, 3 in order.
  3. Open a fresh PowerShell:
gem install bundler jekyll
  1. Make your blog:
jekyll new myblog
cd myblog
bundle install
  1. Run it:
ridk enable
bundle exec jekyll serve --livereload
  1. Open http://localhost:4000. There it is. πŸŽ‰

--livereload auto-refreshes the browser when you save a file. Edit. Save. Watch it update.

Stuck? bigdecimal.so LoadError β†’ run ridk enable && gem pristine bigdecimal. Mac/Linux? Skip ridk, install Ruby via your package manager.

πŸ“– Deep dive: Official Jekyll Quickstart Β· Jekyll on Windows Β· Minima theme docs


Step 2 β€” Folder Layout

myblog/
β”œβ”€β”€ _posts/          ← your articles (one .md per post)
β”œβ”€β”€ _includes/       ← reusable HTML/MD chunks (3D scenes, demos)
β”œβ”€β”€ _layouts/        ← page templates
β”œβ”€β”€ _config.yml      ← site settings (title, author, plugins)
β”œβ”€β”€ Gemfile          ← Ruby dependencies
└── assets/
    β”œβ”€β”€ css/style.css
    └── images/

Open _config.yml first. Set title, author, description, and url. Save. Done with setup.

Drafts: prefix filename with _ or -. Jekyll ignores them. πŸ™ˆ

πŸ“– Deep dive: Jekyll directory structure Β· Front matter reference Β· Drafts


Step 3 β€” Write Your First Post

The whole point. One Markdown file = one published article.

Create _posts/2026-05-01-my-first-post.md (filename must start with YYYY-MM-DD-):

---
layout: post
title: "Why Beams Bend"
date: 2026-05-01
categories: structural-analysis
tags: [beams, FEM]
plotly: true                              # optional: loads Plotly.js
image: /assets/images/beams-thumb.jpg     # optional: thumbnail + og:image
---

Inline math: $\sigma = E\varepsilon$. Display:

$$M = EI \frac{d^2 w}{dx^2}$$

## A Section

Your text here.

Save. Browser auto-reloads. Done. βœ…

MathJax tip: Prefer display math $$...$$ for anything you want to stand out. Inline $...$ for short symbols only. Mixing many inline math + Markdown links in one paragraph can break parsing.

πŸ“– Deep dive: Markdown Guide Β· Jekyll posts Β· MathJax syntax


Step 4 β€” Add Plots and 3D

Plotly chart

Set plotly: true in front matter, then drop:

<div id="chart" style="width:100%;height:400px;"></div>
<script>
Plotly.newPlot('chart', [{x:[1,2,3], y:[1,4,9], mode:'lines'}]);
</script>

Three.js 3D scene

Three.js needs an importmap so the browser knows where to fetch modules. Drop this once at the top of the post, before any module script:

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.183.2/build/three.module.min.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.183.2/examples/jsm/"
  }
}
</script>

Then your scene:

<div id="scene" style="width:100%;height:500px;"></div>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// scene, camera, renderer, animate loop
</script>

Use CSS variables for theme-aware colors. Never hardcode hex. 🎨

Pro tip: For long posts with 3D demos, move the scene HTML/JS into _includes/posts/<slug>/scene.html and pull it in with {% include posts/<slug>/scene.html %}. Keeps the post file readable.

πŸ“– Deep dive: Plotly.js getting started Β· Plotly chart types Β· Three.js manual Β· Three.js examples Β· OrbitControls


Step 5 β€” Let AI Do the Boring Parts

You write the idea. AI writes the code.

You explain in plain words: β€œdraw an Eshelby ellipsoid that the user can rotate.” AI writes the Three.js. You review. You ship.

Pick your AI

Tool Best at Link
Claude Code ⭐ My favorite. Best for coding. claude.com/claude-code
ChatGPT Quick prose, copy-paste flow chatgpt.com
Cursor AI inside IDE cursor.com
GitHub Copilot Inline autocomplete github.com/features/copilot
Gemini General drafting gemini.google.com

Pro tip: feed the AI a project brain

Drop a SITE_REFERENCE.md at your repo root. Document your conventions: front matter format, fragment system, theme rules. Any AI tool reads it and stops guessing. 🧠

Real prompt example

This is what you actually type. Not vague. Specific:

β€œIn _posts/2026-05-02-eshelby-ellipsoid.md, create a Three.js block with a 500 px tall canvas. Draw an ellipsoid with semi-axes a=2, b=1, c=0.5 centered at origin, blue wireframe. Add a red X-axis arrow, green Y, blue Z, each length 3, with text labels β€˜X’, β€˜Y’, β€˜Z’ at the tips. Use OrbitControls. Add a control panel below the canvas with three number inputs labeled β€˜a’, β€˜b’, β€˜c’ (range 0.1 to 3, step 0.1) that live-update the ellipsoid geometry. Add a β€˜Reset’ button that returns axes to (2, 1, 0.5). Use CSS variables --canvas-bg and --panel-bg so it works in dark and light themes. Match the importmap convention from SITE_REFERENCE.md.”

AI reads. AI writes. You preview. You tweak. You ship. βœ…

More examples:

  • β€œAdd a Plotly chart with two traces: Voigt upper bound and Reuss lower bound for Young’s modulus vs fiber volume fraction (0 to 1, 50 points). E_fiber=230 GPa, E_matrix=3.5 GPa. Log y-axis. Theme-aware colors.”
  • β€œMy Three.js scene flickers when toggling dark mode. The background does not update. Fix using a MutationObserver on the data-theme attribute.”
  • β€œConvert the math block on line 42 from inline $...$ to display $$...$$ and number it with \tag{1}.”

πŸ“– Deep dive: Claude Code docs Β· Claude Code quickstart Β· Cursor docs Β· GitHub Copilot quickstart Β· Effective AI prompting

robot helper


Step 6 β€” Push to GitHub

Make a free account at github.com if you do not have one. Install Git if you have not already.

Option A β€” with GitHub CLI (install gh):

gh auth login                              # one-time auth
git init
git add .
git commit -m "initial blog"
gh repo create myblog --public --source=. --push

Option B β€” without gh: Make an empty repo at github.com (no README, no .gitignore), then:

git init
git add .
git commit -m "initial blog"
git remote add origin https://github.com/YOU/myblog.git
git branch -M main
git push -u origin main

πŸ“– Deep dive: GitHub Hello World Β· Git basics tutorial Β· GitHub CLI manual


Step 7 β€” Deploy to Cloudflare Pages (Free)

  1. Sign up at dash.cloudflare.com.
  2. Workers & Pages β†’ Create β†’ Pages β†’ Connect to Git.
  3. Authorize and pick your myblog repo.
  4. Build settings:
Field Value
Framework preset Jekyll
Build command bundle exec jekyll build
Build output directory _site
Production branch main
Environment variable RUBY_VERSION = match what you installed (e.g. 3.2.2). Check with ruby -v.
  1. Hit Save and Deploy. Two minutes later, live at myblog.pages.dev. πŸš€

Every git push to main = automatic rebuild. Branches get preview URLs (great for drafting without breaking your live site). No manual deploys ever again.

Free tier limits: 500 builds/month, unlimited bandwidth and requests. Plenty for any blog. You will never hit it.

πŸ“– Deep dive: Cloudflare Pages β€” Get started Β· Deploy a Jekyll site Β· Build configuration

rocket launch


You can stop right here. Your site already works at myblog.pages.dev. Free forever. 0 €. βœ…

But yourname.com looks better on a CV, business card, or paper footer. Worth the 10 €/year? Up to you.

Registrar Price (.com) Notes
Cloudflare Registrar ⭐ ~10 €/year At-cost. Cheapest. No upsells.
Namecheap ~12 €/year Good UI, frequent promos
Porkbun ~11 €/year Quirky, cheap

Process:

  1. Buy domain (e.g. yourname.com).
  2. Cloudflare Pages project β†’ Custom domains β†’ add it.
  3. Domain on Cloudflare? DNS auto-configures. βœ…
  4. Domain elsewhere? Add the CNAME they show you.
  5. SSL certificate appears automatically.

Total bill if you go custom domain: ~12 €/year. πŸ’Έ
Total bill if you stay on pages.dev: 0 €. πŸ†“

πŸ“– Deep dive: Cloudflare custom domain setup Β· Cloudflare Registrar Β· DNS basics


Step 9 β€” Analytics (Optional, Free)

Make a free Google Analytics account. Get a measurement ID like G-XXXXXXXXXX.

Edit _config.yml:

google_analytics: G-XXXXXXXXXX

Push. Stats start flowing. Watch your readers in real time. πŸ“ˆ

πŸ“– Deep dive: GA4 setup guide Β· Plausible (privacy-friendly, paid) Β· Cloudflare Web Analytics (free, no cookies)


Daily Workflow

# 1. branch (optional but recommended β€” gives you a Cloudflare preview URL)
git checkout -b post/eshelby

# 2. ask AI to draft
#    "draft _posts/2026-05-02-eshelby-tensor.md with a 3D ellipsoid demo"

# 3. preview locally
ridk enable
bundle exec jekyll serve --livereload

# 4. tweak math, prose, animation. save β†’ browser refreshes.

# 5. ship
git add .
git commit -m "add Eshelby post"
git push -u origin post/eshelby

# 6. open PR on GitHub, merge to main β†’ Cloudflare auto-deploys to your live site

Cloudflare deploys before your coffee finishes. β˜•

Faster path for solo blogs: skip the branch, work on main, git push straight to live. Branches matter when you want a preview link before going live.


Learn Markdown

New to Markdown? Skip the cheat sheets. Read the official guide once and you are set:

πŸ“– Markdown Guide β€” Basic Syntax

Bonus links:

Quick Actions

Want to… Do this
New post Create _posts/YYYY-MM-DD-slug.md
Hide a draft Prefix filename with -
Get AI help Point your AI at SITE_REFERENCE.md
Preview locally bundle exec jekyll serve
Deploy git push

Final Cost Breakdown

Item Yearly cost
Hosting (Cloudflare Pages) 0 €
GitHub repo 0 €
SSL certificate 0 €
Build minutes 0 €
AI tools (free tiers) 0 €
Domain name (optional) ~10–15 €
TOTAL β€” myblog.pages.dev 0 €/year πŸ†“
TOTAL β€” yourname.com ~12 €/year βœ…

Less than one fancy coffee per month for a real engineering blog. With math. With 3D. With your name on the URL.


Now Go Write Something

Markdown in. Beautiful blog out. AI handles the boring bits. You own the content, the brand, the domain.

No excuses left. πŸš€