Created
August 26, 2026 02:24
-
-
Save muhadmr/1609db1a266d673b0ecf5cdc71279726 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # I Built and Deployed a Viral Web App for $0/Month (And You Can Too) | |
| ### The Modern Indie Hacker Blueprint: Neon, Render, Vercel, Cloudflare, Resend, AdSense, and GEO | |
| For the last twenty years, the internet has done everything possible to make links tiny. Bitly, TinyURL, and t.co turned the web into a sea of opaque 6-character strings that look like spam and tell you nothing about where youβre going. | |
| So, naturally, I built the exact opposite: **[WhyShorten](https://whyshorten.com)** β a reverse URL shortener that takes a short link and expands it into an absurd, 750-character passage from *Frankenstein*, *Moby-Dick*, or Apollo 11 lunar flight transcripts. | |
| ``` | |
| Original: https://github.com/torvalds/linux | |
| WhyShorten: https://whyshorten.com/l/it-was-on-a-dreary-night-of-november-that-i-beheld-the-accomplishment-of-my-toils-houston-tranquility-base-here-the-eagle-has-landed-6319e2 | |
| ``` | |
| Itβs completely unhinged. But beneath the comedic front lies a full-stack, enterprise-grade architecture with real-time analytics, deterministic hashing, user authentication, ad monetization, and generative AI search indexing. | |
| The best part? **The monthly hosting and infrastructure bill is exactly $0.00.** | |
| Here is the step-by-step blueprint of how I built, deployed, monetized, and optimized WhyShorten so you can launch your next side project with zero infrastructure costs. | |
| --- | |
| ## π§ The Zero-Dollar Modern Stack Overview | |
| ``` | |
| ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β User / AI Crawler β | |
| ββββββββββββββββββββββββ¬ββββββββββββββββββββββββ | |
| β HTTPS (Cloudflare Edge) | |
| βββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββ | |
| β β | |
| βΌ βΌ | |
| ββββββββββββββββββββββββββ ββββββββββββββββββββββββββ | |
| β whyshorten.com β β api.whyshorten.com β | |
| β Vercel (Vue 3 SPA) β β Render (Node/Express)β | |
| ββββββββββββββββββββββββββ ββββββββββββββ¬ββββββββββββ | |
| β | |
| βΌ | |
| ββββββββββββββββββββββββββ | |
| β Neon Serverless DB β | |
| β (PostgreSQL Pooled) β | |
| ββββββββββββββββββββββββββ | |
| ``` | |
| | Layer | Provider | The Secret Sauce | Monthly Cost | | |
| | :--- | :--- | :--- | :--- | | |
| | **Frontend UI** | **Vercel** | Edge CDN, instant Git CI/CD, and automatic asset compression. | **$0** | | |
| | **Backend REST API** | **Render** | Managed Node.js container with free automatic SSL. | **$0** | | |
| | **Database** | **Neon PostgreSQL** | Serverless Postgres that scales down to zero when idle. | **$0** | | |
| | **Edge DNS & Security** | **Cloudflare** | Global DDoS mitigation, HTTP/3, and Full (Strict) SSL. | **$0** | | |
| | **Inbound Email** | **Cloudflare Routing** | Forwards domain mail (`support@...`) to personal Gmail. | **$0** | | |
| | **Outbound Email** | **Resend** | High-deliverability transactional SMTP (100 free emails/day). | **$0** | | |
| | **Monetization** | **Google AdSense** | Dynamic banner revenue during redirect countdowns. | **+$ Revenue** | | |
| --- | |
| ## Step 1: Provision a Serverless Database on Neon | |
| ### π‘ The Strategy: | |
| Traditional cloud databases (like AWS RDS or DigitalOcean droplets) charge you 24/7 just for having a server running, even when nobody is using it. | |
| **Neon** changes the game: it is **serverless PostgreSQL**. When traffic drops, compute scales down to zero ($0 cost). When someone clicks a link, it wakes up in under a second. | |
| ### π οΈ How to Set It Up: | |
| 1. Create a free project at [Neon.tech](https://neon.tech). | |
| 2. Choose your nearest region (e.g., `AWS us-east-1`). | |
| 3. **Crucial Step β Enable Connection Pooling:** | |
| In your Neon dashboard, toggle on **"Connection pooling"**. | |
| > **Pro Tip:** Serverless apps (like Vercel and Render) spawn and kill connections rapidly. Direct Postgres connections will quickly max out your pool. Neon's built-in `neondb-pooler` (powered by PgBouncer) allows thousands of concurrent requests without dropping a single connection. | |
| 4. Copy your pooled connection URI: | |
| ```env | |
| DATABASE_URL=postgresql://<user>:<password>@<neon-pooler-host>/neondb?sslmode=require | |
| ``` | |
| 5. Run your initial schema migration to store links and click counts: | |
| ```sql | |
| CREATE TABLE links ( | |
| id SERIAL PRIMARY KEY, | |
| slug TEXT UNIQUE NOT NULL, | |
| target_url TEXT NOT NULL, | |
| mode VARCHAR(50) DEFAULT 'random', | |
| source_title VARCHAR(255), | |
| click_count INT DEFAULT 0, | |
| expires_at TIMESTAMPTZ NOT NULL, | |
| created_at TIMESTAMPTZ DEFAULT NOW() | |
| ); | |
| ``` | |
| --- | |
| ## Step 2: Deploy the Backend API on Render | |
| ### π‘ The Strategy: | |
| We want our API decoupled from our frontend. If the frontend is re-skinned or moved, the API stays rock-solid. Render gives us a completely managed Docker/Node environment with automatic Git deployments. | |
| ### π οΈ How to Set It Up: | |
| 1. Put your Express/Node backend code inside a `/server` directory in your Git repository. | |
| 2. In [Render.com](https://render.com), click **New > Web Service** and connect your GitHub repo. | |
| 3. Configure the build parameters: | |
| * **Root Directory**: `server` | |
| * **Build Command**: `npm install && npm run build` | |
| * **Start Command**: `npm run start` | |
| * **Plan**: `Free` | |
| 4. Set your **Environment Variables**: | |
| * `DATABASE_URL`: `postgresql://...` *(from Step 1)* | |
| * `NODE_ENV`: `production` | |
| * `PORT`: `10000` | |
| * `CORS_ORIGIN`: `https://whyshorten.com` | |
| > **Trap to Avoid:** Never leave `CORS_ORIGIN` as `*` in production. Setting it explicitly to your frontend domain prevents malicious websites from abusing your API endpoints from their own frontends. | |
| --- | |
| ## Step 3: Deploy the Frontend on Vercel | |
| ### π‘ The Strategy: | |
| Our frontend is built with **Vue 3, Vite, and Tailwind CSS v4**. Static assets should live on a global CDN edge, delivering sub-100ms first paint times anywhere in the world. | |
| ### π οΈ How to Set It Up: | |
| 1. Place your Vue app in a `/client` directory. | |
| 2. In your API configuration ([`client/src/config/api.ts`](file:///D:/00-WORKSPACE/personal-projects/how-adv-works/client/src/config/api.ts)), make the API URL environment-aware: | |
| ```typescript | |
| export const API_BASE_URL = | |
| import.meta.env.VITE_API_URL || | |
| (import.meta.env.PROD ? 'https://api.whyshorten.com' : 'http://localhost:3001'); | |
| ``` | |
| 3. Add a `vercel.json` file to `/client` to handle client-side Single Page Application (SPA) routing: | |
| ```json | |
| { | |
| "rewrites": [ | |
| { "source": "/(.*)", "destination": "/index.html" } | |
| ] | |
| } | |
| ``` | |
| > **Why this matters:** Without this rewrite rule, visiting `whyshorten.com/pricing` or `whyshorten.com/l/some-slug` directly will return a 404 error from Vercel instead of letting Vue Router handle the path. | |
| 4. Import into Vercel and hit **Deploy**. | |
| --- | |
| ## Step 4: Hook Up Cloudflare DNS & SSL | |
| ### π‘ The Strategy: | |
| Cloudflare acts as the defensive shield and intelligent router for your application. It handles SSL encryption, blocks DDoS attacks, and splits traffic between your frontend and API. | |
| ### π οΈ How to Set It Up: | |
| 1. Point your domain's nameservers to Cloudflare. | |
| 2. Set your **SSL/TLS Encryption Mode** to **Full (Strict)**. | |
| 3. Configure your DNS routing table: | |
| ``` | |
| whyshorten.com ββ(CNAME Proxied)βββΊ cname.vercel-dns.com | |
| www.whyshorten.com ββ(CNAME Proxied)βββΊ cname.vercel-dns.com | |
| api.whyshorten.com ββ(CNAME Proxied)βββΊ <your-app>.onrender.com | |
| ``` | |
| 4. Go into Vercel settings and add `whyshorten.com`. | |
| 5. Go into Render settings and add `api.whyshorten.com`. | |
| Cloudflare now automatically provisions edge SSL certificates and proxies all traffic through its global network. | |
| --- | |
| ## Step 5: The $0 "Send and Receive" Business Email Hack | |
| ### π‘ The Strategy: | |
| Google Workspace charges **$6/month per user** just to have an email address like `support@whyshorten.com`. | |
| You can get the exact same professional experience for **$0/month** by splitting your email flow: | |
| 1. **Inbound**: Cloudflare catches all incoming emails and forwards them to your personal Gmail. | |
| 2. **Outbound**: Resend SMTP allows you to reply directly from Gmail using your custom domain. | |
| ``` | |
| Inbound: User βββΊ support@whyshorten.com βββΊ Cloudflare Routing βββΊ Your Gmail | |
| Outbound: Your Gmail (Send As) βββΊ Resend SMTP βββΊ User (Signed with DKIM) | |
| ``` | |
| ### π οΈ How to Set It Up: | |
| #### A. Inbound Forwarding (Cloudflare) | |
| 1. In Cloudflare, go to **Email Routing > Enable Email Routing**. | |
| 2. Add your personal Gmail as a verified destination. | |
| 3. Create a custom address: `support@whyshorten.com` β Forward to `yourname@gmail.com`. | |
| 4. Click **Add DNS records automatically**. | |
| #### B. Outbound Sending (Resend) | |
| 1. Create a free account at [Resend.com](https://resend.com) and add your domain `whyshorten.com`. | |
| 2. Add the provided DKIM and SPF records to your Cloudflare DNS. | |
| 3. Create a Resend API Key. | |
| #### C. Connect Gmail "Send As" | |
| 1. Open **Gmail > Settings βοΈ > Accounts and Import > Add another email address**. | |
| 2. Enter: | |
| * **Email**: `support@whyshorten.com` | |
| * **SMTP Server**: `smtp.resend.com` (Port 587, TLS) | |
| * **Username**: `resend` | |
| * **Password**: `re_your_api_key_here` | |
| 3. Enter the confirmation code forwarded to your inbox. | |
| You can now hit **Reply** inside Gmail and choose `support@whyshorten.com` from the dropdown. | |
| --- | |
| ## Step 6: Monetizing Traffic with Google AdSense | |
| ### π‘ The Strategy: | |
| When someone clicks a WhyShorten link, they land on a 3-second redirect splash screen displaying the source of the quote (e.g. *Frankenstein Chapter 4*) and a countdown timer. This is the perfect organic placement for an ad unit. | |
| ### π οΈ How to Set It Up: | |
| 1. Add your Google AdSense tag to `client/index.html`: | |
| ```html | |
| <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXXX" crossorigin="anonymous"></script> | |
| ``` | |
| 2. **Create your `ads.txt` file** in `client/public/ads.txt`: | |
| ``` | |
| google.com, pub-XXXXXXXXXXXXXXXX, DIRECT, f08c47fec0942fa0 | |
| ``` | |
| > **Why this is critical:** Google and programmatic ad networks will not serve high-paying ads without an authorized `ads.txt` file at the root of your domain. | |
| 3. **Build a Resilient Ad Component:** | |
| While your AdSense account is under review (or if a user is using an ad-blocker), raw ad units can collapse or leave ugly blank spaces. In [`client/src/components/AdBanner.vue`](file:///D:/00-WORKSPACE/personal-projects/how-adv-works/client/src/components/AdBanner.vue), we mount the official `<ins class="adsbygoogle">` tag, but automatically render a styled fallback card if Google ads haven't populated yet. | |
| --- | |
| ## Step 7: Mastering GEO (Generative Engine Optimization) | |
| ### π‘ The Strategy: | |
| SEO is no longer just about Google Search. In 2026, millions of developers and users ask **ChatGPT, Claude, Perplexity, and Gemini** for tool recommendations: | |
| > *"What is a funny reverse URL shortener?"* | |
| > *"Give me a URL lengthener that uses classic books."* | |
| If your site is only built for humans and legacy Googlebot, AI crawlers will miss it. Here is how we optimized WhyShorten for **GEO (Generative Engine Optimization)**: | |
| ### π οΈ How to Optimize for AI Engines: | |
| 1. **Unblock AI Search Bots in `robots.txt`:** | |
| ```txt | |
| User-agent: GPTBot | |
| Allow: / | |
| User-agent: ClaudeBot | |
| Allow: / | |
| User-agent: PerplexityBot | |
| Allow: / | |
| User-agent: Google-Extended | |
| Allow: / | |
| ``` | |
| 2. **Deploy the `llms.txt` Standard:** | |
| Create a markdown file at `whyshorten.com/llms.txt` that describes your architecture, public API endpoints, corpus themes, and use cases in clean, structured text that LLMs can ingest in a single context window. | |
| 3. **Add Structured Schema.org JSON-LD:** | |
| In your HTML head, define rich semantic entities: | |
| * **`Organization`**: Solidifies your canonical brand name and logo. | |
| * **`WebApplication`**: Explains features and free/pro pricing. | |
| * **`FAQPage`**: Feeds direct answers into search engine answer boxes. | |
| 4. **Use Structured Comparison Tables:** | |
| LLMs love structured tables. Embedding a semantic HTML `<table>` comparing *Standard Shorteners* vs *WhyShorten* makes it easy for AI engines to extract and cite your features in comparison queries. | |
| --- | |
| ## π The Result | |
| With this architecture: | |
| * **Initial Page Load:** `< 200ms` via Vercel Edge. | |
| * **Redirect API Resolution:** `< 80ms` via Neon Connection Pooling. | |
| * **Monthly Cost:** **$0.00** | |
| * **Scalability:** Handles 100,000+ monthly visits without changing a single line of code. | |
| ### π¦ Key Takeaways for Indie Hackers: | |
| 1. **Decouple Frontend & Backend:** Use Vercel for UI and Render for API. | |
| 2. **Always Use Connection Pooling on Serverless DBs:** It prevents connection exhaustion. | |
| 3. **Don't Pay for Email Hosting:** Use Cloudflare Inbound + Resend Outbound. | |
| 4. **Optimize for AI (GEO):** Adopt `llms.txt`, permissive `robots.txt`, and rich JSON-LD schema from Day 1. | |
| --- | |
| *Feel free to check out the live project at [whyshorten.com](https://whyshorten.com) or share your own indie stack in the comments below!* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment