Imported from Hamdyx/portfolio (
AGENTS.md). Install upstream withnpx skills add Hamdyx/portfolio. Copyright stays with the author.
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ (resolved from this file's directory; in monorepos the next package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This block is written and re-added by next dev — verify at node_modules/next/dist/server/lib/generate-agent-files.js. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
hamdyx — Ahmed Hamdy's Portfolio
Claude Code is the coding agent for this repo. All changes are made through it. Large efforts are planned once, up front, and split into phases — each phase is then executed in a fresh session from a prompt provided by the user. A session does not carry work over into the next phase on its own.
Git & Session Workflow
Applies to every session, without being asked:
-
Never commit to
main. Start every task on its own branch cut frommain. -
One branch per task, named
<type>/<slug>where<type>is one offeat,fix,chore,docs,perf,security,seo,refactor,ci(e.g.docs/claude-workflow-instructions). -
PRs target
main. -
Stay in scope. A session implements ONLY its assigned scope. Unrelated problems found along the way are reported to the user, not fixed.
-
Verify before asking.
yarn build(every warning is a blocker) andyarn lintmust both pass BEFORE presenting the work. -
ALWAYS ask permission before committing. Show the diff and wait — the user reviews it first. No exceptions.
-
After approval: commit with a short, lowercase, imperative message matching the repo's style (e.g.
update resume), including the Claude co-author trailer:Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>Then push the branch, open the PR with
ghfollowing.github/pull_request_template.md, and give the user the PR URL. The user merges, not the agent.
Mandatory Pre-Flight Checks
Before writing or modifying ANY code, the agent MUST:
- Verify API currency — check official docs or
node_modules/<pkg>/for the exact version installed (seepackage.json). Never rely on training data for API shapes. - Scan for deprecations — run
yarn buildafter changes and treat every warning as a blocker. If a component, prop, hook, or function is deprecated, use its documented replacement. - Read
node_modules/next/dist/docs/— Next.js 16 has breaking changes vs. 15/14. Always validate routing, metadata, caching, and config APIs against the bundled docs. - Consult Ant Design 6 changelog — Ant Design 6 removed or renamed several v5 APIs. When in doubt, verify against
node_modules/antd/es/exports.
Code Quality Principles (Always Apply)
These are defaults — follow them on every change without being asked:
- Clean code — small, single-responsibility functions. Descriptive names. No dead code. No commented-out code.
- TypeScript strict mode — no
any, no@ts-ignore, no non-null assertions (!) unless truly unavoidable. Prefer narrowing and type guards. - No manual memoization — React Compiler is enabled. Never add
useMemo,useCallback, orReact.memo. - Semantic HTML — use correct elements (
<nav>,<main>,<section>,<time>,<button>, etc.). Add ARIA attributes only when native semantics fall short. - Accessibility — all interactive elements must be keyboard-reachable, all images must have meaningful
alttext (oralt=""/aria-hiddenfor decoration), form inputs need labels. - No over-engineering — don't add abstractions, helpers, or error handling beyond what is needed. Don't wrap Ant Design components unnecessarily.
- Security — validate and sanitize at system boundaries. Follow OWASP Top 10. Never expose secrets in client code.
Deprecation & Version Awareness
| Package | Installed | Key Notes |
|---|---|---|
next |
16.3.0 | App Router only. No Pages Router. next/font/google for fonts. Turbopack dev server. |
react / react-dom |
19.2.8 | React 19 — use(), Actions, useFormStatus, useOptimistic are stable. Class component lifecycle is legacy. |
antd |
6.5.4 | v6 — no v4/v5 deprecated APIs (Form.create, Icon from antd, getFieldDecorator). Destructure sub-components, don't use dot notation in App Router. |
@ant-design/icons |
6.3.2 | Named icon imports only. No default import. |
@ant-design/nextjs-registry |
1.3.0 | Single <AntdRegistry> in ThemeProvider.tsx only. |
react-icons |
5.7.0 | Tree-shakeable named imports (react-icons/fa, react-icons/ri, react-icons/si, react-icons/tb). 5.7.0 removed SiOpenai. |
resend |
6.18.1 | Use Resend class constructor. Check for v6 API changes. |
@vercel/analytics |
2.0.1 | <Analytics /> component in layout. |
typescript |
6.0.3 | Use modern syntax: satisfies, using, template literal types where appropriate. Note: @typescript-eslint does not officially support TS 6 yet — unsupported-version warning from ESLint is expected and non-blocking. |
When unsure about any API: check the package's node_modules/<pkg>/ types or README before writing code. Do NOT guess or rely on memory.
Dependency-upgrade PRs MUST update this table — the Installed column has to match package.json in the same PR.
Tech Stack
- Framework: Next.js 16 (App Router only — no Pages Router)
- Language: TypeScript (strict mode)
- Package Manager: Yarn 4.13.0 (Berry, via Corepack)
- UI Library: Ant Design 6 (
antd,@ant-design/icons,@ant-design/nextjs-registry) - Styling: CSS Modules (no Tailwind, no styled-components)
- Email: Resend (
resend) — contact form emails - Analytics: Vercel Analytics (
@vercel/analytics) - Fonts: Geist Sans & Geist Mono via
next/font/google - Import Alias:
@/*→./src/* - React Compiler: Enabled
Project Structure
All source code lives under src/. The app uses the Next.js App Router (src/app/).
src/
├── app/
│ ├── api/
│ │ └── contact/
│ │ └── route.ts # POST handler — sends email via Resend (rate-limited)
│ ├── layout.tsx # Root layout — ThemeProvider, fonts, metadata, viewport, JSON-LD
│ ├── page.tsx # Home page — composes all section components
│ ├── globals.css # Global resets, theme variables (light + dark), base styles
│ ├── loading.tsx # Skeleton loading state (Ant Design Skeleton)
│ ├── not-found.tsx # Custom 404 page
│ ├── robots.ts # robots.txt generation (points to sitemap)
│ ├── sitemap.ts # sitemap.xml generation
│ ├── manifest.ts # PWA web manifest
│ └── page.module.css
├── components/ # Each component: index.tsx + ComponentName.module.css
│ ├── Navbar/ # Fixed nav bar with mobile Drawer
│ ├── Hero/ # Full-viewport intro section
│ ├── About/ # Bio, details, resume download
│ ├── Experience/ # Ant Design Timeline of work history
│ ├── Skills/ # Categorized grid (Row/Col/Card)
│ ├── Projects/ # Project cards with demo/GitHub links
│ ├── Contact/ # Ant Design Form with Resend email submission
│ └── Footer/ # Social links and copyright
├── config/
│ └── theme.ts # Ant Design ThemeConfig tokens (light + dark)
├── constants/ # All display data — edit these to update content
│ ├── personal.ts # Name, tagline, subtitle, social handles, email, website
│ ├── experience.ts # Work history (ExperienceItem[])
│ ├── skills.ts # Skills with categories (SkillItem[])
│ └── projects.ts # Projects with descriptions and URLs (ProjectItem[])
├── hooks/
│ └── useTheme.ts # Theme hook
└── providers/
├── ThemeContext.ts # Theme context definition
└── ThemeProvider.tsx # Theme provider (AntdRegistry + ConfigProvider)
Architecture Notes
- All components use
'use client'— required because Ant Design uses React hooks internally. - Data-driven UI — components read from
src/constants/. To update content (projects, skills, experience), edit the constants files only. - Single-page layout —
page.tsxcomposes sections in order: Navbar → Hero → About → Experience → Skills → Projects → Contact → Footer. - SSR style extraction —
@ant-design/nextjs-registrywrapsConfigProviderinsideThemeProvider.tsx. Do not remove<AntdRegistry>fromThemeProvider.tsx. Do NOT add a second<AntdRegistry>inlayout.tsx. - Contact form — submits via
POST /api/contactRoute Handler, which sends email through Resend. Rate-limited to 3 requests per IP per 60 seconds. RequiresRESEND_API_KEY,RESEND_FROM_EMAIL, andCONTACT_TO_EMAILenvironment variables. - SEO —
layout.tsxexports richmetadata(Open Graph, Twitter Cards, JSON-LD structured data) andviewport. Generatedrobots.ts,sitemap.ts, andmanifest.tslive insrc/app/. - Security headers — configured in
next.config.tsviaheaders():X-Content-Type-Options,X-Frame-Options,X-XSS-Protection,Referrer-Policy,Permissions-Policy. - Domain — deployed at hamdyx.dev via Vercel.
Conventions
React Compiler
React Compiler is enabled — do NOT use manual useMemo, useCallback, or React.memo. The compiler handles memoization automatically at build time.
If Ant Design component behavior quirks arise, disable in next.config.ts:
reactCompiler: false,
Ant Design in App Router
Destructure sub-components — dot notation does NOT work in App Router:
// ✅ Correct
const { Text } = Typography;
<Text>Hello</Text>
// ❌ Broken in App Router
<Typography.Text>Hello</Typography.Text>
Styling
- Use CSS Modules (
.module.css) for custom component styles. - Use Ant Design's
ConfigProvidertheme tokens (insrc/config/theme.ts) for design system overrides. - Primary color:
#4f46e5. Background:#f9f9ff. Text:#151c27. - Do NOT add Tailwind CSS or styled-components.
Import Order (enforced by ESLint)
Imports must follow this order with blank lines between each group:
- Type imports (
import type { ... }) — all type-only imports regardless of source - External packages —
react,next,antd, etc. - Alias imports —
@/*paths - Relative imports —
./,../
import type { Metadata } from 'next';
import type { ReactNode } from 'react';
import type { HomeProps } from '@/types/home';
import { ConfigProvider } from 'antd';
import Image from 'next/image';
import { Header } from '@/components/Header';
import { theme } from '@/config/theme';
import styles from './page.module.css';
Common Pitfalls (Do NOT)
- Do NOT use
next/head— use themetadataexport orgenerateMetadatain App Router. - Do NOT use
getServerSideProps/getStaticProps— these are Pages Router only. - Do NOT import from
antd/lib/...— useantdorantd/es/...only. - Do NOT use
<Image>withlayoutprop — usewidth/heightorfill(Next.js 16 Image API). - Do NOT add
"use server"to files that don't contain Server Actions. - Do NOT create barrel files (
index.tsre-exports) — import directly from the source module.