← Home
Architecture

How this site is built.

Eight diagrams.

Page structure, navigation, content pipeline, SEO, CI/CD, component hierarchy, the public skills library, and the client-state layer. The canonical reference for how arkashj.com is built.

01

Site map

Top-level routes served by the App Router.

#

Page tree

/
/about
/research
/projects
/work
/writing
/media
/knowledge
/architecture
/stack
03

Content pipeline

MDX files in /content are loaded, parsed, and rendered as static pages.

#

MDX → loader → static pages

Source

content/writing/*.mdx (with originalDomain)

Loader

lib/content.ts
gray-matter + serialize

Output

app/[route]/page.tsx
generateStaticParams()
/sitemap.xml
04

SEO pipeline

Metadata, OG images, and JSON-LD layered onto every route.

#

Per-page metadata layers

Every page

app/[route]/page.tsx

generateMetadata()

title · description · canonical

opengraph-image

OG · Twitter card

<JsonLd> Person

global identity

Article JSON-LD

/writing · /knowledge

ScholarlyArticle

/research papers

<link rel="me">

identity verification

05

CI/CD pipeline

From local commit through GitHub Actions to a Vercel deploy.

#

Local → remote → deploy

01

git commit

local

02

husky pre-commit

lint-staged · prettier

03

git push

origin

04

GitHub Actions

lint · format:check · build

05

Vercel deploy

preview / prod

06

Component hierarchy

How layout, sections, UI primitives, and embeds compose the page tree.

#

Layout · sections · UI · embeds

app/layout.tsx
├─ <Providers> (QueryClient)
└─ <ThemeProvider>
├─ <Nav>
└─ sticky · active-route highlight
├─ <main>{children}</main>
└─ <Footer>
└─ site map · social
└─ <JsonLd> Person
components/sections/
├─ <Hero>
├─ <PaperCard>
├─ <ProjectCard>
├─ <ExperienceCard>
├─ <TimelineItem>
├─ <ThesisTracker>
└─ <TradeLog>
components/ui/
├─ <Button>
├─ <Card>
├─ <Badge>
└─ <StatBadge>
components/embeds/
├─ <MdxContent>
├─ <JsonLd>
└─ react-tweet
07

Client state — Zustand + TanStack Query

Two narrow client-state layers wrapped around a server-rendered app: Zustand for transient UI flags, TanStack Query for server-action lifecycle.

#

Provider chain · Zustand store · TanStack Query consumers

Provider chain

<html>
<Providers> (QueryClient)
<ThemeProvider>
app surface

Zustand · lib/store.ts

useUiStore

└─ paletteOpen (cmdk)

└─ mobileNavOpen

└─ modalId · modalPayload

Consumers

components/layout/Nav.tsx
components/ui/CommandPalette.tsx

TanStack Query · app/providers.tsx

QueryClient

└─ staleTime 60s · gcTime 5m

└─ retry 1 · no refetch on focus

└─ mutations: retry 0

Consumers

available for future server-action consumers

Client state lives in two narrow layers. Zustand owns transient UI flags (palette, mobile nav, modal); TanStack Query owns server-action lifecycle (loading · error · success). Both providers mount once in `app/layout.tsx` and stay invisible to server components.

Almost the entire site is server-rendered. The two client-state layers live inside the provider chain mounted by app/layout.tsx: Providers (QueryClient) ThemeProvider. A single Zustand store (useUiStore) owns the cmdk palette, mobile nav, and a generic modal slot — consumed by Nav and CommandPalette.

08

Skills library

71 Claude Code skills served from flat markdown files via /skills, /skills/[slug], /skills/[slug]/raw, and /skills.json.

#

File-based content → server-rendered list → static raw + JSON endpoints

Source

content/skills/*.md
71 markdown files

Loader

lib/skills.ts
fs + gray-matter
category rules (regex)

Surfaces

/skills (list)
/skills/[slug] (detail)
/skills/[slug]/raw (text/plain)
/skills.json (index)

Each skill is a flat .md file. The loader runs once per request on the server, categorizes by filename regex, and feeds three render paths: a categorized list page, a per-skill detail page with a Copy-for-LLM button, and two machine-readable endpoints (`/raw` plain text + `/skills.json` index) designed to be curl-able by other agents.