Bilingual (EN / TH) personal portfolio for a Web Application Consultant · Backend Specialist. Built with Astro 6 + TypeScript + Tailwind CSS 4 + MDX, fully static, dark-mode-first.
Live demo: bawonsak.pages.dev
- English routes:
/,/about,/case-studies,/case-studies/<slug>,/expertise,/contact - Thai routes: same paths under
/th/... - Route-aware language switcher,
hreflang+ canonical metadata, OpenGraph tags.
npm install
npm run dev # http://localhost:4321npm run build # outputs static site to dist/
npm run preview # serve dist/ locally- Push this folder to a Git repository (GitHub/GitLab).
- Cloudflare dashboard → Workers & Pages → Create → Pages → Connect to Git.
- Settings:
- Framework preset: Astro
- Build command:
npm run build - Build output directory:
dist
- Deploy. Add your custom domain under Custom domains.
(CLI alternative: npx wrangler pages deploy dist.)
- Push to a Git repository.
- Vercel dashboard → Add New → Project → import the repo.
- Vercel auto-detects Astro (build
npm run build, outputdist). Deploy.
(CLI alternative: npx vercel.)
- Cloudflare Pages → Settings → Environment variables →
SITE_URL(Production scope) =https://bawonsak.pages.dev. Every absolute URL (canonical/hreflang/OG/sitemap/robots) derives from it. Preview deploys auto-useCF_PAGES_URL, so leaveSITE_URLunset for Preview. -
src/data/site.ts→ GitHub / LinkedIn URLs point to real profiles. -
public/og.png(1200×630) is included. To regenerate after editingpublic/og.svg, render the SVG at 1200×630 and export as PNG.
| What | File |
|---|---|
| English page copy (home, about, expertise, contact) | src/data/en.ts |
| Thai page copy | src/data/th.ts |
| Name, email, socials, SEO titles/descriptions | src/data/site.ts |
| Case studies (English) | src/content/case-studies/en/*.mdx |
| Case studies (Thai) | src/content/case-studies/th/*.mdx |
| Small shared UI strings (nav, footer, labels) | src/i18n/ui.ts |
| Colors, fonts, design tokens | src/styles/global.css |
| Hero architecture diagram | src/components/HeroArchitectureVisual.astro |
| Terminal panel log lines | terminal section in src/data/en.ts / th.ts |
- Create
src/content/case-studies/en/<slug>.mdxandsrc/content/case-studies/th/<slug>.mdxwith the sameslugandorderin frontmatter (schema insrc/content.config.ts). - Routes, cards, and the language switcher pick it up automatically.
src/
components/ # 25 reusable components (+ pages/ = 5 per-page templates)
content/case-studies/{en,th}/ # MDX case studies
data/ # en.ts, th.ts, site.ts — all page content
i18n/ # locale config, UI strings, route utils
layouts/ # BaseLayout (SEO/hreflang), CaseStudyLayout
lib/ # seo helpers
pages/ # thin route files; th/ mirrors the root
styles/global.css # design tokens (OKLCH) + utilities
Code is released under the MIT License — feel free to learn from or reuse the implementation.
Personal content — case-study copy, name, photos, branding, and the OG image — is not covered by the MIT license and remains © Bawonsak Petchbunjerdkul. Please replace it with your own if you fork this for your portfolio.
