@@ -4,74 +4,85 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44
55## Project Overview
66
7- ** CodeHelp** is a Gatsby v4 -based static site generator serving as a community-driven resource portal (codehelp.io). It aggregates curated links for developers, designers, and marketers across learning materials and development tools.
7+ ** CodeHelp** is an Astro -based static site serving as a community-driven resource portal (codehelp.io). It aggregates curated links for developers, designers, and marketers across learning materials and development tools.
88
9- - ** Framework** : Gatsby v4.5.2
10- - ** Language** : JavaScript/React v17
11- - ** Styling** : styled-components (CSS-in-JS)
12- - ** Deployment** : Netlify (automatic on git push)
13- - ** State Management** : React Context API (theme/dark mode)
9+ - ** Framework** : Astro 5 with React 18 integration
10+ - ** Language** : JavaScript/JSX (Astro components + React islands)
11+ - ** Styling** : CSS (global) + styled-components (legacy page styles)
12+ - ** State Management** : nanostores (theme/dark mode)
13+ - ** Deployment** : Netlify (automatic on git push to master)
14+ - ** Node** : v20+ (set in ` .nvmrc ` and ` netlify.toml ` )
1415
1516## Common Development Commands
1617
1718| Command | Purpose |
1819| ---------| ---------|
19- | ` npm start ` or ` npm run develop ` | Start dev server on localhost:8000 with hot reload |
20- | ` npm run build ` | Build production-optimized site to ` /public ` |
21- | ` npm run serve ` | Serve the built site locally for testing |
22- | ` npm run clean ` | Clear Gatsby cache and build artifacts |
20+ | ` npm run dev ` | Start Astro dev server on localhost:4321 with hot reload |
21+ | ` npm run build ` | Build production site to ` /dist ` |
22+ | ` npm run preview ` | Serve the built site locally for testing |
23+ | ` npm run clean ` | Remove ` dist ` and ` .astro ` cache directories |
2324| ` npm run format ` | Format all code with Prettier (2-space, single quotes) |
24- | ` npm run test ` | Currently not implemented—echo stub only |
2525
2626## Architecture & Code Structure
2727
2828### Directory Layout
2929
3030```
3131src/
32- ├── pages/ # File-based routing (auto-creates routes)
33- │ ├── index.js # Homepage (/)
34- │ ├── learning.js # /learning resources page
35- │ ├── resources.js # /resources development tools page
36- │ └── 404.js # Not found page
32+ ├── pages/ # File-based routing (Astro auto-creates routes)
33+ │ ├── index.astro # Homepage (/)
34+ │ ├── learning.astro # /learning resources page
35+ │ ├── resources.astro # /resources development tools page
36+ │ └── 404.astro # Not found page
3737│
38- ├── components/ # Reusable React components
39- │ ├── Layout.js # Main wrapper (contains globalContext Provider via gatsby-browser.js)
40- │ ├── Header/ # Logo and navigation
41- │ ├── Nav/ # Main nav links + Discord popup modal
42- │ ├── Footer/ # Footer with links
43- │ ├── Sidebar/ # Category navigation with anchor links
44- │ ├── DataList/ # Maps data array → Resource cards
45- │ ├── Resource/ # Individual resource card component
46- │ ├── ThemeToggle/ # Dark/light mode switcher
47- │ └── Seo.js # react-helmet wrapper for head management
38+ ├── layouts/
39+ │ └── Layout.astro # Main HTML wrapper (head, analytics, theme script)
4840│
49- ├── context/ # React Context for state
50- │ └── globalContext.js # Theme state (dark/light), persists to localStorage
41+ ├── components/ # Reusable components (dual Astro + JSX pattern)
42+ │ ├── Header/ # Logo and navigation (.astro + .jsx)
43+ │ ├── Nav/ # Main nav links + Discord popup modal (.jsx only)
44+ │ ├── Footer/ # Footer with links (.astro + .jsx)
45+ │ ├── Sidebar/ # Category navigation with anchor links (.astro + .jsx)
46+ │ ├── DataList/ # Maps data array -> Resource cards (.astro + .jsx)
47+ │ ├── Resource/ # Individual resource card (.astro + .jsx)
48+ │ ├── PageTitle/ # Page heading component (.astro + .jsx)
49+ │ └── ThemeToggle/ # Dark/light mode switcher (.jsx only)
5150│
52- ├── hooks/
53- │ └── useWindowSize.js # Track window dimensions for responsive design
51+ ├── stores/
52+ │ └── themeStore.js # nanostores atom for theme state, syncs to localStorage
53+ │
54+ ├── utils/
55+ │ └── theme-script.js # Inline script to prevent FOUC on page load
5456│
5557├── data/ # Static JSON data (no database)
56- │ ├── resources.json # Development tools/frameworks organized by category
57- │ └── learning.json # Learning materials organized by category
58+ │ ├── resources.json # Development tools/frameworks organized by category
59+ │ └── learning.json # Learning materials organized by category
5860│
59- ├── assets / # Static files
60- │ ├── styles/ # Global + component-level styles
61- │ ├── fonts/ # Custom fonts (Apercu-Mono-Pro)
62- │ └── images/ # PNG, SVG assets
61+ ├── styles / # Global CSS
62+ │ ├── global.css # Theme variables, layout, typography
63+ │ ├── normalize.css # CSS reset
64+ │ └── fonts.css # Custom font declarations (Apercu Mono Pro)
6365│
64- └── pages/ + components/ → Rendered via Layout wrapper → Theme provider
66+ └── assets/ # Static files
67+ ├── styles/ # Legacy styled-components page styles
68+ ├── fonts/ # Custom font files (.woff, .woff2)
69+ └── images/ # PNG, SVG assets
6570```
6671
72+ ### Component Pattern
73+
74+ Most components have dual implementations:
75+ - ` .component.astro ` — server-rendered Astro component (preferred for static content)
76+ - ` .component.jsx ` — React component (used for interactive islands like Nav, ThemeToggle)
77+
6778### Data Flow & Structure
6879
6980** Page rendering** :
70- 1 . Pages (` resources.js ` , ` learning.js ` ) import static JSON from ` src/data/ `
81+ 1 . Pages (` .astro ` ) import static JSON from ` src/data/ `
71822 . Pass data to ` Sidebar ` (category filters) and ` DataList ` (resource cards)
72833 . Sidebar renders anchor links for category navigation
73- 4 . DataList maps array → Resource components (individual cards)
74- 5 . All styled with styled-components, theme-aware via Context
84+ 4 . DataList maps array -> Resource components (individual cards)
85+ 5 . Layout.astro wraps all pages with head metadata, analytics, and theme initialization
7586
7687** Data shape** (JSON structure):
7788``` javascript
@@ -104,107 +115,99 @@ src/
104115
105116### Styling Architecture
106117
107- - ** CSS-in-JS** via styled-components
108- - ** Theme variables** defined in ` src/assets/styles/ ` (e.g., ` --color__background ` , ` --color__text ` )
109- - ** Global styles** wrap all components with theme-aware colors
110- - ** Component styles** : Each component has a ` .styles.js ` file (e.g., ` Header.styles.js ` )
111- - ** Responsive design** : CSS media queries in component styles
118+ - ** Global CSS** in ` src/styles/global.css ` with CSS custom properties (` --color__background ` , ` --color__text ` , etc.)
119+ - ** Theme** controlled via ` data-theme ` attribute on ` <html> ` element
120+ - ** Legacy styled-components** in ` src/assets/styles/pages/ ` for page-level styles
121+ - ** Responsive design** : CSS media queries
112122
113123### State Management
114124
115- ** Global Theme** :
116- - Stored in ` src/context/globalContext .js ` (React Context)
117- - Wrapped around entire app in ` gatsby-browser.js `
118- - Persists theme choice to localStorage
119- - Switch via ThemeToggle component
125+ ** Theme (nanostores) ** :
126+ - Defined in ` src/stores/themeStore .js ` using nanostores ` atom `
127+ - Persists to localStorage, syncs to ` document.documentElement.dataset.theme `
128+ - React components access via ` @nanostores/react ` ( ` useStore ` )
129+ - FOUC prevention via inline script in Layout.astro ( ` src/utils/theme-script.js ` )
120130
121- ### Key Plugins & Features
131+ ### Integrations (astro.config.mjs)
122132
123- | Plugin | Purpose |
124- | --------| ---------|
125- | gatsby-plugin-google-analytics | Google Analytics tracking (trackEvent on Discord clicks) |
126- | gatsby-plugin-image/sharp | Optimized image handling and processing |
127- | gatsby-plugin-styled-components | styled-components integration |
128- | gatsby-plugin-anchor-links | Smooth anchor navigation for sidebar categories |
129- | gatsby-plugin-manifest | PWA manifest for installability |
130- | gatsby-plugin-offline | Service worker for offline PWA support |
131- | gatsby-plugin-react-helmet | Head tag management via react-helmet |
133+ | Integration | Purpose |
134+ | -------------| ---------|
135+ | ` @astrojs/react ` | React component islands |
136+ | ` @astrojs/sitemap ` | Auto-generated sitemap.xml |
137+ | ` @astrojs/partytown ` | Google Analytics in web worker (off main thread) |
132138
133139## Important Config Files
134140
135141| File | Notes |
136142| ------| -------|
137- | ` gatsby- config.js ` | Plugin setup , site metadata, Google Analytics ID, PWA manifest |
138- | ` gatsby-browser.js ` | Wraps app with globalContext Provider for theme state |
143+ | ` astro. config.mjs ` | Integrations , site URL, image service, static output |
144+ | ` .nvmrc ` | Node version (v20) |
139145| ` .prettierrc ` | Enforce 2-space indentation, single quotes, no semicolons, trailing commas |
140- | ` .eslintrc ` | Airbnb config + React/JSX/a11y plugins |
141- | ` netlify.toml ` | Netlify deployment (auto-builds on git push) |
142- | ` .env.development/.env.production ` | Google Analytics ID (GOOGLE_ANALYTICS_ID ) |
146+ | ` .eslintrc ` | ESLint configuration |
147+ | ` netlify.toml ` | Build command, publish dir ( ` dist ` ), Node version, redirects |
148+ | ` .env.development/.env.production ` | Google Analytics ID (` PUBLIC_GA_ID ` ) |
143149
144150## Code Patterns & Conventions
145151
146152### Component Structure
147- - Functional components with hooks
148- - styled-components for component styles
149- - PropTypes for prop validation
150- - File structure: ` ComponentName.js ` + ` ComponentName.styles.js `
153+ - Astro components for static content, React for interactivity
154+ - styled-components for legacy page styles (in ` src/assets/styles/pages/ ` )
155+ - File naming: ` ComponentName.component.astro ` / ` ComponentName.component.jsx `
151156
152157### Comments
153158
154159- Always use ** lowercase** unless referencing case-sensitive items (component names, file paths, variable names, etc.)
155160- Write comments declaratively and directly, like a commit message
156161- Focus on the "why" rather than obvious "what"
157162- Examples:
158- - ✓ ` // toggle dark mode theme in localStorage `
159- - ✗ ` // This toggles the dark mode theme in localStorage `
160- - ✓ ` // map categories to sidebar navigation links `
161- - ✗ ` // Map categories to sidebar navigation links `
163+ - ` // toggle dark mode theme in localStorage `
164+ - ` // map categories to sidebar navigation links `
162165
163166### Adding a New Resource/Learning Item
1641671 . Edit ` src/data/resources.json ` or ` src/data/learning.json `
1651682 . Follow existing category/resource structure
166- 3 . Run ` npm start ` to see changes (hot reload works)
167- 4 . No build or deployment needed for local testing
169+ 3 . Run ` npm run dev ` to see changes (hot reload works)
168170
169171### Adding a New Page
170- 1 . Create ` .js ` file in ` src/pages/ ` (Gatsby auto-routes)
171- 2 . Export React component with Layout wrapper
172- 3 . Use Seo component for head metadata
173- 4 . Styling via styled-components
172+ 1 . Create ` .astro ` file in ` src/pages/ ` (Astro auto-routes by filename)
173+ 2 . Import and use ` Layout.astro ` as the wrapper
174+ 3 . Pass ` title ` and ` description ` props to Layout for head metadata
174175
175176### Theme-Aware Styling
176- ``` javascript
177- import { useContext } from ' react'
178- import { GlobalContext } from ' ../context/globalContext'
177+ ``` css
178+ /* use CSS custom properties that change with data-theme */
179+ .my-element {
180+ background : var (--color__background );
181+ color : var (--color__text );
182+ }
183+ ```
179184
180- const MyComponent = () => {
181- const { theme } = useContext (GlobalContext)
185+ ``` jsx
186+ // react components can read theme from nanostores
187+ import { useStore } from ' @nanostores/react'
188+ import { themeStore } from ' ../stores/themeStore'
182189
183- return styled .div `
184- background: var(--color__background);
185- color: var(--color__text);
186- `
190+ const MyComponent = () => {
191+ const theme = useStore (themeStore)
192+ // ...
187193}
188194```
189195
190196## Deployment & Build Process
191197
192- - ** Dev** : ` npm start ` → localhost:8000
193- - ** Production** : ` npm run build ` → outputs ` /public/ ` with optimized assets
194- - ** Netlify** : Auto-detects gatsby-config.js, builds and deploys on git push to master
198+ - ** Dev** : ` npm run dev ` -> localhost:4321
199+ - ** Production** : ` npm run build ` -> outputs ` /dist ` with static assets
200+ - ** Netlify** : Builds and deploys on git push to master
195201- ** Live site** : https://codehelp.io
196202
197203## Linting & Formatting
198204
199- - ** ESLint** : Airbnb config enforces style rules
205+ - ** ESLint** : Configured via ` .eslintrc `
200206- ** Prettier** : Auto-format with ` npm run format `
201- - Pre-commit hooks: None currently configured (consider adding)
202207
203- ## Notes for Future Development
208+ ## Notes
204209
205- - Data is static JSON—no database or API backend
206- - Theme switching is client-side only (Context + localStorage)
207- - Analytics tracked on Discord link clicks (see Nav component)
208- - Accessibility plugins enabled (jsx-a11y, manifest)
209- - PWA support enabled (installable, offline fallback)
210- - No automated tests currently—test suite commented in package.json
210+ - Data is static JSON — no database or API backend
211+ - Theme switching is client-side only (nanostores + localStorage)
212+ - Analytics via Google Analytics loaded through Partytown (web worker)
213+ - Static output mode (` output: 'static' ` in astro.config.mjs)
0 commit comments