From da0212aa5f6cb58175b1a54056ca3648b268c63e Mon Sep 17 00:00:00 2001 From: Naomi Chopra Date: Wed, 12 Nov 2025 17:35:04 -0800 Subject: [PATCH 1/2] feat(assets): add static assets service for RefRef scripts - Introduced a new `assets` application to serve static scripts for attribution tracking and referral widgets via Cloudflare. - Implemented build scripts to copy and prepare assets for deployment, including versioning and checksum generation. - Configured CORS and caching headers for optimal performance in production. - Added comprehensive README documentation for setup, deployment, and usage instructions. - Updated environment variables in the webapp to point to the new assets service. - Created necessary configuration files for TypeScript, Wrangler, and Git ignore settings. - Enhanced the overall project structure to support the new assets service. --- apps/assets/.gitignore | 21 + apps/assets/README.md | 430 +++++++++++++ apps/assets/package.json | 24 + apps/assets/public/_headers | 24 + apps/assets/public/_redirects | 11 + apps/assets/scripts/build.ts | 126 ++++ apps/assets/tsconfig.json | 13 + apps/assets/wrangler.jsonc | 12 + apps/refer/README.md | 251 ++++++++ apps/webapp/.env.example | 8 +- apps/webapp/src/app/layout.tsx | 5 +- apps/webapp/src/env.ts | 5 + pnpm-lock.yaml | 1029 +++++++++++++++++++++++++++----- turbo.json | 2 +- 14 files changed, 1816 insertions(+), 145 deletions(-) create mode 100644 apps/assets/.gitignore create mode 100644 apps/assets/README.md create mode 100644 apps/assets/package.json create mode 100644 apps/assets/public/_headers create mode 100644 apps/assets/public/_redirects create mode 100644 apps/assets/scripts/build.ts create mode 100644 apps/assets/tsconfig.json create mode 100644 apps/assets/wrangler.jsonc create mode 100644 apps/refer/README.md diff --git a/apps/assets/.gitignore b/apps/assets/.gitignore new file mode 100644 index 0000000..49db43b --- /dev/null +++ b/apps/assets/.gitignore @@ -0,0 +1,21 @@ +# Build outputs +dist/ + +# Generated assets (built from packages) +public/*.js +public/*.js.map + +# Keep configuration files +!public/_headers +!public/_redirects + +# Dependencies +node_modules/ + +# TypeScript +*.tsbuildinfo + +# Environment +.env +.env.local +.env.*.local diff --git a/apps/assets/README.md b/apps/assets/README.md new file mode 100644 index 0000000..f4d039a --- /dev/null +++ b/apps/assets/README.md @@ -0,0 +1,430 @@ +# RefRef Assets Service + +Static assets service for serving RefRef scripts (attribution tracking and referral widget) via CDN. + +## Overview + +This app bundles and prepares RefRef scripts for deployment to Cloudflare Workers/Pages as a static site. Scripts are served with proper caching headers and CORS configuration for optimal performance. + +## Production vs Development + +⚠️ **This service is for PRODUCTION deployments only.** + +### Development (apps/refer) +- Use the refer server for local development +- Scripts served dynamically at `http://localhost:3002/scripts/*` +- Hot-reloading and no build step needed +- See [apps/refer/README.md](../refer/README.md) for details + +### Production (apps/assets - this service) +- Deploy to Cloudflare Workers/Pages for CDN delivery +- Scripts served from edge locations worldwide +- Immutable caching for maximum performance +- Version management and cache control +- Lower bandwidth costs and server overhead + +**Key Benefit:** By separating static assets from your application server, you get: +- Faster load times (CDN edge caching) +- Reduced server load (no dynamic script serving) +- Better scalability (Cloudflare's global network) +- Cost efficiency (free tier for static assets) + +## Scripts Available + +- **attribution.v1.js** - Attribution tracking script +- **widget.v1.js** - Referral widget +- **attribution.latest.js** - Alias to latest attribution version +- **widget.latest.js** - Alias to latest widget version + +## Development + +### Prerequisites + +Make sure the required packages are built: + +```bash +# From monorepo root +pnpm -F @refref/attribution-script build +pnpm -F @refref/widget build +``` + +### Build Assets + +```bash +# Build assets (copies bundles to public/) +pnpm -F @refref/assets build + +# Clean generated files +pnpm -F @refref/assets clean +``` + +### Build Output + +The build script will: +1. Copy compiled bundles from packages to `public/` +2. Name them with version suffix (e.g., `attribution.v1.js`) +3. Generate checksums for verification +4. Display build statistics + +## Deployment + +### Quick Deploy with Wrangler CLI + +Deploy directly from your local machine or CI/CD: + +```bash +# Production deployment +pnpm -F @refref/assets deploy:cloudflare + +# Dev/Preview deployment +pnpm -F @refref/assets deploy:cloudflare:dev + +# Local preview with Wrangler +pnpm -F @refref/assets preview +``` + +**First-time setup:** +```bash +# Login to Cloudflare (one-time) +pnpm -F @refref/assets exec wrangler login + +# Then deploy +pnpm -F @refref/assets deploy:cloudflare +``` + +**Deployment Process:** + +The deploy commands automatically: +1. Build the assets (runs `tsx scripts/build.ts`) +2. Copy bundles from packages to `public/` with versioning +3. Deploy `public/` directory to Cloudflare Workers +4. Production deploys to `refref-assets` worker +5. Dev deploys to `refref-assets-dev` worker + +**After Deployment:** + +Your scripts will be available at: +- Production: `https://refref-assets.workers.dev/attribution.v1.js` +- Dev: `https://refref-assets-dev.workers.dev/attribution.v1.js` + +**Custom Domain Setup:** + +After your first deployment: +1. Go to Cloudflare Dashboard → Workers & Pages +2. Select your worker (`refref-assets`) +3. Go to Settings → Domains & Routes +4. Add custom domain: `assets.refref.ai` +5. Cloudflare will automatically provision SSL certificate + +Then update your webapp environment: +```bash +# In apps/webapp/.env (or production environment) +NEXT_PUBLIC_ASSETS_URL="https://assets.refref.ai" +``` + +### Cloudflare Pages Setup (Alternative) + +If you prefer using Cloudflare Pages dashboard instead of Wrangler: + +1. **Connect Repository** + - Go to Cloudflare Pages dashboard + - Create new project from GitHub repo + - Select `refref` repository + +2. **Build Configuration** + ``` + Build command: pnpm -F @refref/assets build + Build output dir: apps/assets/public + Root directory: (leave as repo root) + ``` + +3. **Environment Variables** + - None required (static files only) + +4. **Custom Domain** + - Add custom domain: `assets.refref.ai` + - Configure DNS as instructed by Cloudflare + +### CI/CD Deployment + +Add to your GitHub Actions or CI/CD pipeline: + +```yaml +# .github/workflows/deploy-assets.yml +name: Deploy Assets to Cloudflare + +on: + push: + branches: [main] + paths: + - 'apps/assets/**' + - 'packages/attribution-script/**' + - 'packages/widget/**' + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 10 + + - name: Install dependencies + run: pnpm install + + - name: Build packages + run: | + pnpm -F @refref/attribution-script build + pnpm -F @refref/widget build + + - name: Deploy to Cloudflare + run: pnpm -F @refref/assets deploy:cloudflare + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} +``` + +**Setup:** +1. Create a Cloudflare API Token with Workers Deploy permissions +2. Add as `CLOUDFLARE_API_TOKEN` in GitHub Secrets +3. Push changes to trigger deployment + +### Cloudflare Configuration Files + +- **_headers** - Sets cache control and CORS headers + - Versioned files: 1 year immutable cache + - Latest aliases: 1 hour cache + +- **_redirects** - URL rewrites for latest aliases + - `/attribution.latest.js` → `/attribution.v1.js` + - `/widget.latest.js` → `/widget.v1.js` + +- **wrangler.jsonc** - Wrangler configuration + - Worker name: `refref-assets` + - Assets directory: `./public` + - Dev environment: `refref-assets-dev` + +## Usage + +### In Production + +Use the CDN URLs in your production application: + +```html + + + + + + + + + + + +``` + +**In Next.js (apps/webapp):** + +```typescript +// Configured via NEXT_PUBLIC_ASSETS_URL environment variable +