364 lines
10 KiB
Markdown
364 lines
10 KiB
Markdown
# High Performance Structures Website
|
|
|
|
A modern, high-performance website for High Performance Structures - a Colorado-based company specializing in Insulating Concrete Form (ICF) construction services. Built with Next.js 16 and deployed to Cloudflare Workers for global edge distribution.
|
|
|
|
## 🚀 Tech Stack
|
|
|
|
- **Framework:** [Next.js 16](https://nextjs.org/) with App Router
|
|
- **UI Library:** [React 19](https://react.dev/)
|
|
- **Language:** [TypeScript](https://www.typescriptlang.org/)
|
|
- **Styling:** [Tailwind CSS v4](https://tailwindcss.com/) with CSS variables
|
|
- **Components:** [shadcn/ui](https://ui.shadcn.com/) (Radix UI primitives)
|
|
- **Deployment:** [Cloudflare Workers](https://developers.cloudflare.com/workers/)
|
|
- **Bridge:** [OpenNext Cloudflare](https://opennext.js.org/cloudflare)
|
|
- **Icons:** [Lucide React](https://lucide.dev/)
|
|
- **Forms:** [React Hook Form](https://react-hook-form.com/) + [Zod](https://zod.dev/)
|
|
- **Analytics:** [Vercel Web Analytics](https://vercel.com/analytics)
|
|
|
|
## ✨ Features
|
|
|
|
- **Responsive Design** - Mobile-first approach with optimized layouts for all screen sizes
|
|
- **Modern UI** - Clean, professional interface built with shadcn/ui components
|
|
- **Server-Side Rendering** - SSR/SSG capabilities for optimal performance and SEO
|
|
- **Edge Deployment** - Global distribution via Cloudflare's edge network
|
|
- **Blog System** - Dynamic blog post pages with markdown support
|
|
- **Contact Forms** - Validated contact forms with React Hook Form and Zod
|
|
- **Service Showcases** - Dedicated pages for ICF services, training, and resources
|
|
- **Performance Optimized** - Fast page loads with optimized images and static assets
|
|
|
|
## 📋 Prerequisites
|
|
|
|
- **Node.js** 18.x or higher
|
|
- **pnpm** (package manager) - Install with `npm install -g pnpm`
|
|
- **Cloudflare Account** (for deployment)
|
|
|
|
## 🛠️ Getting Started
|
|
|
|
### Installation
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone <repository-url>
|
|
cd high-performance-structures
|
|
```
|
|
|
|
2. Install dependencies:
|
|
```bash
|
|
pnpm install
|
|
```
|
|
|
|
3. Start the development server:
|
|
```bash
|
|
pnpm dev
|
|
```
|
|
|
|
4. Open [http://localhost:3000](http://localhost:3000) in your browser.
|
|
|
|
The page will automatically reload when you make changes to the code.
|
|
|
|
## 📜 Available Scripts
|
|
|
|
### Development
|
|
|
|
```bash
|
|
pnpm dev # Start Next.js dev server (http://localhost:3000)
|
|
pnpm lint # Run ESLint code quality checks
|
|
```
|
|
|
|
### Build & Deployment
|
|
|
|
```bash
|
|
pnpm build # Create production build (.next/ and .open-next/ outputs)
|
|
pnpm start # Start production server locally
|
|
pnpm preview # Test on Cloudflare Workers runtime locally
|
|
pnpm deploy # Deploy to Cloudflare Workers (requires authentication)
|
|
```
|
|
|
|
### Component Management
|
|
|
|
```bash
|
|
npx shadcn-ui@latest add [component-name] # Add shadcn/ui component
|
|
```
|
|
|
|
## 📁 Project Structure
|
|
|
|
```
|
|
high-performance-structures/
|
|
├── app/ # Next.js App Router pages
|
|
│ ├── page.tsx # Home page
|
|
│ ├── layout.tsx # Root layout with metadata
|
|
│ ├── globals.css # Global styles and Tailwind config
|
|
│ ├── blog/ # Blog pages
|
|
│ │ ├── page.tsx # Blog listing
|
|
│ │ └── [slug]/ # Dynamic blog post pages
|
|
│ ├── services/ # Services page
|
|
│ ├── contact/ # Contact page
|
|
│ └── resources/ # Resources page
|
|
├── components/ # React components
|
|
│ ├── ui/ # shadcn/ui components (30+ components)
|
|
│ ├── site-header.tsx # Site header with navigation
|
|
│ ├── site-footer.tsx # Site footer
|
|
│ └── hps-logo.tsx # Brand logo component
|
|
├── lib/ # Utilities
|
|
│ └── utils.ts # cn() function for merging Tailwind classes
|
|
├── hooks/ # Custom React hooks
|
|
│ ├── use-toast.ts # Toast notifications
|
|
│ └── use-mobile.ts # Mobile detection
|
|
├── public/ # Static assets
|
|
│ ├── images/ # Image assets
|
|
│ ├── logos/ # Logo files
|
|
│ └── _headers # Cloudflare caching rules
|
|
├── next.config.ts # Next.js configuration
|
|
├── wrangler.jsonc # Cloudflare Workers configuration
|
|
├── open-next.config.ts # OpenNext bridge configuration
|
|
├── tsconfig.json # TypeScript configuration
|
|
└── package.json # Dependencies and scripts
|
|
```
|
|
|
|
## 🏗️ Architecture
|
|
|
|
### High-Level Stack
|
|
|
|
```
|
|
React 19 Components
|
|
↓
|
|
Next.js 16 App Router (SSR/SSG)
|
|
↓
|
|
Cloudflare Workers (via OpenNext bridge)
|
|
↓
|
|
Cloudflare Edge Network (global distribution)
|
|
```
|
|
|
|
### Build Outputs
|
|
|
|
- **`.next/`** - Standard Next.js build output
|
|
- **`.open-next/`** - OpenNext bridge output for Cloudflare
|
|
- `worker.js` - Cloudflare Worker entry point
|
|
- `assets/` - Static files for edge serving
|
|
|
|
## ⚙️ Configuration
|
|
|
|
### TypeScript Path Aliases
|
|
|
|
The project uses path aliases for cleaner imports:
|
|
|
|
```json
|
|
{
|
|
"paths": {
|
|
"@/*": ["./*"]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Import pattern:** `import { Component } from "@/components/Component"`
|
|
|
|
### Tailwind CSS v4
|
|
|
|
The project uses **Tailwind CSS v4** with CSS-only configuration in `app/globals.css`:
|
|
|
|
```css
|
|
@import "tailwindcss";
|
|
|
|
:root {
|
|
--primary-blue: #0066bf;
|
|
--deep-navy: #0f172a;
|
|
--cyan-accent: #8cc63f;
|
|
/* ... more variables ... */
|
|
}
|
|
```
|
|
|
|
**Key Brand Colors:**
|
|
- Deep Navy: `#0f172a` - Primary background
|
|
- Primary Blue: `#0066bf` - Action elements
|
|
- Cyan/Lime Accent: `#8cc63f` - Brand highlight
|
|
|
|
Dark mode is supported via `next-themes` package.
|
|
|
|
### Component Library (shadcn/ui)
|
|
|
|
All UI components use **shadcn/ui** (Radix UI primitives + Tailwind):
|
|
- Location: `components/ui/`
|
|
- Style: New York (modern, clean)
|
|
- Icons: Lucide React
|
|
- Installation: `npx shadcn-ui@latest add [component]`
|
|
- Configuration: `components.json`
|
|
|
|
## 🔧 Development Workflows
|
|
|
|
### Adding a New Page
|
|
|
|
1. Create directory under `app/` (e.g., `app/new-page/`)
|
|
2. Add `page.tsx` file with default export component:
|
|
```typescript
|
|
export default function NewPage() {
|
|
return <div>New Page Content</div>
|
|
}
|
|
```
|
|
3. Optionally create `layout.tsx` for page-specific layout
|
|
4. Import `SiteHeader` and `SiteFooter` for consistent layout
|
|
|
|
### Adding UI Components
|
|
|
|
```bash
|
|
npx shadcn-ui@latest add button
|
|
npx shadcn-ui@latest add card
|
|
npx shadcn-ui@latest add form
|
|
```
|
|
|
|
All components are composable and styled with Tailwind.
|
|
|
|
### Creating Forms
|
|
|
|
```typescript
|
|
import { useForm } from "react-hook-form"
|
|
import { zodResolver } from "@hookform/resolvers/zod"
|
|
import { z } from "zod"
|
|
|
|
const schema = z.object({
|
|
email: z.string().email("Invalid email"),
|
|
message: z.string().min(10),
|
|
})
|
|
|
|
export default function MyForm() {
|
|
const form = useForm({
|
|
resolver: zodResolver(schema),
|
|
})
|
|
// form.register(), form.handleSubmit(), etc.
|
|
}
|
|
```
|
|
|
|
### Dark Mode Implementation
|
|
|
|
Uses `next-themes`:
|
|
|
|
```typescript
|
|
import { useTheme } from "next-themes"
|
|
|
|
const { theme, setTheme } = useTheme()
|
|
```
|
|
|
|
CSS dark mode via `prefers-color-scheme` media query + `.dark` class support.
|
|
|
|
## 🚢 Deployment
|
|
|
|
### Cloudflare Workers Configuration
|
|
|
|
**Wrangler Setup** (`wrangler.jsonc`):
|
|
- Worker entry: `.open-next/worker.js`
|
|
- Compatibility date: `2025-03-01`
|
|
- Node.js compatibility enabled: `nodejs_compat` flag
|
|
- Static assets binding: `ASSETS` → `.open-next/assets`
|
|
- Observability: Enabled
|
|
|
|
### Deployment Process
|
|
|
|
**Important:** Follow these steps in order:
|
|
|
|
1. **Build for Cloudflare:**
|
|
```bash
|
|
npx @opennextjs/cloudflare build
|
|
```
|
|
|
|
2. **Deploy to Cloudflare:**
|
|
```bash
|
|
npx wrangler deploy
|
|
```
|
|
|
|
**Note:** Do NOT skip the build step. Wrangler deploys without this step will push stale assets.
|
|
|
|
### Caching Strategy
|
|
|
|
**Static assets** (in `public/_headers`):
|
|
```
|
|
/_next/static/*
|
|
Cache-Control: public,max-age=31536000,immutable
|
|
```
|
|
|
|
- Cached for 1 year at edge
|
|
- Content hash in filename ensures cache busting
|
|
|
|
### Account Management
|
|
|
|
Cloudflare account is stored in local Wrangler config (`~/.wrangler/config.json`). To switch accounts:
|
|
|
|
```bash
|
|
wrangler logout
|
|
wrangler login
|
|
```
|
|
|
|
### Local Preview
|
|
|
|
```bash
|
|
pnpm preview
|
|
```
|
|
|
|
Simulates Cloudflare Workers runtime locally using Wrangler.
|
|
|
|
## 🔐 Environment Variables
|
|
|
|
### Development
|
|
|
|
- **File:** `.dev.vars` (Git ignored)
|
|
- **Template:** `.dev.vars.example`
|
|
- **Content:** Currently just `NEXTJS_ENV=development`
|
|
|
|
Used by Wrangler for local development. Extend as needed for API keys, secrets, etc.
|
|
|
|
### Production
|
|
|
|
Set environment variables in Cloudflare Dashboard or via Wrangler:
|
|
|
|
```bash
|
|
wrangler secret put MY_SECRET
|
|
```
|
|
|
|
## 📚 Additional Resources
|
|
|
|
### Documentation
|
|
|
|
- [Next.js Documentation](https://nextjs.org/docs)
|
|
- [OpenNext Cloudflare](https://opennext.js.org/cloudflare)
|
|
- [Tailwind CSS v4](https://tailwindcss.com/docs)
|
|
- [shadcn/ui](https://ui.shadcn.com/)
|
|
- [Cloudflare Workers](https://developers.cloudflare.com/workers/)
|
|
- [React Hook Form](https://react-hook-form.com/)
|
|
- [Zod](https://zod.dev/)
|
|
|
|
### Related Tools
|
|
|
|
- [Radix UI](https://www.radix-ui.com/) - Unstyled, accessible component primitives
|
|
- [Lucide Icons](https://lucide.dev/) - Beautiful icon library
|
|
- [Vercel Analytics](https://vercel.com/analytics) - Web analytics
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Module not found errors for `@/lib/utils` or components
|
|
|
|
Ensure files exist in project root at correct paths and `tsconfig.json` path alias points to `"./*"`.
|
|
|
|
### OpenNext Cloudflare for Dev
|
|
|
|
The `initOpenNextCloudflareForDev()` call in `next.config.ts` enables `getCloudflareContext()` usage in `next dev` mode.
|
|
|
|
### React 19 Compatibility
|
|
|
|
- `vaul@^1.0.0` required (not 0.9.x which only supports React 18)
|
|
- All shadcn/ui components tested with React 19
|
|
|
|
### Build Errors
|
|
|
|
- **ESLint config errors during build:** They're informational—build still succeeds, but you should address them separately.
|
|
- **Viewport metadata warning:** Move viewport values from metadata to generateViewport per Next.js docs.
|
|
|
|
## 📝 License
|
|
|
|
Private project - All rights reserved.
|
|
|
|
## 👥 Contact
|
|
|
|
For questions about this project, please contact the development team.
|
|
|
|
---
|
|
|
|
Built with ❤️ using Next.js and Cloudflare Workers
|