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.