Personal blog for Maarten Casteels at https://casteels.dev, built with Hugo and a custom theme.
- Hugo (site generation)
- Tailwind CSS + PostCSS (styling)
- Pagefind (static search index)
- AWS S3 + CloudFront + Route53 (hosting)
- Terraform (infrastructure as code)
Requirements:
- Hugo (extended)
- Node.js + npm
Common commands:
npm install
npm run devWhat it does:
- Builds the CSS once, then keeps Tailwind/PostCSS watching for changes
- Builds the site (including drafts and future posts)
- Runs Pagefind on
public/ - Starts the Hugo dev server
Important:
hugo serveralone does not rebuildstatic/css/main.css.- For template or Tailwind changes, use
npm run devor runnpm run build:cssmanually.
npm run buildOutputs the site to public/ and generates the Pagefind index.
To preview the IndexNow payload from the current sitemap:
npm run build
npm run indexnow:dry-runcontent/- posts and pageslayouts/- custom layouts/shortcodesthemes/custom/- theme sourcestatic/- static assets copied to the siteresources/- Hugo pipeline cache/artifacts
- Blog posts under
content/posts/...should usecover.webpas the hero image. - Preferred cover size is
2400x1260. - New posts created with
hugo new posts/...usearchetypes/posts.md, which includes the standard cover front matter.
Terraform lives in infra/ and manages:
- S3 buckets:
casteels.devandwww.casteels.dev - CloudFront distributions (main + www redirect)
- ACM certs (us-east-1) and Route53 records
- Security headers (CSP, HSTS, etc.)
Typical workflow:
terraform -chdir=infra init
terraform -chdir=infra plan
terraform -chdir=infra applyNotes:
- Backend state is stored in
s3://casteels-dev-terraform-state-bucket/hugo-site/terraform.tfstate. - AWS credentials are required for
eu-west-1andus-east-1. - CSP allowlists are defined in
infra/cloudfront.tf(fonts, analytics, comments, etc.). If a browser reports CSP violations, add the required domains to the relevantcsp_*_allowlist.
- The site hosts its IndexNow key at
/a9396471fd0ec31f789c1992bb07f313.txt. - The first deploy after the key goes live submits the full sitemap to IndexNow.
- The deploy workflow compares the live sitemap with the freshly built
public/sitemap.xml. - After the S3 sync, it submits added, updated, and removed URLs to the IndexNow global endpoint.
Comments are handled via utteranc.es linked to denmette/denmette.github.io (see hugo.toml).