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 with App Router
- UI Library: React 19
- Language: TypeScript
- Styling: Tailwind CSS v4 with CSS variables
- Components: shadcn/ui (Radix UI primitives)
- Deployment: Cloudflare Workers
- Bridge: OpenNext Cloudflare
- Icons: Lucide React
- Forms: React Hook Form + Zod
- Analytics: Vercel Web 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
- Clone the repository:
git clone <repository-url>
cd high-performance-structures
- Install dependencies:
pnpm install
- Start the development server:
pnpm dev
- Open http://localhost:3000 in your browser.
The page will automatically reload when you make changes to the code.
📜 Available Scripts
Development
pnpm dev # Start Next.js dev server (http://localhost:3000)
pnpm lint # Run ESLint code quality checks
Build & Deployment
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
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 Cloudflareworker.js- Cloudflare Worker entry pointassets/- Static files for edge serving
⚙️ Configuration
TypeScript Path Aliases
The project uses path aliases for cleaner imports:
{
"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:
@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
- Create directory under
app/(e.g.,app/new-page/) - Add
page.tsxfile with default export component:
export default function NewPage() {
return <div>New Page Content</div>
}
- Optionally create
layout.tsxfor page-specific layout - Import
SiteHeaderandSiteFooterfor consistent layout
Adding UI Components
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
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:
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_compatflag - Static assets binding:
ASSETS→.open-next/assets - Observability: Enabled
Deployment Process
Important: Follow these steps in order:
- Build for Cloudflare:
npx @opennextjs/cloudflare build
- Deploy to Cloudflare:
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:
wrangler logout
wrangler login
Local Preview
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:
wrangler secret put MY_SECRET
📚 Additional Resources
Documentation
- Next.js Documentation
- OpenNext Cloudflare
- Tailwind CSS v4
- shadcn/ui
- Cloudflare Workers
- React Hook Form
- Zod
Related Tools
- Radix UI - Unstyled, accessible component primitives
- Lucide Icons - Beautiful icon library
- Vercel 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.0required (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