Portfolio Website Development ๐Ÿ—๏ธ - Part 3

Portfolio Website Development ๐Ÿ—๏ธ - Part 3

24 Aug, 2025 โ€ข 3 min read

Portfolio series Part 3: Next.js 15 App Router, Velite and MDX, SEO via sitemap RSS and JSON-LD, global search, theming, and lessons from running souravdey.space as home for my writing.

Listen
Playback speed
In Part 1 I sketched the stack and the Figma-led plan. In Part 2 I shipped a single-page Next.js site with scroll sections and Hashnode powering the latest posts. A lot has changed since then. This part is about the current souravdey.space: what it runs on, how content works, and why I optimized for maintainability and discoverability as much as for the hero section.
If you are reading this on the site, you are already looking at the outcome. If not, here is the same place: souravdey.space.

From single-page scroll to the App Router

The old version felt right at the time: one long page, anchor navigation, a clear story. Over the years I wanted proper URLs for every blog and mind nugget, tag and series pages, and room to grow without turning one file into a kitchen sink.
Today the project is Next.js 15 with the App Router (src/app/). Pages like /blogs, /blogs/[slug], /mindNuggets/[slug], /mentorship, and /sideProjects are first-class routes instead of sections inside a single view. That choice trades a bit of that original โ€œone canvasโ€ vibe for something closer to how people actually share and return to specific pieces of content.

Content lives in the repo, not only in APIs

Part 2 mentioned moving blogs to MDX on the site. That migration is in place now. Posts and shorter pieces live under src/content/ as .mdx files. Velite validates frontmatter, runs the MDX pipeline (including syntax highlighting via rehype-pretty-code), and generates typed data under .velite/ that the app imports through the #content alias.
Collections I use today include blogs, mind nuggets, ideas, and books. Blogs support tags, optional series, reading time from metadata, and a table of contents derived from headings. Publishing is a frontmatter flag, so drafts stay out of the sitemap and RSS until I flip them on.
No more fetching โ€œlatest fourโ€ from Hashnode for the homepage story. The narrative and SEO now center on this domain and this content graph.

SEO and feeds as first-class features

Shipping articles is only half the job if search and aggregators cannot see them cleanly. The current setup includes:
  • sitemap.ts: entries for published blogs and mind nuggets, plus tag and series index URLs and static pages.
  • robots.ts: allows crawlers and points to the sitemap.
  • feed.xml: RSS with Atom link for blogs (and related structure for discoverability).
Per-page generateMetadata on dynamic routes sets titles, descriptions, Open Graph, and Twitter cards from frontmatter (including article dates and tags where it matters). JSON-LD covers sitewide Person and WebSite schema, with BlogPosting / Article style data on content pages so rich results have something consistent to read.
That is not glamour work, but it is the kind of work that compounds once you write in public for years.

UX details that matter day to day

A few things I reach for myself when I use the site:
  • Theme toggle with persistence (light and dark), aligned with how the layout and CSS variables are structured.
  • Global search over an index built from content, so jumping to a post or nugget does not depend on remembering the slug.
  • Motion used sparingly for page transitions and small accents so the site still feels alive without fighting readability.
  • MDX components (callouts, embeds, image grids) so posts are not plain walls of text when the topic needs more than paragraphs.
These are not โ€œfeatures for a portfolio checklist.โ€ They are the friction removers you notice once the content count grows.

Stack snapshot (high level)

If you like a single glance:
  • Framework: Next.js 15 (App Router), React 18
  • Styling: Tailwind CSS v4
  • Content: MDX + Velite, content in src/content/
  • Deployment: still in the Vercel-shaped world you would expect for this stack
  • Analytics: Google Analytics via Nextโ€™s third-party helper where configured
Exact dependency versions belong in package.json; the point is the shape of the system: typed content, static generation where it fits, and metadata treated as part of the product.

What I would do differently

Hindsight is easy, but two things stand out.
First, I would have moved canonical hosting of posts to the personal domain earlier. Cross-posting and syndication are fine; owning the URL and the HTML long term matters more than I gave it credit for in 2021.
Second, I would document content conventions (frontmatter, tags, images, series) in one place as soon as the second post type appeared. Mind nuggets and blogs share patterns but are not identical. A short internal doc saves future me from guessing.

What is next?

The site is never โ€œdone,โ€ but the next improvements I care about are incremental: tighter performance budgets on heavy pages, more internal linking between related posts, and maybe reviving routes I parked behind comments in the nav when I have content worth showing there.
If you are building your own portfolio, you do not need this exact stack. You do need a plan for where writing lives, how URLs work, and how a stranger finds one specific thing you wrote. Get that right early; the gradient borders can wait.
โœจ Thanks for following this little trilogy. If Part 4 ever shows up, it will probably be about something this stack enabled, not the stack itself.