mikkelmanniche.dk
The site you're on. Hand-written from scratch, no WordPress, theme or build process, and written in Danish, English and German. The video shows the pricing page, from fixed price to payment.
The starting point
I wanted a site that does what I offer other people: fast, without unnecessary third parties, and honest about what's measured. So standard solutions like Google Fonts and ready-made cookie-banner scripts were ruled out, because they pass data on themselves before anyone has said yes.
What was built
Pages in three languages in hand-written HTML, CSS and a little JavaScript. The fonts sit on my own domain. Analytics only start once you press accept; if you say no, nothing happens.
The pricing page has fixed prices, and payment happens via Stripe straight from the page. The video above shows the flow from choosing a package to payment.
Fixed one-off prices, no VAT, quoted from pricing.html. Only "Larger Website" is an indicative starting price.
Behind the scenes
Behind the site sits an admin panel for enquiries, mailboxes and visitor numbers, built in Vite and React, and a lead tool for finding new clients. Notifications are optional and off by default.
The admin panel's stackpackage.json
- Vite 6Build and local server
- React 19+ react-router-dom
- Tailwind CSS 4+ HeroUI
- PHP APInpm run api, local router
Locally the API is run by npm run api against test data; test data is reset with npm run testdata, otherwise the test login doesn't work.
The technology
Plain HTML and CSS with no framework, the same approach as on terjepedersen.dk. A strict browser security rule allows content only from my own domain, so nothing can be loaded from anywhere else unless I've written it in myself.
Security rule in .htaccessContent-Security-Policy
default-src 'self'; script-src 'self' https://www.googletagmanager.com https://datafa.st https://www.googleadservices.com https://googleads.g.doubleclick.net https://www.google.com; connect-src 'self' https://admin.mikkelmanniche.dk https://datafa.st https://*.google-analytics.com …; img-src 'self' data: https://*.google-analytics.com …; style-src 'self' 'unsafe-inline'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; base-uri 'self'
-
/assets/style.cssOwn domain allowed -
fonts.googleapis.comGoogle Fonts — font-src only allows 'self' blocked -
cdnjs.cloudflare.comThird-party script CDN, not in script-src blocked -
www.googletagmanager.com/gtag/jsIn script-src, but only loaded once you've said yes allowed by the rule -
www.youtube.com/embed/…Third-party iframe, no frame-src exception blocked
The rule only sends script, style, font and image requests to the domains it names itself — everything else falls back to default-src 'self' and is stopped by the browser, not by the server.