Modern React application built with Vike (SSG), deployed to Cloudflare Pages.
- Node.js 18+
- pnpm
- Airtable account with API key
- Stripe account
# Install dependencies
pnpm install
# Copy environment template
cp .env.local.example .env.local
# Edit .env.local and add your API keyspnpm dev # Runs both Vike AND Cloudflare FunctionsVisit http://localhost:8788 (note: wrangler uses port 8788, not 3000)
pnpm buildpnpm preview├── pages/ # Vike pages (SSG)
│ ├── index/ # Homepage
│ ├── funds/ # Donations page
│ ├── jobs/ # Job listings
│ ├── policy/ # Policy page
│ └── projects/ # Project pages
├── components/ # React components
│ ├── ui/ # shadcn/ui components
│ ├── Navigation.tsx # Header navigation
│ └── DonationStats.tsx # Client-side donation stats
├── lib/ # Utilities
│ ├── airtable.ts # Airtable data fetchers
│ ├── stripe-client.ts # Stripe client utilities
│ └── utils.ts # shadcn utils
├── types/ # TypeScript types
│ ├── airtable.ts # Airtable record types
│ └── stripe.ts # Stripe types
├── functions/ # Cloudflare Functions
│ └── api/
│ └── donation-stats.ts # Stripe API proxy
└── public/ # Static assets
├── robots.txt # SEO (disallow all)
└── images/ # Images
- Framework: Vike (SSG mode - pure static site generation)
- UI Library: React 19
- Styling: Tailwind CSS 4
- Components: shadcn/ui
- Icons: Heroicons
- Data: Airtable (build-time fetch)
- Payments: Stripe Buy Buttons
- Deployment: Cloudflare Pages
- Language: TypeScript
Architecture: This is a pure SSG (Static Site Generation) app, not SSR. All pages are pre-rendered at build time into static HTML files. Cloudflare Functions run separately as serverless edge functions for the donation stats API.
- Jobs
- Projects
- Teams/People
- Expenses
- Donation statistics (last 30 days)
- Recent donations
Uses Stripe Buy Buttons for donations:
- Monthly donations:
buy_btn_1STkr7K5E1L5TSuqjuFbdUKO - One-time donations:
buy_btn_1STk1QK5E1L5TSuqNdkTV2km
No server-side Stripe code needed (Buy Buttons handle everything).
The /api/donation-stats endpoint is a Cloudflare Function that:
- Fetches transactions from Stripe API (last 30 days)
- Calculates monthly vs one-time donations
- Returns recent charges with country info
- Called client-side from Funds page
- Connect GitHub repository to Cloudflare Pages
- Build settings:
- Build command:
pnpm build - Build output directory:
dist/client
- Build command:
- Environment variables:
AIRTABLE_KEYAIRTABLE_BASESTRIPE_PUBLISHABLE_KEYSTRIPE_SECRET_KEY(for Function)
# Build the site
pnpm build
# Deploy via wrangler
npx wrangler pages deploy dist/clientThese are used during the build process and embedded into static assets:
AIRTABLE_KEY- Airtable API keyAIRTABLE_BASE- Airtable base IDSTRIPE_PUBLISHABLE_KEY- Stripe publishable key
Copy from .env.local.example to get started.
These are used by Cloudflare Functions at runtime:
STRIPE_SECRET_KEY- Stripe secret key
Important:
.dev.varsis for local development only (gitignored)- In production, set
STRIPE_SECRET_KEYas encrypted secret in Cloudflare dashboard
- Update data in Airtable
- Trigger rebuild:
- Manual: Push to GitHub or trigger deploy hook
- Automated: (Future) Airtable webhook → Cloudflare deploy hook
- Button
- Card
- Badge
- Accordion
- Progress
- Alert
Navigation- Header with linksDonationStats- Real-time donation statistics
This is an internal project for Sahaja Yoga web developers.
For questions: contact@sydevelopers.com
Private - All rights reserved