Portfolio, Next.js 16 App Router, React 19 ve TypeScript ile inşa edilmiş çok kanallı bir çalışma alanıdır. content/ klasöründeki MDX ve PDF dosyaları otomatik olarak kenar çubuğuna, bloga, proje detaylarına ve not rafına bağlanır. app/layout.tsx tek bir veri katmanı oluşturarak ActivityBar, komut paleti, kenar çubuğu ve sayfa içeriklerini senkron tutar.
- Workspace odaklı UI:
app/components/layoutaltındaki ActivityBar, animasyonlu sosyal menü, komut paleti ve filtrelenebilir kenar çubuğu her cihazda çalışır. - Komut paleti & arama:
SearchModal+ Fuse.js ile sayfa, proje, blog, PDF not ve sosyal bağlantılarda ⌘/Ctrl + K kısayolu; ayrıca tema döngüsü ve e-posta kopyalama gibi hızlı aksiyonlar. - Zengin içerik akışı:
lib/mdx,lib/blog,lib/projectsvelib/notestüm MDX/PDF kaynaklarını derleyiprehype-highlightile kod bloklarını renklendirir. - PDF rafı:
PdfViewerbileşeni pdfjs-dist ile ilk sayfa ön izlemesi çizer, modal okuyucu açar ve/api/notes/[slug]üzerinden PDF’i servis eder. - Tema sistemi:
ThemeProvider30+ tema için CSS değişkenlerini yönetir, kullanıcı tercihini localStorage’da saklar veThemeSwitcherüzerinden değiştirir. - RSS + otomasyon:
app/rss.xml/route.tsblog yazıları ile PDF notlarını tek feed’de birleştirir, güncelleme tarihi olarak içerik metadata’sını ve dosya sistemini kullanır. - Statik üretim + esneklik: Blog, projeler ve sayfalar
generateStaticParamsile build sırasında ön üretilir, eksik slug’lardanotFound()ile güvenle hata verir.
Önerilen ortam: Node.js ≥ 18.18, pnpm 9.
pnpm install # bağımlılıkları yükle
pnpm dev # http://localhost:3000
pnpm build # production çıktısı (.next)
pnpm start # build edilmiş projeyi başlat
pnpm lint # eslint.config.mjs kurallarını çalıştırVarsayılan avatarlar, özgeçmiş (public/resume.pdf) ve robots.txt gibi statik içerikler public/ altında servis edilir; geliştirme ile production davranışı aynıdır.
app/
components/ → ActivityBar, Sidebar, tema sheet’i, PDF viewer
blog/, projects/, notes/ → Rota dosyaları + dinamik slug sayfaları
api/notes/[slug]/ → PDF streaming API
rss.xml/route.ts → RSS feed üretimi
custom-md.css → MDX stilleri
content/
pages/, blog/, projects/, notes/ → Tüm içerik kaynakları (MDX + PDF)
data/
navigation.ts, tech.ts → ActivityBar ve tech-stack veri kümeleri
lib/
mdx.ts, blog.ts, projects.ts, notes.ts → Dosya sistemi yardımcıları
public/
avatars/, images/, resume.pdf → Medya ve statik dosyalar
app/layout.tsxtüm içerik metadata’sını yükler, ActivityBar/Sidebar/arama için tek kaynak oluşturur.app/[slug]/page.tsxMDX sayfalarınıcompileMDXile render eder; frontmatter’dakilinksalanını call-to-action butonlarına map eder.globals.css+custom-md.css, temalara göre güncellenen CSS değişkenleri ile tipografi ve Prose stillerini tanımlar.
Kişisel sayfalar (overview, about, projects vb.) burada tutulur. Frontmatter örneği:
---
slug: "overview"
title: "Welcome to My Workspace"
order: 1 # Sidebar sırası
tags: [intro, portfolio]
description: "Genel açıklama"
links:
- label: "Contact"
href: "/contact"
target: "_self"
---order değeri küçük olan ilk sayfa / rotasında otomatik yönlendirme hedefidir.
Her yazı için slug, title, description, date ve tags alanları kullanılır. Dosya ismi slug olarak okunur ve getAllBlogPostsMetadata tarih + başlık sırasına göre sıralar. Kod blokları rehype-highlight sayesinde otomatik renklendirilir.
Projeler bloglarla aynı MDX pipeline’ını kullanır fakat frontmatter’daki links dizisi proje detay sayfasında butonlara dönüştürülür. /app/projects/[slug]/page.tsx case study içeriğini ve bağlantılarını render eder, /content/pages/projects.mdx ise hızlı özetler sunar.
PDF’i klasöre bırakmak yeterlidir; isteğe bağlı metadata girerek kartları zenginleştirebilirsin:
{
"atomicdesign": {
"title": "Atomic Design Notları",
"description": "Bileşen hiyerarşisi özeti",
"tags": ["design systems", "ui"],
"date": "2025-02-10"
}
}PdfViewer bileşeni metadata’yı kart üzerinde gösterir, fileUrl olarak /api/notes/{slug} çağırır ve modalda iframe ile sunar.
- ActivityBar (
app/components/layout/activitybar.tsx),ACTIVITY_LINKSveSOCIAL_LINKSverisini kullanır; search butonu modalı açar, sosyal butonu animasyonlu dropdown üretir. - Komut paleti (
search-modal.tsx),Fuse.jsile hızlı arama vequickActions(tema döngüsü, e-posta kopyalama) sağlar.SECTION_ORDERsayesinde sonuçlar action → project → page → blog → note → social sırasına göre gruplandırılır. - Sidebar (
sidebar.tsx),content/pagesmetadata’sını kullanarak Explorer görünümünü oluşturur; mobilde motion tabanlı sheet, masaüstünde filtrelenebilir liste sunar.
Bu üçlü app/layout.tsx içerisindeki searchIndex objesi ile senkronize çalışır ve yeni içerik eklenir eklenmez güncellenir.
ThemeProvider (client component) tüm temaları APP_THEMES dizisinde tanımlar; id, label, açıklama ve ön izleme renkleri içerir. Kullanıcının seçimi portfolio.theme anahtarıyla localStorage’da saklanır. ThemeSwitcher, select bileşeni ve renk ön izleme küpleri ile temalar arasında geçiş yapar. Yeni bir tema eklemek için APP_THEMES dizisine obje ekleyip CSS değişkenlerini globals.css içinde tanımlamak yeterlidir.
PdfViewer pdfjs-dist’i dinamik import eder, ilk sayfayı canvas’a render eder, yükleme/başarısızlık durumlarını overlay olarak gösterir ve AnimatePresence ile modalı yönetir. /app/api/notes/[slug]/route.ts PDF’i dosya sisteminden okur, slug doğrulaması yapar ve cache header’ları ile döner. Böylece notlar hem web modalı hem de doğrudan download linki olarak paylaşılabilir.
app/rss.xml/route.ts blog yazıları ve PDF notlarından FeedItem dizisi oluşturur, içerik açıklamalarını sanitize eder ve CDATA ile sarar. Not dosyalarının güncelleme tarihi fs.stat ile okunarak feed’e işlenir. Varsayılan domain https://poyrazavsever.com; farklı bir domain için SITE_URL sabitlerini güncellemek yeterlidir.
- Production build:
pnpm build && pnpm start. - Next.js 16 otomatik olarak
appyönlendirmelerini optimize eder;content/klasörü git’e dahil olduğu sürece ekstra env değişkenine gerek yoktur. - PDF API’si dosya sistemine eriştiği için Vercel gibi sunucusuz ortamda
content/notesdosyalarınıpublic/yerinecontent/ile deploy paketine dahil etmelisin (git repo buna hazır).
- Next.js 16 (App Router, MDX, Edge-ready API Routes)
- React 19 + Server Components
- TypeScript 5.9
- Tailwind CSS 4 (configless) + özel CSS değişkenleri
- Framer Motion 12 (animasyonlar, modallar)
- Fuse.js (fuzzy arama)
- pdfjs-dist (PDF render)
- next-mdx-remote + rehype-highlight (MDX pipeline)
- Gray-matter (frontmatter ayrıştırma)
pnpm linttüm app + content bileşenlerinieslint.config.mjskurallarına göre denetler (next/core-web-vitals+ TypeScript plugin).- Bir içerik slug’ı bulunamadığında
notFound()çağrısı otomatik 404 üretir; geliştirme sırasında terminalde hata görebilirsin, slug/ dosya adı uyuştuğundan emin ol. - PDF ön izlemesi büyük dosyalarda zaman alabilir; canvas çözünürlüğünü
PdfVieweriçindekiPREVIEW_RESOLUTIONsabitiyle ayarlayabilirsin.
Portfolio is a multi-channel workspace built with Next.js 16 App Router, React 19, and TypeScript. MDX and PDF files that live under content/ automatically hydrate the sidebar, blog, project case studies, and note shelf. app/layout.tsx creates a single content index so that the ActivityBar, command palette, sidebar, and page body stay in sync.
- Workspace-grade UI: The ActivityBar, animated social dropdown, command palette, and filterable sidebar inside
app/components/layoutwork across breakpoints. - Command palette & search:
SearchModal+ Fuse.js let you discover pages, projects, blog posts, PDF notes, and social links with the ⌘/Ctrl + K shortcut plus quick actions (theme cycle, copy email). - Rich content flow:
lib/mdx,lib/blog,lib/projects, andlib/notescompile every MDX/PDF source whilerehype-highlightstyles code blocks. - PDF shelf:
PdfViewerrenders a first-page preview via pdfjs-dist, opens a modal reader, and streams the binary from/api/notes/[slug]. - Theme system:
ThemeProvidermanages 30+ color palettes as CSS variables, persists the preference in localStorage, and exposesThemeSwitcher. - RSS + automation:
app/rss.xml/route.tsmerges blog entries and PDF notes into one feed, reusing both metadata and filesystem timestamps. - Static generation + safety: Blog, project, and page routes call
generateStaticParamsduring build and fall back tonotFound()whenever a slug is missing.
Recommended toolchain: Node.js ≥ 18.18, pnpm 9.
pnpm install # install deps
pnpm dev # http://localhost:3000
pnpm build # production bundle (.next)
pnpm start # serve the built app
pnpm lint # run ESLintStatic assets such as the avatar set, public/resume.pdf, and robots.txt are served from public/ both locally and in production.
app/
components/ → ActivityBar, sidebar, theme sheet, PDF viewer
blog/, projects/, notes/ → Route handlers + dynamic slug pages
api/notes/[slug]/ → PDF streaming API
rss.xml/route.ts → RSS feed builder
custom-md.css → MDX styles
content/
pages/, blog/, projects/, notes/ → All MDX/PDF sources
data/
navigation.ts, tech.ts → ActivityBar + tech-stack datasets
lib/
mdx.ts, blog.ts, projects.ts, notes.ts → Filesystem helpers
public/
avatars/, images/, resume.pdf → Static media
app/layout.tsxpreloads every metadata entry and shares it with the ActivityBar/Sidebar/search index.app/[slug]/page.tsxrenders page MDX viacompileMDX, mapping frontmatterlinksto CTA chips.globals.css+custom-md.cssdefine the theme-aware typography and prose rules that adapt to each palette.
Reusable workspace pages (overview, about, bookmarks, projects, etc.). Sample frontmatter:
---
slug: "overview"
title: "Welcome to My Workspace"
order: 1 # sidebar ordering
tags: [intro, portfolio]
description: "General intro"
links:
- label: "Contact"
href: "/contact"
target: "_self"
---The smallest order becomes the redirect target for /.
Each article defines slug, title, description, date, and tags. File names become slugs, and getAllBlogPostsMetadata sorts by date, then title. Code blocks are highlighted through rehype-highlight.
Project case studies share the same MDX pipeline but expose their links array as buttons on /projects/[slug]. The overview card grid inside /content/pages/projects.mdx can link back to these case studies.
Drop any PDF into the folder and optionally enrich it via metadata:
{
"atomicdesign": {
"title": "Atomic Design Notes",
"description": "Hierarchy recap",
"tags": ["design systems", "ui"],
"date": "2025-02-10"
}
}PdfViewer displays the metadata on the card, hits /api/notes/{slug} as fileUrl, and opens an iframe-based modal reader on tap.
- ActivityBar (
activitybar.tsx) consumesACTIVITY_LINKS/SOCIAL_LINKS, animates the search button, and displays an expandable social panel. - Command palette (
search-modal.tsx) leverages Fuse.js for fuzzy grouping (actions → projects → pages → blog → notes → social) and exposes quick actions like theme cycling or copying the email address. - Sidebar (
sidebar.tsx) mirrors thecontent/pagesmetadata as the Explorer list with filtering, plus a motion-powered drawer on mobile.
All three read from the searchIndex object built in app/layout.tsx, so any new MDX/PDF file becomes searchable instantly.
ThemeProvider defines every palette under APP_THEMES, keeps the currently selected id in React state, propagates it to the <html data-theme> attribute, and persists it via localStorage. To add a palette, push a new entry to APP_THEMES and extend the CSS variables inside globals.css.
PdfViewer dynamically imports pdfjs-dist, renders page 1 to a canvas, shows loading/error overlays, and opens a Framer Motion modal. /app/api/notes/[slug]/route.ts validates the slug, streams the PDF, and adds caching headers, so notes can be embedded or downloaded directly.
app/rss.xml/route.ts builds a feed that combines blog posts with PDF notes, sanitizes content, wraps it in CDATA, and derives note timestamps via fs.stat. Update the SITE_URL constants to repoint the feed to a new domain.
- Run
pnpm build && pnpm start(or deploy on a compatible hosting provider such as Vercel). - Ensure
content/is part of the deployment artifact so that MDX and PDF assets are available at runtime. - The PDF API needs filesystem access; keep the notes within the repository (the current setup is Vercel-friendly).
- Next.js 16 (App Router, MDX, API Routes)
- React 19 + Server Components
- TypeScript 5.9
- Tailwind CSS 4 + custom CSS variable themes
- Framer Motion 12
- Fuse.js (command palette)
- pdfjs-dist
- next-mdx-remote + rehype-highlight
- Gray-matter
pnpm lintenforceseslint.config.mjs(Next core web vitals + TypeScript rules).- Missing slugs trigger
notFound()and surface 404s during development; double-check your file names and frontmatter. - Large PDFs may render slowly—tune the
PREVIEW_RESOLUTIONconstant insidePdfViewerto balance quality/performance.