Compare commits

...

3 commits

Author SHA1 Message Date
0fc2737a00 Split WM to separate section in setup 2026-08-04 10:41:40 +02:00
a771755907 Fixed external link icon 2026-08-04 10:39:52 +02:00
7b0ab11425 Setup page added 2026-08-04 10:37:15 +02:00
6 changed files with 136 additions and 6 deletions

View file

@ -18,7 +18,7 @@ export async function generateMetadata(): Promise<Metadata> {
}
}
export default async function Post() {
export default async function AboutPage() {
const { meta, content, tableOfContents } = await getPostBySlug('about', 'content/pages')
return (

35
app/setup/page.tsx Normal file
View file

@ -0,0 +1,35 @@
import { metadata } from '@/app/metadata'
import { TableOfContents } from '@/components/post/TableOfContents'
import { getPostBySlug } from '@/lib/posts'
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
const { meta } = await getPostBySlug('setup', 'content/pages')
return {
title: `${meta.title} | ${metadata.title!.toString()}`,
description: meta.description,
openGraph: {
type: 'website',
title: `${meta.title} | ${metadata.title!.toString()}`,
description: meta.description,
url: process.env.SITE_URL + `/setup`,
siteName: metadata.title!.toString(),
},
}
}
export default async function SetupPage() {
const { meta, content, tableOfContents } = await getPostBySlug('setup', 'content/pages')
return (
<main className="flex w-full">
<article className="max-w-3xl 2xl:max-w-4xl mx-auto px-4 py-8 mb-8 lg:py-16 min-w-0">
<h1 className="text-4xl font-bold mb-4">{meta.title}</h1>
<p className="text-fg text-lg mb-4">{meta.description}</p>
<div className="prose">{content}</div>
</article>
<TableOfContents items={tableOfContents} />
</main>
)
}

View file

@ -1,4 +1,4 @@
import { ChartColumnStacked, GitBranch, Home, Info, Rss, Tags } from 'lucide-react'
import { ChartColumnStacked, GitBranch, Home, Info, Rss, Server, Tags } from 'lucide-react'
type NavItem = {
href: string
@ -18,6 +18,7 @@ export const navItems: NavItem[] = [
icon: <ChartColumnStacked className={navIconsClassName} />,
},
{ href: '/tags', label: 'Tags', icon: <Tags className={navIconsClassName} /> },
{ href: '/setup', label: 'Setup', icon: <Server className={navIconsClassName} /> },
{
href: '/feed.xml',
label: 'RSS Feed',

View file

@ -1,3 +1,4 @@
import { ExternalLinkIcon } from 'lucide-react'
import type { AnchorHTMLAttributes } from 'react'
type ExternalLinkProps = Omit<
@ -7,6 +8,11 @@ type ExternalLinkProps = Omit<
href: string
}
export function ExternalLink(props: ExternalLinkProps) {
return <a {...props} target="_blank" rel="noopener noreferrer" />
export function ExternalLink({ children, ...props }: ExternalLinkProps) {
return (
<a {...props} target="_blank" rel="noopener noreferrer">
{children}
<ExternalLinkIcon className="inline-block w-3 h-3 ml-1 mb-2" />
</a>
)
}

90
content/pages/setup.md Normal file
View file

@ -0,0 +1,90 @@
---
title: Setup
description: Learn more about my setup, what I use, self-host, and how I manage my development environment. Discover the tools and configurations that help me stay productive and efficient in my work as a software developer.
---
A running list of the software, tools, and infrastructure I use day to day — as a developer, a self-hoster, and someone who'd rather configure something once than fight it every day.
## Desktop
- **[Arch Linux (EndeavourOS)](https://endeavouros.com/)** — my daily driver. I like Arch for the control it gives me over the system, and EndeavourOS strips away the parts of a base Arch install I don't want to do by hand.
- **[macOS](https://www.apple.com/macos/)** — my secondary OS that runs on my work laptop. I mainly use it for work, but I like the polish and the ecosystem it offers. I don't use it as my primary OS because I prefer the control and flexibility of Linux.
### Window Manager
- **[Hyprland](https://hypr.land/)** — my window manager of choice. I like the flexibility and the modern features it offers, and I enjoy configuring it to my liking.
## Mobile
- **[Android](https://www.android.com/)** — my current mobile OS. But as Google is increasingly hostile to privacy, I plan to switch to [GrapheneOS](https://grapheneos.org/) on a Pixel device in the future.
- **[FUTO Keyboard](https://keyboard.futo.tech/)** — my keyboard of choice. I like the layout and the feel of the keys, and I enjoy customizing it to my liking.
- **[F-Droid](https://f-droid.org/)** — my app store of choice. I like the open-source apps it offers, and I enjoy discovering new apps that respect my privacy.
## Browser
- **[Firefox](https://www.mozilla.org/en-US/firefox/new/)** — my main browser. I like the privacy features it offers, and I enjoy customizing it to my liking.
### Extensions
- **[uBlock Origin](https://ublockorigin.com/)** — does the heavy lifting for ad and tracker blocking. Fast, lightweight, and I've never felt the need to look elsewhere.
- **[Decentraleyes](https://decentraleyes.org/)** — serves common CDN-hosted libraries locally instead of pinging Google/Cloudflare on every page load. Small privacy win, no downside.
- **[I still don't care about cookies](https://www.i-dont-care-about-cookies.eu/)** — auto-dismisses cookie banners.
- **[Privacy Badger](https://privacybadger.org/)** — catches trackers uBlock misses by learning their behavior rather than relying on a static list.
- **[ClearURLs](https://addons.mozilla.org/en-US/firefox/addon/clearurls/)** — strips tracking parameters from links before they even load. Cleaner URLs, less fingerprinting.
- **[Return YouTube Dislike](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislike/)** — brings back a signal YouTube decided I didn't need to see.
- **[Unhook](https://addons.mozilla.org/en-US/firefox/addon/youtube-recommended-videos/)** — strips out recommendations, endless feeds, and other rabbit-hole bait so I can use the site without losing an hour to it.
## Email & RSS
- **[Thunderbird](https://www.thunderbird.net/)** — handles both my email and RSS feeds. One inbox-shaped app for everything I need to keep an eye on, instead of a browser tab I forget to check.
## Privacy & Utility Tools
- **[Mullvad VPN](https://mullvad.net/)** — for general browsing privacy.
- **[SearXNG](https://searxng.org/)** — self-hosted metasearch, so I'm not feeding every query into a single company's index.
- **Degoogling** — an ongoing, low-key project of replacing Google services with self-hosted or privacy-respecting alternatives where it makes sense.
## Editor & Terminal
- **[VS Code Insiders](https://code.visualstudio.com/insiders/)** — my main editor. I like the speed and the early access to new features, and I don't mind the occasional bug.
- **[Vim](https://www.vim.org/)** — my secondary editor. I use it for quick edits, and I like the modal editing paradigm.
- **[kitty](https://sw.kovidgoyal.net/kitty/)** — my terminal emulator of choice. I like the speed, the GPU rendering, and the features it offers.
- **[fish shell](https://fishshell.com/)** — my shell of choice. I like the syntax highlighting, the autosuggestions, and the ease of use.
- **[starship](https://starship.rs/)** — my prompt of choice. I like the speed, the customization, and the features it offers.
## Development Stack
- **[Next.js](https://nextjs.org/)** — my go-to framework for full-stack web projects. Good defaults, and I rarely fight it.
- **[TypeScript](https://www.typescriptlang.org/)** — non-negotiable at this point. Catching mistakes at compile time beats catching them in production.
- **[Prisma](https://www.prisma.io/)** — my usual ORM when a project needs one. Type-safe queries and migrations that don't make me nervous.
- **[Supabase](https://supabase.com/)** (managed) — Postgres, auth, and storage without having to hand-roll all three, for client and hosted projects.
- **[bun](https://bun.sh/)** — my package manager and runtime of choice. Faster installs, faster scripts.
## Self-Hosted
I run my own infrastructure on a Hetzner VPS, mostly because I like understanding every layer of what I ship rather than trusting a black box. I'd like to move to a dedicated server eventually, but I refuse to pay the current hardware prices — inflated by an AI bubble that has nothing to do with what I actually need a machine for.
### Platform
- **[Coolify](https://coolify.io/)** — the deployment layer for most of my self-hosted apps. Handles builds, deploys, and rollbacks without me needing a full DevOps setup.
- **[Traefik](https://traefik.io/)** — reverse proxy in front of everything, handling routing and TLS.
- **[Authentik](https://goauthentik.io/)** — single sign-on across my self-hosted services (Forgejo, Paperless-ngx, Immich, SearXNG, and more). One login instead of a dozen.
- **[Forgejo](https://forgejo.org/)** — my self-hosted Git host, with CI/CD wired into Coolify for automatic deploys.
- **[Headscale](https://headscale.net/)** — a self-hosted mesh VPN (open-source Tailscale control server) that ties my devices and services together securely.
- **Hetzner Storage Box** — persistent storage for backups and the services that need it.
### Services
- **[Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx)** — document management, so paperwork doesn't pile up in random folders.
- **[Immich](https://github.com/immich-app/immich)** — self-hosted photo backup, an alternative to Google Photos.
- **[ntfy](https://github.com/binwiederhier/ntfy)** — push notifications from scripts, servers, and self-hosted services.
- **[Stirling PDF](https://github.com/Stirling-Tools/Stirling-PDF)** — a self-hosted toolkit for PDF manipulation.
- **[Mealie](https://github.com/mealie-recipes/mealie)** — a self-hosted recipe manager, because I like cooking and want to keep my recipes organized.
- **[Uptime Kuma](https://github.com/louislam/uptime-kuma)** — monitoring for my self-hosted services, so I know when something goes down.
- **[Vaultwarden](https://github.com/dani-garcia/vaultwarden)** — self-hosted password manager, so I control my credentials.
- **[Supabase](https://github.com/supabase/supabase)** (self-hosted) — my own Postgres, auth, and storage instance for personal projects, without relying on a third-party service.
- **[Continuwuity](https://forgejo.ellis.link/continuwuation/continuwuity)** (a Matrix server implementation) — lets me chat with friends and communities without relying on a corporate service.
---
This list changes fairly often — I'll keep it updated as tools come and go.

View file

@ -26,7 +26,6 @@ import { rehypeDefinition } from '@/lib/rehype-definition'
import { slugify } from '@/utils/slug'
import { PostMeta } from '@/types/Post.type'
import Link from 'next/link'
import { ExternalLinkIcon } from 'lucide-react'
const postsDirectory = path.join(process.cwd(), 'content/posts')
@ -102,7 +101,6 @@ export async function getPostBySlug(slug: string, postDirectory: string = postsD
href?.startsWith('http') ? (
<ExternalLink href={href}>
{children}
<ExternalLinkIcon className="inline-block w-3 h-3 ml-1" />
</ExternalLink>
) : (
<Link href={href}>{children}</Link>