- JavaScript 97.9%
- Astro 1.6%
- CSS 0.2%
- TypeScript 0.2%
Het menu (position:fixed) stond binnen <header>, die een backdrop-filter heeft. Een backdrop-filter-voorouder maakt een fixed-kind relatief aan die voorouder i.p.v. het scherm, waardoor het menu inklapte zodra de header niet meer transparant was (na scrollen). Het menu staat nu buiten <header>, dus fixed werkt weer t.o.v. het scherm. Geverifieerd in een headless browser: menu dekt na scrollen het volledige scherm (top 74px, hoogte 726px) op zowel home als binnenpagina's. Geen gevolgen voor PageSpeed (alleen een DOM-verplaatsing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| public | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .nvmrc | ||
| astro.config.mjs | ||
| Caddyfile | ||
| docker-compose.yml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Casa Cossi
Moderne website voor Casa Cossi — een vrijstaand vakantiehuis met privézwembad in Ligurië, Italië. Gebouwd met Astro (statische site), een lokaal gehoste Decap CMS (zonder CDN) op een Forgejo/Gitea-backend, en kant-en-klaar om te deployen op Coolify via een Dockerfile.
Alle afbeeldingen en het logo van de oude site zijn behouden; beelden worden tijdens de build geoptimaliseerd naar WebP met onbeperkt cachebare (immutable) bestandsnamen. Cache-tijden en de Umami-statistieken zijn volledig instelbaar vanuit het CMS.
Inhoud
- Snel starten (lokaal)
- Projectstructuur
- Content beheren met het CMS
- Forgejo/Gitea: OAuth-applicatie aanmaken
- Deployen op Coolify
- Umami-statistieken instellen
- Cache & afbeeldingen
- Hoe een wijziging live komt
- Goed om te weten
Snel starten (lokaal)
Vereist: Node 20.19+ of 22 en npm.
npm install
npm run dev # site op http://localhost:4321
Lokaal het CMS gebruiken (zonder Forgejo-login)
Het CMS kan lokaal tegen je bestandssysteem werken via de meegeleverde proxy. Start in een tweede terminal:
npm run cms # decap-server proxy op poort 8081
Open daarna http://localhost:4321/admin/. Dankzij local_backend: true schrijft het CMS
rechtstreeks naar de bestanden in src/ — handig om content te bewerken zonder in te loggen.
Build
npm run build # statische site in dist/
npm run preview # bekijk de productie-build lokaal
Projectstructuur
.
├─ Dockerfile # multi-stage: Astro bouwen → serveren met Caddy
├─ Caddyfile # compressie, cache-headers (placeholders), 404-fallback
├─ docker-entrypoint.sh # vult cache- en OAuth-waarden in, start Caddy
├─ docker-compose.yml # lokaal de productie-image testen
├─ astro.config.mjs
├─ public/
│ ├─ admin/ # Decap CMS (lokaal gehost, geen CDN)
│ │ ├─ index.html
│ │ ├─ config.yml # collecties + Forgejo-backend (met placeholders)
│ │ └─ decap-cms.js # de CMS-bundel, meegeleverd in de repo
│ ├─ favicon.svg · og.jpg · apple-touch-icon.png · robots.txt
├─ src/
│ ├─ assets/images/ # alle bronafbeeldingen (+ uploads/ voor het CMS)
│ ├─ components/ # Hero, Header, Footer, Gallery, Card, SmartImage …
│ ├─ content/ # de content (markdown), bewerkt via het CMS
│ │ ├─ pages/ news/ activities/ places/
│ ├─ content.config.ts # schema's van de content-collecties
│ ├─ data/ # site.json (contact/umami/cache) · prices.json
│ ├─ layouts/ lib/ pages/ styles/
Content beheren met het CMS
Het CMS (/admin/) is ingedeeld in:
| Collectie | Wat je beheert |
|---|---|
| Instellingen → Algemeen | Contactgegevens, telefoonnummers, adres, Facebook, CIR/CIN, Umami-statistieken en cache-instellingen |
| Instellingen → Prijzen | De prijstabel, wat is inbegrepen en aanvullende info |
| Pagina's | Hero-tekst en inhoud van Home, Over ons, Het huis, De omgeving, Activiteiten, Prijzen en Contact (incl. de fotogalerij van Het huis) |
| Nieuws | Nieuwsberichten / verhalen (aanmaken, bewerken, als concept markeren) |
| Activiteiten | De activiteitenkaarten |
| Omgeving | Plaatsen en bezienswaardigheden (met "uitgelicht" voor op de homepagina) |
Elke wijziging wordt als commit naar de Forgejo-repo geschreven.
Forgejo/Gitea: OAuth-applicatie aanmaken
Decap gebruikt de Gitea-backend met PKCE (geen client secret nodig). Eenmalig instellen:
- Log in op
https://code.securityasaservice.org. - Ga naar Instellingen → Toepassingen → OAuth2-toepassing beheren (of op organisatie-/ admin-niveau).
- Maak een nieuwe toepassing:
- Naam:
Casa Cossi CMS - Redirect URI:
https://www.casacossi.com/admin/(gebruik exact het domein waarop de site draait, inclusief de afsluitende/) - Confidential Client: UITvinken ❗ (PKCE → publieke client, geen secret)
- Naam:
- Sla op en kopieer de Client ID. Die zet je in Coolify als
OAUTH_APP_ID(zie hieronder).
CORS inschakelen op Forgejo
De browser praat rechtstreeks met de Forgejo-API, dus CORS moet aan staan voor je domein.
In app.ini van de Forgejo-instantie:
[cors]
ENABLED = true
ALLOW_DOMAIN = https://www.casacossi.com
METHODS = GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
Forgejo 1.21.4+ / Gitea 1.20+ is vereist voor de Decap Gitea-backend.
Deployen op Coolify
De repo bevat een Dockerfile die zelf bouwt en serveert — Coolify hoeft niets extra's te doen.
-
New Resource → Application en kies je Forgejo-repo (
Fraseneggi/CasacossiWebsite). -
Build Pack: Dockerfile.
-
Port:
8080(de container serveert op poort 8080). -
Zet de environment-variabelen (zie
.env.example):Variabele Voorbeeld Toelichting SITE_URLhttps://www.casacossi.comPublieke URL (canonical, OG, sitemap, CMS). Zet ook als build-variabele zodat de juiste URL in de build komt. OAUTH_APP_ID(Client ID uit Forgejo) Verplicht voor het CMS-inloggen. FORGEJO_URLhttps://code.securityasaservice.orgJe Forgejo-instantie. GIT_REPOFraseneggi/CasacossiWebsiteDe repo ( eigenaar/naam).GIT_BRANCHmainBranch waar het CMS naartoe commit. PORT8080Optioneel. IMAGE_MAXAGE/HTML_MAXAGE(leeg) Optioneel; overschrijft de cache-instelling uit het CMS. -
Deploy. Stel daarna een webhook in zodat een push (ook CMS-commits) een rebuild start: kopieer de webhook-URL uit Coolify en voeg die toe onder Forgejo → repo → Instellingen → Webhooks.
Lokaal de productie-image testen
SITE_URL=http://localhost:8080 docker compose up --build
# → http://localhost:8080
Umami-statistieken instellen
Umami draait al via Coolify (eigen instantie, geen externe CDN). Koppelen doe je in het CMS:
- Open
/admin/→ Instellingen → Algemeen → Statistieken. - Vul in:
- Umami script-URL: bv.
https://umami.casacossi.com/script.js - Umami website-id: de Website ID uit je Umami-dashboard.
- Umami script-URL: bv.
- Opslaan. Pas wanneer beide velden zijn ingevuld, wordt het script geladen — anders laadt er niets.
Cache & afbeeldingen
- Afbeeldingen worden tijdens de build geoptimaliseerd naar WebP met gehashte bestandsnamen
(
/_astro/…). Die zijnimmutableen worden onbeperkt gecachet; bij een wijziging verandert de hash vanzelf, dus caches lopen nooit achter. - Instelbaar vanuit het CMS (Instellingen → Cache & afbeeldingen):
- Cache afbeeldingen / HTML (seconden) → bepalen de
Cache-Control-headers die Caddy meestuurt. - WebP-kwaliteit (30–100) → de compressie van de gegenereerde beelden.
- Cache-versie → ophogen om caches geforceerd te verversen.
- Cache afbeeldingen / HTML (seconden) → bepalen de
- De waarden worden bij het opstarten van de container in de Caddy-config gezet
(
docker-entrypoint.sh). Na een wijziging in het CMS → rebuild → nieuwe headers actief.
Hoe een wijziging live komt
Bewerken in /admin → commit naar Forgejo → webhook → Coolify rebuildt → live
De site is volledig statisch; er draait alleen Caddy om de bestanden te serveren (snel en veilig).
Goed om te weten
- Bron-afbeeldingen staan in
src/assets/images/(max. 2400px). Nieuwe uploads via het CMS komen insrc/assets/images/uploads/en worden net zo geoptimaliseerd. - In het CMS kan de voorbeeldweergave van een reeds geoptimaliseerde afbeelding soms leeg blijven; op de live site wordt het beeld altijd correct (als WebP) getoond.
- Het contactformulier opent de mailclient van de bezoeker met een ingevuld bericht (geen server/backend nodig, privacyvriendelijk).
- De kaart op de contactpagina gebruikt OpenStreetMap (geen tracking, geen API-sleutel).
- Het CMS en alle fonts worden lokaal geserveerd — er wordt nergens een externe CDN gebruikt.
Gemaakt met liefde voor Ligurië. 🇮🇹