Portfolio + blog site built with Astro, with room to grow AI-powered tools.
- Astro + TypeScript
- Svelte integration enabled for interactive components
- MDX support for richer writing workflows
- ESLint + Prettier + Husky + lint-staged for guardrails
/
├── public/ # static assets
├── src/
│ ├── components/ # shared UI components
│ ├── content/ # content collections (blog)
│ │ └── blog/
│ ├── layouts/ # page layouts
│ ├── lib/
│ │ └── ai/ # AI provider and env helpers
│ ├── pages/
│ │ ├── api/ai/ # AI endpoints
│ │ ├── blog/ # blog list + dynamic post routes
│ │ ├── tools/
│ │ └── ...
│ ├── styles/
│ └── content.config.ts # Astro content collection schema
├── .husky/ # git hooks
├── eslint.config.js
└── lint-staged.config.mjs
npm installnpm run devnpm run checknpm run buildnpm run preview
Blog posts now live in src/content/blog/*.md and are typed by src/content.config.ts.
- List page:
src/pages/blog/index.astro - Post page:
src/pages/blog/[slug].astro
The project includes a starter server-side AI shape:
src/lib/ai/env.tsvalidates required environment variablessrc/lib/ai/providers/openai.tscontains a provider wrappersrc/pages/api/ai/health.json.tshealth endpointsrc/pages/api/ai/generate.json.tsprompt -> text endpoint
Copy .env.example and set:
OPENAI_API_KEY
- Keep API keys server-side only (never in client bundles).
- Use API routes for AI calls and keep prompts/provider logic inside
src/lib/ai.