- Astro 74.6%
- CSS 8.5%
- TypeScript 8.1%
- JavaScript 7.3%
- HTML 0.9%
- Andere 0.6%
Performance - width/height op alle img tags voorkomt layout shift - decoding=async overal - fetchpriority=high + loading=eager op hero images en blog cover SEO - BlogPosting JSON-LD per blog-artikel (datum, auteur, publisher, mainEntityOfPage). Naast de bestaande BicycleStore LocalBusiness data. Copy - 56 em-dashes vervangen door hyphens in content, components, README, Decap config, code-comments en JSON. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| public | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .nvmrc | ||
| astro.config.mjs | ||
| Dockerfile | ||
| nginx.conf | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Roto Tweewielers - website
Een frisse, snelle website voor Roto Tweewielers (Deventer), gebouwd met Astro en beheerd via Decap CMS. De content is volledig redactioneel bewerkbaar; de webshop draait apart via een eigen API en valt buiten dit project.
- Framework: Astro (statische build, 0 KB JS standaard)
- CMS: Decap CMS met Forgejo/Gitea-backend (PKCE-login)
- Hosting: Docker → Coolify (nginx serveert de statische build)
- Taal: Nederlands
Snel starten (lokaal)
Vereist: Node.js 20+ en npm.
npm install # dependencies installeren
npm run dev # dev-server op http://localhost:4321
Het CMS lokaal testen
Decap draait lokaal tegen je git-werkmap, zónder login. Start in een tweede terminal:
npm run cms # decap-server (proxy) op poort 8081
Open dan http://localhost:4321/admin/. Wijzigingen die je opslaat, schrijft Decap
direct naar de bestanden in src/content/ en src/data/. Dit werkt doordat
local_backend: true in public/admin/config.yml staat.
Projectstructuur
src/
├── content/ # Door het CMS beheerde content (markdown)
│ ├── pages/ # Vaste pagina's (home, werkplaats, service, …)
│ ├── assortiment/ # Fietscategorieën
│ ├── tweedehands/ # Occasions
│ ├── diensten/ # Servicevormen
│ └── blog/ # Blogartikelen
├── data/ # site.json (contact, tijden, menu) + brands.json
├── components/ # Herbruikbare Astro-componenten
├── layouts/ # BaseLayout (head, SEO, structured data)
├── pages/ # Routes (.astro) + blog/rss.xml.js
├── styles/global.css # Design system (tokens, componenten)
└── content.config.ts # Schema's van de content-collecties
public/
├── admin/ # Decap CMS (index.html + config.yml)
├── images/uploads/ # Door redacteuren geüploade media
├── favicon.svg
└── robots.txt
Dockerfile, nginx.conf # Deploy naar Coolify
Inhoud en presentatie zijn gescheiden: het schema in src/content.config.ts en de
velden in public/admin/config.yml beschrijven dezelfde data. Pas je het één aan,
werk dan het ander bij.
Content bewerken
| Onderdeel | Waar in het CMS | Bestanden |
|---|---|---|
| Homepage & pagina's | Pagina's | src/content/pages/*.md |
| Fietscategorieën | Assortiment - categorieën | src/content/assortiment/*.md |
| Tweedehands fietsen | Tweedehands fietsen | src/content/tweedehands/*.md |
| Servicevormen | Diensten | src/content/diensten/*.md |
| Blog | Blog | src/content/blog/*.md |
| Contact, tijden, menu | Instellingen → Algemeen | src/data/site.json |
| Merken | Instellingen → Merken | src/data/brands.json |
Afbeeldingen worden geüpload naar public/images/uploads/ en automatisch goed
gelinkt. Staat er nog geen foto bij een item, dan toont de site een nette placeholder.
Productie: Forgejo-login instellen
Decap logt rechtstreeks in op je Forgejo (gitea-backend, PKCE - geen aparte OAuth-server nodig). Eenmalig instellen:
-
OAuth-app in Forgejo Ga naar Instellingen → Toepassingen → Nieuwe OAuth2-toepassing beheren (of org-/admin-niveau voor een gedeelde app).
- Redirect URI:
https://<jouw-site>/admin/ - Confidential Client: uitvinken (verplicht voor PKCE)
- Kopieer de Client ID.
- Redirect URI:
-
public/admin/config.ymlinvullen (onderbackend:):backend: name: gitea repo: <eigenaar>/rotosite # je Forgejo-repository branch: main app_id: <Client ID uit stap 1> api_root: https://<jouw-forgejo>/api/v1 base_url: https://<jouw-forgejo> auth_endpoint: https://<jouw-forgejo>/login/oauth/authorize -
CORS aanzetten in Forgejo en versie 1.21.4+ gebruiken, anders mislukt de login.
Redacteuren hebben push-rechten op de content-repository nodig. Let op: de gitea-backend ondersteunt (nog) géén editorial workflow; opslaan commit direct naar de gekozen branch. Werk daarom bij voorkeur via een aparte branch of staging-omgeving als je een reviewstap wilt.
Deployen op Coolify
De Dockerfile bouwt de site en serveert hem met nginx.
- Push deze repository naar Forgejo.
- Maak in Coolify een nieuwe resource → Dockerfile-based, wijzend naar de repo.
- Zet eventueel environment-variabelen (zie
.env.example):PUBLIC_SITE_URL- de echte domeinnaamPUBLIC_CONTACT_ENDPOINT- endpoint voor het contactformulier (optioneel)
- Deploy. Coolify bouwt het image en serveert de statische site op poort 80.
Elke push naar de content-repo (ook via het CMS) kan een automatische rebuild triggeren via een Coolify-webhook.
Tip: commit na de eerste
npm installook depackage-lock.json. Wijzig dan in deDockerfilenpm installnaarnpm civoor reproduceerbare builds.
Voorraadportaal (Bus Vol Bikes)
De pagina's /assortiment, /tweedehands en de "Uitgelicht uit de voorraad"-sectie
op de homepage halen hun data live op uit het Bus Vol Bikes voorraadportaal
(https://portaal.busvolbikes.nl, source op
code.vanmullemholding.eu/jesse-a/BusVolBikesAPI).
Hoe het werkt
- Server-side fetch tijdens
astro build:src/lib/busvol.tsroept/api/fietsenaan en Astro rendert de kaarten als statische HTML. Geen CORS-zorgen, snel laden, SEO-vriendelijk. - Fail-soft: als het portaal even niet bereikbaar is, valt de pagina terug op een "voorraad even niet bereikbaar"-blok met telefoonnummer.
/assortimenttoont alles met client-side filterknoppen (Alles/Nieuw/Gebruikt)./tweedehandsfiltert al server-side via?state=used.- Homepage toont 6 uitgelichte fietsen met een knop naar
/assortiment.
Vers houden
Statische builds betekent dat data zo vers is als de laatste build. Twee paden:
- Coolify webhook: rebuild bij elke push naar
main(automatisch via Decap). - Cron-rebuild voor live stock: configureer in Coolify een uurly redeploy
(
Resources → Schedules), of trigger via webhook vanuit het portaal zodra de voorraad wijzigt.
Configuratie
| Env-var | Default | Wat |
|---|---|---|
PUBLIC_BUSVOL_PORTAL_URL |
https://portaal.busvolbikes.nl |
Base-URL van het portaal. Override voor andere klanten of staging. |
Inhoud aanpassen
De producten zelf beheer je in het portaal (admin van Bus Vol Bikes), niet via
Decap. De intro-teksten boven het assortiment- en tweedehands-grid zijn wél
bewerkbaar in Decap (Pagina's → Assortiment / Tweedehands).
Handige commando's
npm run dev # ontwikkelserver
npm run cms # Decap local backend (naast dev)
npm run build # productie-build naar ./dist
npm run preview # de build lokaal bekijken
Design aanpassen
Alle kleuren, typografie en spacing staan als CSS-variabelen bovenin
src/styles/global.css. Een eigen lettertype toevoegen kan eenvoudig met een
self-hosted font (bijv. via Fontsource) door
--font-display / --font-sans aan te passen.