orchestrator.dev architecture
• 3 min read
architecture astro cloudflare content search
Overview
This post documents how orchestrator.dev is structured: the stack, content model, build pipeline, search, security, and how drafts and deployments work.
Stack
- Framework: Astro (static output)
- Styling: Tailwind CSS
- Content: Markdown collections (blog, portfolio) with Zod schemas
- Search: Pagefind (static index, client-only bundle)
- Hosting: Cloudflare Pages (static deploy)
- Deploy tooling: GitHub Actions (optional), Wrangler CLI only if manually deploying assets
- Node target: 22.x (matches Cloudflare Pages)
Content model
- Blog posts live in
src/content/blog/and portfolio items insrc/content/portfolio/. - Each file uses frontmatter validated by Astro content collections:
- Required:
title,description,pubDate - Optional:
updatedDate,heroImage,tags,draft
- Required:
- Draft gating:
draft: trueexcludes from listings and static paths; an action can also remove drafts before deploy onmain.
Branching and workflow
main: published content; Cloudflare Pages deploys from here.draft: work-in-progress; safe to keep drafts here or in PRs.- Optional GitHub Action
filter-drafts.ymlremovesdraft: truecontent before production deploy onmain.
Build and deploy (Pages)
Key commands:
npm run build->astro build+npm run pagefind- Output:
dist/(static HTML, assets,pagefindbundle)
If using Wrangler manually instead of Pages auto-deploy:
npm run buildnpx wrangler pages deploy dist --project-name orchestrator-devwrangler.jsoncpoints Wrangler to./distassets.
Runtime request path (static)
Search
- Pagefind CLI runs after build to generate
dist/pagefind/. - In
src/pages/search.astro, we load/pagefind/pagefind.jsat runtime and callwindow.pagefind.init(); this avoids bundling the Node package and keeps Vite from resolving it. - The index is fully static; no backend is required.
SEO and LLM friendliness
- JSON-LD via
generateJsonLdhelpers inBaseLayout. sitemap-index.xmlfrom@astrojs/sitemap.robots.txtinpublic/.- Canonicals, Open Graph, Twitter cards, RSS feed (
/rss.xml).
Security and performance
- Security headers via
src/middleware.ts: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy. - Additional headers in
public/_headersfor Pages. - Static output keeps the attack surface minimal; Cloudflare CDN adds edge caching and TLS.
Project layout (high level)
src/
content/
blog/ # markdown posts
portfolio/ # markdown projects
components/ # Header, Footer, ThemeToggle, etc.
layouts/ # BaseLayout
pages/ # routes (blog, portfolio, search, about)
utils/ # seo.ts helpers
middleware.ts # security headers
public/
images/ # static assets
_headers # extra headers for Pages
robots.txt
dist/ # build output (generated)
dist/pagefind/ # search index (generated)
Local development
npm install
npm run dev
# Build + search index
npm run build
Domain and redirects
- Primary domain:
orchestrator.dev - Redirect
www-> apex can be set in Cloudflare Pages Redirects (or a_redirectsfile inpublic/if desired). - Update
astro.config.mjssiteandpublic/robots.txtto match the chosen domain.
Notes on Pages vs. Wrangler
- Preferred: let Cloudflare Pages deploy the static
dist/(no Worker entry point needed). - If using Wrangler CLI, keep
wrangler.jsoncwithassets.directory: "./dist"; do not expectworkers-site/index.js(that is for deprecated Workers Sites).