Next + Strapi
Portfolio Website
I built my portfolio as a headless CMS using Next.js and Strapi to make content edits easy, add new languages quickly, and improve perceived performance with skeleton loading.
Why headless and Next.js
- Keep content and code separate so updates don’t require deploys.
- Roll out multilingual pages without duplicating templates.
- Smooth the loading experience with skeletons instead of blank flashes.
Architecture in a nutshell
- Frontend: Next.js App Router (app/[locale]/...) fetching content via API.
- CMS: Strapi models for Project, Experience, Category, Tag, plus locale-aware entries.
- Data flow: locale-aware requests with populate/sort; cache tuned per route using revalidate for freshness.
Multilingual approach
- Locale segment in the route (/[locale]/...) drives both UI text and Strapi queries.
- Strapi locales handle per-language entries; missing translations can optionally fall back.
- Translation workflow: create base entry → duplicate per locale → review/publish in Strapi.
Skeleton UX
- Skeletons for project/experience cards and detail pages to hide layout shift.
- Swap to real content once Strapi data resolves; loading/error states share the same patterns.
- Outcome: steadier perceived load (lower bounce), even when API responses vary.
Implementation highlights
- strapiFetch utility wraps auth, locale-aware queries, and error handling.
- Queries like fetchExperiences use sort: ["orderId:desc"] and populate for categories/tags to avoid N+1 calls.
- Dynamic routes generate metadata per locale, keeping SEO consistent across languages.
Results so far
- Content updates now happen in Strapi without redeploys.
- Adding a new language is mostly content work (no code changes).
- Skeletons reduced “flash of nothing” moments; perceived speed improved.
Challenges & next steps
- Automate translation or add a review checklist to prevent missing locales.
- Add preview/draft mode for safer publishing.
- Add image option and try image optimization and caching rules for media-heavy pages.
Key learnings
- Next.js App Router pairs well with Strapi.
- Designing locale-first routes early avoids refactors later.
- Consistent loading/error patterns make the UX feel intentional, not just fast.