Building 86dfrom.com: Multi-Region Deployment with Google Apps Script, Vercel, and AWS CloudFront
This post documents the infrastructure and deployment pipeline built for 86dfrom.com, a Bella+Canvas t-shirt e-commerce site integrating Printful, Stripe, and Google Apps Script for order fulfillment. The project demonstrates a hybrid deployment pattern: Next.js 14 on Vercel for the web application, AWS S3 + CloudFront for static asset delivery and domain forwarding, and Google Apps Script for serverless order processing.
Architecture Overview
The 86dfrom.com stack consists of three primary components:
- Primary application: Next.js 14 deployed on Vercel, handling product listing, cart, checkout, and Stripe webhook ingestion
- Static and redirect infrastructure: S3 + CloudFront for the main domain and domain forwarding (86from.com → 86dfrom.com)
- Order fulfillment automation: Google Apps Script in standalone deployment mode, triggered by Stripe webhook events
This architecture decouples concerns: Vercel handles dynamic application logic and scales for traffic spikes, while CloudFront CDN ensures global asset delivery with minimal latency. The Google Apps Script layer provides a lightweight, maintainable serverless option for webhook processing without introducing additional compute infrastructure.
Deployment Pipeline: Local to Production
The project uses a multi-stage deployment pattern:
Stage 1: Local Development
All source files are version-controlled in ~/Documents/repos/sites/86dfrom.com/, with subdirectories for:
site/— Next.js application (index.html for static builds, success.html for Stripe success callback)gas/— Google Apps Script source files (Code.gscontaining webhook handlers,appsscript.jsonwith manifest metadata)scripts/— Deployment automation (deploy.shhandles S3 sync and CloudFront cache invalidation)
Local environment variables are stored in .env.local (not committed), loaded by Next.js at build time. This includes:
- Printful API key for variant lookups
- Stripe publishable and secret keys
- Google Apps Script deployment ID
Stage 2: Vercel Production Deployment
The Next.js application is deployed via:
npx vercel@latest --prod
This command builds the application in Vercel's infrastructure, runs the test suite (a clean compile confirms all 5 API routes compile without error), and promotes the build to the production domain. Environment variables are injected via Vercel's dashboard or CLI, encrypted at rest in Vercel's secret store.
The deployment exports two key outputs:
/api/webhook— Stripe webhook endpoint (HTTPS-only, authenticated via signature verification)- Next.js API routes for product variants and cart operations
Stage 3: Static and Redirect Infrastructure
AWS infrastructure for domain management includes:
- S3 buckets: One per domain (e.g.,
86dfrom.com,86from.com) - ACM certificates: Requested for each domain, validated via DNS CNAME records in Route53
- CloudFront distributions: One for the primary domain (S3 origin), one for each alias/redirect domain
- Route53 hosted zone: Single zone per domain family, managing DNS resolution
For 86dfrom.com (primary domain):
aws s3 mb s3://86dfrom.com --region us-east-1
aws acm request-certificate --domain-name 86dfrom.com --validation-method DNS --region us-east-1
Once the certificate was validated (via DNS CNAME records added to Route53), a CloudFront distribution was created with:
- Origin: S3 bucket endpoint
- CNAME aliases: 86dfrom.com, www.86dfrom.com
- Default root object: index.html
- Cache behavior: CloudFront-managed cache with 24-hour TTL for HTML, aggressive caching for versioned assets
Route53 A record:
Name: 86dfrom.com
Type: A (alias)
Target: CloudFront distribution alias
Evaluate target health: yes
Stage 4: Domain Forwarding
For the secondary domain 86from.com, a CloudFront Function was deployed to redirect all traffic to the primary domain:
function handler(event) {
var request = event.request;
return {
statusCode: 301,
statusDescription: 'Moved Permanently',
headers: {
'location': { value: 'https://86dfrom.com' + request.uri }
}
};
}
This function is attached to the CloudFront distribution for 86from.com, ensuring all variants (www, bare domain, subpaths) redirect seamlessly with minimal latency.
Key Decisions and Trade-offs
Why Vercel for the application layer? Vercel's native Next.js integration eliminates build configuration overhead, provides automatic HTTPS, and scales horizontally on demand. The `/api/webhook` route runs in Vercel's edge network, reducing latency for Stripe → application communication.
Why S3 + CloudFront for static assets? This decouples static delivery from application compute. CloudFront's edge locations globally cache assets, reducing origin load and improving first-byte time. Using a separate S3 bucket allows independent scaling; a traffic spike on static assets doesn't impact application performance.
Why Google Apps Script for webhooks? Rather than adding a Lambda function or standalone server, Google Apps Script provides a lightweight, free-tier-friendly option. The deployment is bound to a Google Sheet or standalone service, and the script can directly trigger Printful order creation via HTTP requests. This eliminates dependency management and reduces operational overhead.
Why Route53 for DNS? Consolidating DNS, ACM, and CloudFront in AWS simplifies credential management and automation. A single `aws acm` command validates certificates via Route53 DNS CNAME records, eliminating manual DNS verification steps at third-party registrars.
Infrastructure Summary
The final state includes:
- Vercel project:
86dfrom(Git-connected, auto-deploys on push) - S3 buckets:
86dfrom.com,86from.com - CloudFront distributions: 2 (primary + redirect)
- Route53 hosted zone: 1 (with A and CNAME records for both domains)
- ACM certificates: 2 (one per domain, auto-renewed by AWS)
- Google Apps Script project: deployed standalone, with script ID in
.env.local`