Kako i zašto sam izgradio ovu web stranicu
Od WordPressa do Astra, od dinamičkog do statičkog, od ovisnosti do potpune kontrole. Priča o potpunoj obnovi miran.at.
Pet godina miran.at je radio na WordPressu. Funkcioniralo je — ali nikad se nije osjećalo kako treba.
Svako ažuriranje donosilo je nove ovisnosti. Svaki plugin dodavao je JavaScript koji nitko nije tražio. Page builder borio se s temom, tema se borila s cache pluginom, a ja sam se borio sa svima.
U jednom trenutku zapitao sam se: zašto pokrećem cijeli CMS backend server za web stranicu koja se jedva mijenja? Zašto posjetitelji preuzimaju 500 KB JavaScripta samo da bi pročitali blog post?
Odgovor je bio: više ne.
Polazište
miran.at je bio klasična WordPress stranica s vlastoručno izrađenom temom. Izgledala je dobro, ali ispod haube bila je kompromis.
Najveća bolna točka bio je sam WordPress. Ne zato što je WordPress loš — izvrstan je CMS za klijentske projekte. Ali za moju vlastitu stranicu bio je previše kompliciran. Nisam trebao admin panel, WYSIWYG editor ni upravljanje medijskom bibliotekom. Trebao sam Markdown datoteke, Git repozitorij i build proces koji proizvodi statički HTML.
Povrh toga:
- Performanse: WordPress stranice nisu brze bez agresivnog cachinga. A caching često razbija admin panel.
- Sigurnost: Svaka WordPress instalacija je meta. Ažuriranja, hardening, monitoring — sve dodatni posao.
- Ovisnost: MySQL baza podataka, PHP-FPM proces, redoviti backupi. Za statičku web stranicu.
- Kreativna sloboda: WordPress nameče određeni mentalni model — postovi, stranice, custom post typeovi, taksonomije. Htio sam organizirati sadržaj na način koji ima smisla meni.
Tehnološke odluke
Astro — Temelj
Astro je bio pravi izbor od početka. Njegova temeljna filozofija — nula JavaScripta prema zadanim postavkama, statički HTML kao izlaz — savršeno odgovara mom slučaju.
Proučio sam druge static site generatore:
- Next.js je app framework prerušen u static site generator. Pretežak za content stranicu.
- Hugo je munjevito brz, ali njegov template jezik osjeća se kao korak unatrag.
- Eleventy je solidan, ali bez ugrađene island arhitekture morao bih sam riješiti interaktivnost.
- Astro nudi najbolji paket: type-safe Content Collections, Island Architecture, Vue/React/MDX podršku i izvrsno developersko iskustvo.
Presudni faktor bile su Content Collections. Zod shema definira točno koja polja frontmattera blog post mora imati. Nedostaje polje? Pogrešan tip? Build pada. To zvuči strogo, ali sprječava najčešće pogreške na content-driven stranicama.
Vue 3 — Interaktivni otoci
Ne treba svaka interakcija single-page aplikaciju. Astrova Island Architecture omogućuje mi korištenje Vue komponenti samo tamo gdje su zaista potrebne: animirani tekstovi, cookie consent dijalog, scroll animacije.
Zašto Vue umjesto Reacta ili Sveltea?
- Vue mi je prirodniji. Single-File Components s
<template>,<script>i<style>u jednoj datoteci odgovaraju načinu na koji organiziram svoje razmišljanje. - Composition API s
<script setup>je elegantan i type-safe. - Vueov reaktivni sustav radi u pozadini bez potrebe za ručnom optimizacijom ovisnosti.
Tailwind CSS 4
Dugo nisam bio ljubitelj Tailwinda. Utility klase u HTML-u osjećale su se pogrešno.
Onda sam shvatio: Tailwind te ne tjera da napustiš semantiku. Daje ti drugačiju razinu apstrakcije — naime nultu. Umjesto da definiraš klasu .hero-headline koja u datoteci components/hero.css skuplja proizvoljne stilove, izravno u HTML-u vidiš koji su stilovi primijenjeni.
Tailwind CSS 4 s CSS-first config pristupom (@theme u global.css) još je jedan korak naprijed. Nema više tailwind.config.js — samo prave CSS custom propertyje.
GSAP — Motion Design
Animacije na content stranici moraju imati svrhu. GSAP mi omogućuje preciznu kontrolu nad onim što se događa — i još važnije, kada se ništa ne događa.
Svaka GSAP animacija je dinamički uvezena. Ako posjetitelj ima uključen prefers-reduced-motion, nijedna animacija se ne pokreće. Točka.
ScrollTrigger pokreće reveal efekte koji prate tijek čitanja bez prekidanja.
Three.js — 3D Igra
Portfolio ne mora biti dosadan. Interaktivni 3D dio (/spiel/ na njemačkom, /en/play/ na engleskom) mali je eksperiment — igriv način predstavljanja mog rada.
Three.js se učitava samo na toj jednoj stranici. Ostatak stranice ostaje lagan.
Self-Hosting — Docker + nginx
Stranica radi na mom vlastitom serveru. Docker container s nginxom poslužuje statičke datoteke. Cloudflared tunel brine o SSL-u i DDoS zaštiti bez zaobilaženja Cloudflare proxyja.
Alternativni deployment put (rsync na Webmin) spreman je ako ikad poželim promijeniti providera.
Bez CDN-a, bez vanjskog hostiranja resursa. Sve je samostalno hostirano.
i18n — Tri jezika
Njemački, engleski, hrvatski. Tri jezika, jedna baza koda.
Implementacija je bila zahtjevnija nego što sam očekivao. Astrov i18n sustav podržava prefixDefaultLocale: false za njemački kao korijenski jezik. Ali content rute morao sam sam izgraditi — buildDefaultBlogStaticPaths() za njemački, buildLocalizedBlogStaticPaths() za engleski i hrvatski.
Manifest ruta u route-manifest.ts definira za svaku rutu koji su jezici dostupni i koju URL strukturu imaju:
- Njemački:
/blog/wie-und-warum-ich-diese-website-gebaut-habe/ - Engleski:
/en/blog/how-and-why-i-built-this-website/ - Hrvatski:
/hr/blog/kako-i-zasto-sam-izgradio-ovu-web-stranicu/
Dizajn
Švicarska editorialna estetika
Stranica ne izgleda kao template. To je bio najvažniji cilj.
Inspiriran švicarskim dizajnom 1950-ih i 1960-ih: jasne mreže, puno bijelog prostora, tipografija kao dizajnerski alat, bez ukrašavanja radi ukrašavanja.
Mreža od 8 stupaca
Većina web stranica koristi 12 stupaca. Ja koristim 8.
Razlika je suptilna, ali važna. 8 stupaca tjera na jasnije odluke. 2+6, 3+5, 4+4, 8. Manje kombinacija — i to je dobra stvar.
Tri boje
#08163C, #7FB5FF, #FFFFFF. Tri boje. Nijansi, gradijenata, ukrasa.
U tamnom načinu rada, prednji i stražnji plan zamjenjuju uloge. Plava ostaje kao akcentna boja.
Syne — Jedna debljina
Syne na težini 400. Bez bolda, bez semibolda, bez lighta.
Kad sve ima istu težinu, hijerarhija mora dolaziti iz veličine i razmaka. Zahtjevnije je — ali rezultat je čišći.
Ciljevi
1. Performanse. Stranica se učitava za manje od sekunde. Nijedan JavaScript bundle ne blokira renderiranje. Lighthouse nije savršen — ali konstantno iznad 95.
2. Održavanje. git pull, npm run build, Docker restart. Gotovo. Bez WordPress ažuriranja, bez konflikta pluginova, bez skripti za migraciju baze podataka.
3. Potpuna kontrola. Svaki piksel na ovoj stranici je samostalno odlučen. Nijedna tema ne diktira kako element treba izgledati. Nijedan page builder ne ograničava na unaprijed definirane blokove.
4. Višejezičnost bez kompromisa. Tri jezika, jedna baza koda. Dodavanje prijevoda znači stvaranje nove Markdown datoteke s odgovarajućim translationKey.
5. Dugovječnost. Astro proizvodi statički HTML. Statički HTML radit će i za 20 godina. Nema potrebe za nadogradnjom frameworka, nema kraja životnog vijeka runtimea, nema breaking changeova React verzija.
Što sam naučio
Redizajn nikad nije samo redizajn. To je prilika da preispitaš svoje pretpostavke.
Zašto mi treba CMS? Trebam li stvarno admin panel? Je li dinamičko uvijek bolje od statičkog? Koliko je JavaScripta zaista potrebno?
Odgovori na ova pitanja oblikovali su ovu web stranicu. I učinili su me boljim developerom.
Izgrađeno s Astro 5, Vue 3, Tailwind CSS 4, GSAP i Three.js. Samostalno hostirano na vlastitoj infrastrukturi. Na tri jezika.
Ovako moja web stranica izgleda sada. Ovako će izgledati godinama koje dolaze.