Skip to content

Commit b593a77

Browse files
committed
Remove remaining Gatsby references, fix Netlify build
Update .nvmrc to Node v20 (was v14.17.1, incompatible with Astro 5). Remove .gatsby-image-wrapper CSS selector from Index.styles.js. Rewrite CLAUDE.md, README.md for Astro. Fix LICENSE copyright.
1 parent f4fb430 commit b593a77

File tree

5 files changed

+113
-122
lines changed

5 files changed

+113
-122
lines changed

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v14.17.1
1+
v20

CLAUDE.md

Lines changed: 103 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -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
```
3131
src/
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/`
7182
2. Pass data to `Sidebar` (category filters) and `DataList` (resource cards)
7283
3. 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
164167
1. Edit `src/data/resources.json` or `src/data/learning.json`
165168
2. 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)

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The BSD Zero Clause License (0BSD)
22

3-
Copyright (c) 2020 Gatsby Inc.
3+
Copyright (c) 2020 Tom Gooden
44

55
Permission to use, copy, modify, and/or distribute this software for any
66
purpose with or without fee is hereby granted.

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Netlify Status](https://api.netlify.com/api/v1/badges/9e534487-a699-4fac-b2c8-c4d607915ec2/deploy-status)](https://app.netlify.com/sites/infallible-haibt-f24d3a/deploys)
22

3-
# 🤖 CodeHelp Website
3+
# CodeHelp Website
44

55
## About
66

@@ -9,20 +9,21 @@ The official repository for [CodeHelp.io](https://codehelp.io). This will be a c
99
## Dependencies
1010

1111
- NPM
12-
- Gatsby CLI
12+
- Node.js v20+
1313

1414
## Setup
1515

1616
1. Clone the repository. Run `git clone https://github.com/good3n/codehelp.git`
1717
2. Navigate to repository via `cd codehelp` and install the node packages with `npm install`
18-
3. Start the Gatsby development environment with `gatsby develop`
19-
4. Open your browser and go to `localhost:8000`
20-
5. Happy coding 🤖
18+
3. Start the Astro development server with `npm run dev`
19+
4. Open your browser and go to `localhost:4321`
20+
5. Happy coding
2121

2222
## Structure
2323

24-
- All pages are inside of the `pages/` directory.
25-
- All components are inside of the `components/` directory.
24+
- All pages are inside of the `src/pages/` directory.
25+
- All components are inside of the `src/components/` directory.
26+
- All data is inside of the `src/data/` directory.
2627

2728
## Pull request guidelines
2829

src/assets/styles/pages/Index.styles.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,6 @@ export const StyledHome = styled.div`
99
display: inline-flex;
1010
}
1111
12-
.gatsby-image-wrapper {
13-
position: absolute;
14-
top: 0;
15-
right: -85px;
16-
transform: rotate(13deg);
17-
18-
@media (max-width: 991px) {
19-
max-width: 9vw;
20-
top: 3%;
21-
right: -13%;
22-
}
23-
}
24-
2512
h1 {
2613
font-size: var(--font-size__h0);
2714
color: var(--color__green);

0 commit comments

Comments
 (0)