Personal Portfolio Platform
02/15/2026 · 6 min read
A static-first personal product with typed content, reusable UI systems, and production-minded delivery flow.
Next.jsReactTypeScriptServer ActionsTailwindArchitecture
Project Intent
This project is my main engineering surface: a portfolio and technical notebook built to stay maintainable while still shipping polished UI and real product behavior.
- Keep the stack lean and understandable so development remains fast without hidden operational complexity.
- Build reusable page and component patterns that support both product storytelling and technical deep-dives.
- Ship release-ready behavior (forms, metadata, navigation, accessibility, and responsive UX) instead of only static visuals.
Architecture Snapshot
- • Next.js App Router with server-first pages, route-level metadata, and static generation for project/blog slugs.
- • Typed content modules for projects/blog/home copy to keep authoring close to rendering logic and prevent schema drift.
- • A reusable design layer with Tailwind primitives, shared cards, and a unified code block surface powered by react-syntax-highlighter.
- • Server actions for contact delivery using Resend, with validation, anti-spam checks, and deterministic redirect outcomes.
- • Dependency choices prioritize readability and ecosystem fit: Next.js, React, TypeScript, Tailwind, lucide-react, and react-syntax-highlighter.
Shipped Feature Set
- • Unified slug-based project and blog routes with canonical metadata and legacy query-route redirect compatibility.
- • A configurable code presentation component that supports compact previews, detailed examples, line numbers, and optional copy-to-clipboard.
- • Contact workflow with honeypot/timing/link heuristics, user-facing feedback states, and optional Resend delivery fallback behavior.
- • Mobile-first interaction layer: drawer navigation, horizontal photo rail, modal viewer, and reduced-motion-aware transitions.
- • Icon refactor from inline SVG paths to lucide-react components for readability and maintainability.
Implementation Examples
Reusable code surfaces mirror the style used in project previews and deeper technical pages.
contact-action-guardrails.ts
1export async function submitContactForm(formData: FormData) {
2 const name = toSafeText(formData.get("name"));
3 const email = toSafeText(formData.get("email")).toLowerCase();
4 const message = toSafeText(formData.get("message"));
5 const company = toSafeText(formData.get("company"));
6 const formStartedAt = Number.parseInt(toSafeText(formData.get("formStartedAt")), 10);
7
8 const isTooFast = Number.isFinite(formStartedAt) && formStartedAt > 0 && Date.now() - formStartedAt < 1500;
9 const hasSuspiciousLink = URL_PATTERN.test(message) && message.length < 40;
10
11 if (company || isTooFast || hasSuspiciousLink) {
12 redirect("/contact?status=error&code=spam");
13 }
14
15 if (!name || !EMAIL_PATTERN.test(email)) {
16 redirect("/contact?status=error&code=email");
17 }
18
19 if (message.length < 10 || message.length > 3000) {
20 redirect("/contact?status=error&code=message");
21 }
22}reusable-code-block-surface.tsx
1export function CodeBlock({
2 code,
3 title,
4 language = "typescript",
5 compact = false,
6 showLineNumbers = true,
7 wrapLongLines = false,
8 enableCopy = false,
9}: CodeBlockProps) {
10 return (
11 <div className="overflow-hidden rounded-2xl border border-zinc-800/80 bg-zinc-950">
12 <div className="flex items-center justify-between border-b border-zinc-800 px-4 py-2">
13 <p className="text-xs text-zinc-400">{title ?? "typescript"}</p>
14 {enableCopy ? <CopyButton code={code} /> : null}
15 </div>
16
17 <SyntaxHighlighter
18 language={language}
19 style={oneDark}
20 showLineNumbers={showLineNumbers}
21 wrapLongLines={wrapLongLines}
22 customStyle={{
23 margin: 0,
24 background: "transparent",
25 fontSize: compact ? "0.75rem" : "0.875rem",
26 }}
27 >
28 {code}
29 </SyntaxHighlighter>
30 </div>
31 );
32}Current Focus
- • Content pass: rewrite and personalize all copy with stronger outcomes, clearer project narrative, and better contextual screenshots/snippets.
- • Pre-release hardening: final accessibility/SEO/performance checks and deployment configuration validation.
- • Translation rollout: complete EN/SK divergence from shared placeholders once content quality pass is done.