a808f1010f124d347e22cfb1e8725207ecb1aecc
The browser never talks to Strapi: pages call Nitro endpoints under server/api/, which are the only place Strapi queries are built. That keeps the Strapi URL internal to the Docker network and avoids CORS entirely. Article bodies are rendered from Markdown to HTML in the endpoint, so the content is server-rendered and crawlable, marked stays out of the client bundle, and the meta description is derived from the opening of the body. Pages carry canonical URLs, Open Graph tags and BlogPosting structured data, and handle empty, missing and failed states.
Blog
Blog platform: a public website built with Nuxt, and a private Strapi CMS where editors write the articles. Everything runs behind Caddy via Docker Compose.
Browser → Caddy ─┬─ public domain → Nuxt (website)
└─ cms subdomain → Strapi (CMS) → PostgreSQL
Status: bootstrap. The application code is not in place yet.
Getting started
Requires Docker and Node.js 20+.
cp .env.example .env # fill in the secrets, never commit this file
docker compose up -d --build
Then open the CMS URL to create the first admin account and start publishing. The public site picks up published articles automatically.
Working on it
cd frontend && npm run dev # website
cd cms && npm run develop # CMS
Architecture, conventions and constraints are documented in CLAUDE.md.
License
Proprietary — Copyright (c) 2026 Davide Grilli. All rights reserved. See LICENSE.
Languages
TypeScript
60.1%
Vue
29.7%
JavaScript
5%
CSS
4%
Dockerfile
0.9%
Other
0.3%