Rebuilding tristanisfeld.com
I rebuilt `tristanisfeld.com` because I wanted the site to feel more like a real working home for my projects, notes, and technical writing. The old version existed, but it did not feel like the system I wanted to keep using. For a personal developer site, that matters. If the publishing flow feels awkward, the blog goes stale. If adding projects feels annoying, the portfolio stops representing the real work. If the local setup only works on one machine, deployment becomes stressful. So the rebuild was not only a visual refresh. It was also an infrastructure cleanup.
The Mental Model
The site is a custom static site. The basic publishing path is: ```plain text Notion or local Markdown -> content/blog -> Python build -> output/
Production should serve the generated \`output/\` directory.
The repository contains the source code, templates, source assets, and build tools. The built site is generated from that.
That separation is important.
Source files belong in Git. Generated output should be reproducible.
## Why Static
A personal site does not always need a full web application backend.
For this site, static output has several advantages:
- simple hosting
- fast page loads
- fewer server moving parts
- easier deployment
- no database required for public page rendering
- content can be built ahead of time
That does not mean the workflow is primitive.
The site can still have templates, Sass, TypeScript, optimized images, icons, pagination, categories, and synced blog content.
The difference is that all of that work happens at build time.
## Content Sources
I wanted the site to support two content paths:
- local Markdown
- Notion-synced blog content
Local Markdown is useful because it is simple, testable, and Git-friendly.
Notion is useful because it is a comfortable writing interface.
The build system should not care too much where the content came from. By the time the site builds, blog posts should exist as files under \`content/blog\`.
That makes the static generator easier to reason about.
## Local Development
A good local workflow matters because this site should be easy to run on another machine.
The development script handles the repetitive setup:
- check required tools
- create a Python virtual environment when needed
- install Python dependencies
- install Node dependencies
- optionally sync Notion content
- prepare generated assets
- build the static site
- start the local dev server and browser reload workflow
That is the kind of boring automation that pays off.
The command should be obvious:
```bash
./dev-start.sh
If a project needs a long list of manual setup steps, it becomes fragile quickly.
Notion Sync Without Hard Dependency
One important design choice is that Notion sync should be optional by default in development. If the `.env` file has the required Notion variables, the script can sync content. If it does not, the site can still build from existing local Markdown. That matters because a fresh checkout should not fail just because a private token is missing. The token belongs in `.env`, not in the codebase. The generated Markdown content can still be present for builds, but the secret that talks to Notion should stay local to the machine or server.
Assets and Images
I also wanted the image workflow to be clear. Source images belong in the repository when they are part of the site itself:
- homepage images
- portfolio images
- project icons
- source visual assets Generated images and optimized output can be rebuilt. That distinction matters because committing build output makes the repository noisy, but failing to commit source images breaks the site on another machine. The source assets should be portable. The build system can take care of preparing them for `output/`.
Common Mistakes
Mistake 1: Making the site depend on one machine
If the site only builds on the original development machine, the setup is not finished. A personal site should be easy to clone, configure, build, and deploy from a second machine.
Mistake 2: Committing secrets
API tokens, database IDs, deployment credentials, and private config do not belong in the repository. Use `.env` locally and configure production secrets on the server.
Mistake 3: Confusing source assets and build output
Source images should be committed when the site depends on them. Generated optimized images should be rebuilt. Those are different kinds of files.
Where This Goes Next
The rebuild gives the site a better foundation for writing and projects. The next steps are mostly content and publishing workflow:
- seed the blog with useful launch articles
- push polished drafts into Notion
- attach or generate article images
- keep the local build reliable
- deploy from the generated static output That is the practical goal. The site should not just look finished. It should be easy enough to keep using.
Key Takeaways
- The site is built as a custom static site.
- Content can come from Notion or local Markdown.
- Python build tools generate the final `output/` directory.
- Secrets belong in `.env`, not in Git.
Source assets should be committed; generated output should be rebuildable.
Related Articles
Building a Static Blog With Python and Markdown
- Building Small Software Projects in Public
- Python Virtual Environments Explained