Frontpage source code for Ruby from AppliedMind.
npm install
npm run dev # http://localhost:3000There are three things to deploy, in this order:
This receives lead submissions and writes them to a Google Sheet.
-
Create a new Google Sheet
- Rename the first tab to Leads
- Add headers in row 1:
Timestamp | Email | Website | Source | IP | Country | City | Region | Device Type | User Agent | Language | Referrer | UTM Source | UTM Medium | UTM Campaign | Full JSON - Copy the spreadsheet ID from the URL:
https://docs.google.com/spreadsheets/d/{SHEET_ID}/edit
-
Go to script.google.com → New project
- Replace the default
Code.gswith the contents ofappscript/Code.gs - Go to Project Settings → check "Show appsscript.json manifest file in editor"
- Replace the contents of
appsscript.jsonwithappscript/appsscript.json
- Replace the default
-
Set script properties
- Project Settings → Script Properties → Add property (add both)
SHEET_ID— your spreadsheet ID from step 1NOTIFY_EMAILS— comma-separated list of addresses to notify on each signup (e.g.alice@example.com,bob@example.com). Leave unset to disable notifications.
-
Deploy the script as a web app
- Deploy → New deployment
- Type: Web app
- Execute as: Me
- Who has access: Anyone
- Click Deploy, authorize when prompted (grant both Sheets and Mail permissions)
- Copy the web app URL — you'll need it in Step 2
Each signup sends a notification email to every address listed in
NOTIFY_EMAILSwith the lead's email, website, location, and device type.
This is the API endpoint that the website POSTs to. It validates input, enriches with Cloudflare geolocation data, and forwards to the Apps Script.
Prerequisites: Cloudflare account with appliedmind.ai domain added.
-
Install dependencies
cd worker npm install -
Log in to Cloudflare
npx wrangler login
-
Set the Apps Script URL as a secret
npx wrangler secret put APPS_SCRIPT_URL # Paste the web app URL from Step 1.4 -
Deploy the worker
npx wrangler deploy
-
Verify it's working
curl -X POST https://subscribe.appliedmind.ai \ -H 'Content-Type: application/json' \ -d '{"email":"test@example.com","source":"test"}' # Should return: {"ok":true}
-
Check your Google Sheet — you should see a new row with the test data.
The static site built with Vite + React.
-
Build the site
# From the project root (not worker/) npm install npm run buildThis outputs to
dist/withindex.html,privacy.html,support.html, andterms.html. -
Deploy
dist/to your hosting provider. Options:- Cloudflare Pages: Connect the repo in the Cloudflare dashboard, set build command to
npm run buildand output directory todist - Manual upload: Upload the
dist/folder via Cloudflare Pages → Direct Upload - Any static host: The
dist/folder is self-contained static files
- Cloudflare Pages: Connect the repo in the Cloudflare dashboard, set build command to
-
Verify the full flow
- Visit
https://ruby.appliedmind.ai - Enter an email in the CTA form and click "Try It Now"
- Check the Google Sheet for the new lead with all enriched data
- Visit
ruby-frontpage-source/
├── components/
│ ├── LandingPage.tsx # Main landing page with all sections & animations
│ ├── Privacy.tsx # Privacy policy page
│ ├── Support.tsx # Support/FAQ page
│ └── Terms.tsx # Terms of service page
├── worker/ # Cloudflare Worker (subscribe.appliedmind.ai)
│ ├── src/index.ts # Worker: CORS, validation, CF geo enrichment, forwarding
│ ├── wrangler.toml # Wrangler config with custom domain route
│ ├── package.json # Worker dependencies
│ └── tsconfig.json # Worker TypeScript config
├── appscript/ # Google Apps Script (lead storage)
│ ├── Code.gs # doPost handler → appends to Sheet + sends email notification
│ ├── appsscript.json # Manifest with Sheets + Mail scopes
│ └── README.md # Detailed setup instructions
├── public/
│ ├── robots.txt
│ └── sitemap.xml
├── App.tsx # Root component with URL-based routing
├── index.tsx # Entry point
├── index.html # HTML template with SEO metadata
├── index.css # Tailwind imports + base styles
├── vite.config.ts # Vite config with HTML copy plugin
├── tsconfig.json # TypeScript configuration
├── tailwind.config.js # Tailwind CSS configuration
└── postcss.config.js # PostCSS configuration