How I Used ngrok to Deploy My Dynamic Website

How I Used ngrok to Deploy My Dynamic Website — And Why Method 2 Changed Everything

If you've ever built a dynamic website locally and thought "how do I share this with someone right now without deploying it to a server?" — this post is for you.

I was in the exact same situation. I had a frontend running on localhost:3000 and a backend API on localhost:5000. Everything worked perfectly on my machine. But the moment I wanted to share it or test it on another device, I was stuck.

That's when I discovered ngrok — and honestly, it saved my project.


What Is ngrok and Why Do You Need It?

ngrok is a tool that creates a secure public URL for your locally running application. Instead of deploying to a cloud server, you simply run a command and get a live URL like https://abc123456.ngrok-free.app — which anyone can access from anywhere.

It's perfect for:

  • Sharing work-in-progress with clients
  • Testing webhooks
  • Demoing projects without a deployment pipeline

My Setup: A Typical Dynamic Website

My project was a simple dynamic site:

  • Frontend — React app on localhost:3000
  • Backend — Node.js + Express API on localhost:5000
  • Frontend fetches data from the backend via API calls

At first, I tried running two separate ngrok tunnels — one for frontend, one for backend. It kind of worked, but it was messy. I had to keep track of two different URLs, update my frontend code every time the backend URL changed, and deal with CORS issues constantly.

Then I discovered Method 2 — the single tunnel approach. And it changed everything.


The Method I Used: Single ngrok Tunnel (Method 2)

Instead of running two tunnels, I merged everything into one. Here's exactly what I did:

Step 1: Build the React frontend

npm run build

This creates an optimized build/ folder with all your static files.

Step 2: Serve the frontend from the Express backend

In my server.js, I added these two lines:

app.use(express.static("build"));

app.get("*", (req, res) => {
  res.sendFile(__dirname + "/build/index.html");
});

Now my Express server serves both the React app and the API — everything on a single port: localhost:5000.

Step 3: Run ngrok just once

ngrok http 5000

That gave me one clean public URL. Frontend loaded. API worked. Done.


Why Method 2 Was Better for My Situation

Here's the honest truth — Method 2 felt closer to how real websites actually work. When you deploy to production, your frontend and backend usually live together. This approach mimics that structure.

The benefits I noticed immediately:

  • One URL to share — no confusion about which link to send
  • No CORS headaches — since frontend and backend are on the same origin, the browser doesn't block requests
  • No hardcoded ngrok URLs in my frontend code — API calls just go to /api/... as relative paths
  • Cleaner and more professional — felt like a real deployed app, not a local hack

The Mistakes I Made Before Getting This Right

I want to be honest here because these mistakes cost me hours:

1. Using localhost in frontend API calls When your site is exposed via ngrok, localhost no longer works for the person accessing it remotely. Everything has to go through the ngrok URL — or better, use relative paths when both are on the same server.

2. Forgetting CORS When I was running two tunnels, my backend was blocking frontend requests because CORS wasn't configured. The fix is simple — just add this to your Express app:

const cors = require('cors');
app.use(cors());

3. Starting ngrok before building the frontend I built the frontend after starting the server, so the build/ folder wasn't being served. Always build first, then start the server.


Should You Use Method 1 or Method 2?

Here's a simple way to decide:

Method 1 (Two Tunnels) Method 2 (Single Tunnel)
Setup effort More setup Slightly more upfront
Best for Quick demos, learning Cleaner sharing, testing
CORS issues Yes, need to handle No, same origin
Number of URLs Two One
Feels like production No Yes

If you're just starting out, Method 1 is fine to understand how things connect. But if you want something that actually works cleanly — go with Method 2. That's the one I'm sticking with.


Final Thoughts

ngrok is genuinely one of those tools I wish I had known about earlier. The single tunnel method took a bit more setup — building the frontend and wiring it into Express — but the result was worth it. One URL, no CORS drama, and it felt like a proper working site.

If you're building a dynamic web app locally and need to share it fast, try this approach. You'll thank yourself later.

When I learned this at Navantra Global Solutions Pvt. Ltd., it made local development much easier.

If you're starting full-stack development, mastering ngrok is a smart first step.

Learn locally. Test globally. Build confidently. 🚀



Have questions or ran into a different issue? Drop a comment below — I'd love to hear how others are solving this.

Comments

Popular posts from this blog

My First Stipend-Based Internship💻🚀

How I Fixed the Prisma Error

Design Web Pages using CSS