Skip to content

Latest commit

 

History

History
73 lines (55 loc) · 3.92 KB

File metadata and controls

73 lines (55 loc) · 3.92 KB

DaveGoosem.com — Claude Code Context

Stack

  • Framework: Next.js 14 (App Router), TypeScript
  • Content: Contentlayer2 — MDX files in data/blog/ and data/authors/
  • Styles: Tailwind CSS 3 (class-based dark mode, Space Grotesk font)
  • Deployment: Vercel
  • Package manager: npm
  • Comments: Giscus (GitHub Discussions), configured via env vars
  • Search: kbar (local public/search.json, regenerated on build)
  • Analytics: Google Analytics via Pliny

Key Commands

npm run dev       # start dev server
npm run build     # production build + postbuild (RSS, search index)
npm run lint      # ESLint with auto-fix

Path Aliases (tsconfig.json)

Alias Resolves to
@/components/* components/*
@/data/* data/*
@/layouts/* layouts/*
@/css/* css/*
contentlayer/generated .contentlayer/generated

Key Directories

Path Purpose
app/ Next.js App Router pages
components/ Shared React components
layouts/ Blog post layout templates
data/blog/ MDX blog posts (41 posts)
data/authors/ Author MDX profiles
data/siteMetadata.js Site-wide config (title, URL, socials)
public/static/images/ Static image assets
scripts/ postbuild.mjs (RSS + search index)

SEO & Structured Data

The following are already implemented — do not duplicate or replace them:

  • Canonical URLs — set in generateMetadata() in app/blog/[...slug]/page.tsx via post.canonicalUrl ?? computed URL
  • BlogPosting JSON-LD — generated by Contentlayer in contentlayer.config.ts (includes publisher, mainEntityOfPage, author). Injected in app/blog/[...slug]/page.tsx
  • BreadcrumbList JSON-LD — injected alongside BlogPosting in app/blog/[...slug]/page.tsx
  • WebSite JSON-LD — injected in app/layout.tsx (covers all pages)
  • Publisher logo — uses DaveGoosem.com_Logo_Black.png (not the white variant) so it is legible on white backgrounds as Google requires
  • Sitemapapp/sitemap.ts, auto-generated, excludes drafts
  • Robotsapp/robots.ts, auto-generated

Constraints

  • Do not add API routes — this is a static/SSG blog with no backend
  • Do not add a database or server-side state
  • Contentlayer2 auto-generates TypeScript types on npm run build / npm run dev — do not edit .contentlayer/ manually
  • ESLint uses flat config (eslint.config.mjs) — not .eslintrc
  • External links require target="_blank" and rel="noopener noreferrer" (enforced by ESLint)

Gotchas

Contentlayer scans all of data/ — any plain .md file placed inside data/ (e.g. a CLAUDE.md) must be added to contentDirExclude in contentlayer.config.tsmakeSource(), otherwise Contentlayer warns and skips it at startup.

Content Security Policynext.config.js contains a hand-written CSP string. If you add any external script, font, frame, or image source (e.g. a new analytics provider, embed, or CDN), add its hostname to the appropriate CSP directive in that file or the browser will silently block it.

Remote imagesnext/image only proxies domains listed in next.config.jsimages.remotePatterns. Currently only picsum.photos is allowed. Add new domains there before using external image URLs in posts or components.

Bundle analysis — run ANALYZE=true npm run build to open the webpack bundle visualiser. Useful before committing large new dependencies.