JT
  • Home
  • Projects
  • Extras
  • Contact

© 2025 Joshua Tjhie. All rights reserved.

GitHubLinkedInEmail
Back to Projects
  1. Home
  2. Projects
  3. Personal Portfolio
2024-05-12

Personal Portfolio

The Next.js + Tailwind build powering this site.

Implementation notes for my current portfolio, design system, and content pipeline.

Next.jsReactDesign Systems
Personal Portfolio

Quick Stats

Role: Designer & Developer
Duration: Ongoing
Next.js 16 (App Router)React 19Tailwind CSS v4MDX

Links

Site Repository

Portfolio Architecture Snapshot

This is the temporary skeleton for the write-up about the site you’re browsing. I’ll flesh it out with deeper dives on the design system, animations, and content tooling soon.

My previous portfolio was a rigid single-page build that made adding experiments painful, so this iteration focuses on extensibility first and polish second.

Goals

  • Ship a performant, animation-rich portfolio on the latest Next.js App Router stack.
  • Keep content authoring simple via MDX while enforcing validation.
  • Showcase experiments, extras, and project write-ups with consistent UI primitives.

Stack Highlights

  • App shell: Next.js 16 with React Server Components, streaming layouts, and custom metadata helpers.
  • Design system: Tailwind v4 + shadcn-inspired primitives, gradient overlays, and canvas background layers.
  • Content pipeline: MDX files validated with Zod, image metadata via Sharp, and custom carousels for featured work.
Current UI pass placeholder
Placeholder frame until fresh captures are rendered.

Component Sketches

Prototype animation of the featured carousel interactions.
// simplified MDX loader wiring
export async function getAllContent(type) {
const entries = await loadAllContent(type)
return entries.map((entry) => ({
  ...entry,
  isPlaceholder: entry.title.endsWith('(Work in Progress)'),
}))
}

Roadmap

  • Document the motion system (Framer Motion + intersection observers).
  • Add a section on the embedded OG image generator.
  • Publish performance metrics and accessibility checks.

Content Authoring Process

Writing new project or extra entries stays intentionally lightweight:

  1. Create an .mdx file under content/projects or content/extras.
  2. Populate front matter with the required fields (title, slug, date, tags, etc.). The Zod schema in lib/content.ts validates everything at load time.
  3. Reference media with the /projects/<slug>/... paths emitted by the asset pipeline. Missing files automatically fall back to the gear placeholder.

Available MDX Components

  • <Image> and <Gallery> handle responsive media with blur placeholders.
  • <Video> and <AudioPlayer> embed hosted assets with consistent framing.
  • <LinkButton> creates gradient CTAs to source repos, demos, or contact links.
  • <RelatedContent> can surface other entries (projects/extras) by slug and type.
  • <Callout>, <Quote>, <Code>, and <Markdown> give me flexible narrative building blocks without retyping markup.

By sticking to these primitives, every page inherits the same typography, spacing, and motion patterns—even when the underlying project is still a work in progress.

View Source
Obsidian Workspace (Work in Progress)
Obsidian Workspace (Work in Progress)
A look at my current Obsidian vault organization and daily note workflow.
Extra•2024-05-08•Obsidian
Neovim Setup (Work in Progress)
Neovim Setup (Work in Progress)
Plugins, keymaps, and workflow choices in my Neovim setup.
Extra•2024-05-01•Neovim

Have thoughts?

Curious what others see or think

Feel free to reach out or leave feedback

Share Feedback

Prefer email? joshuatjhie@pm.me