Developing Apps Locally: New and Existing

Agility Apps run inside iframes in the CMS. That means your app needs to be reachable from a real URL. Not http://localhost:3000. The browser won't allow it, and neither will Agility.

This trips up every developer at least once. You scaffold your app, fire up next dev, point Agility at localhost, and nothing loads. No error message. Just a blank iframe.

Here's the deal. There are two scenarios, and each has a clean solution.

Scenario 1: You're Building a Brand New App

You don't have a deployed URL yet. You just want to get something rendering inside the CMS so you can start building.

Use ngrok.

ngrok gives you a public HTTPS URL that tunnels traffic to your local machine. It takes about 30 seconds to set up.

Steps

  1. Install ngrok if you haven't already:
brew install ngrok
  1. Start your app locally:
npm run dev

This runs on http://localhost:3000 as usual.

  1. In a separate terminal, start ngrok:
ngrok http 3000
  1. ngrok gives you a URL like https://abcd-1234.ngrok-free.app. Copy it.

  2. In Agility, register your app using that ngrok URL. Your /.well-known/agility-app.json file will be served through the tunnel, and all your app surfaces (custom fields, sidebars, dashboards, etc.) will load inside the CMS.

Things to Know

  • The ngrok URL changes every time you restart it (unless you're on a paid plan with reserved domains). You'll need to update your app registration in Agility each time.
  • ngrok free tier shows an interstitial warning page on first load. This can interfere with the iframe. A paid plan removes that, or you can add the ngrok-skip-browser-warning header in your app.
  • This is a temporary workflow. Once you're ready, deploy your app to a proper host (Vercel, Netlify, Cloudflare, wherever) and update your app registration to the real URL.

Scenario 2: You're Updating an Existing Deployed App

Your app is already deployed and registered in Agility at something like https://my-agility-app.vercel.app. You want to make changes locally and see them in the CMS without deploying every time.

Spoof the URL locally.

The idea is simple. Run your app locally on HTTPS using the same domain as the deployed app, then redirect that domain to your local machine using your hosts file.

Step 1: Run Next.js in HTTPS Mode

Next.js has built-in support for self-signed certificates in dev mode:

next dev --experimental-https

This starts your dev server at https://localhost:3000 with a self-signed cert.

For more details, see Vercel's guide on running Next.js with HTTPS locally.

Step 2: Edit Your Hosts File

Your hosts file lets you override DNS for any domain on your machine. You're going to point your app's production domain to 127.0.0.1.

On Mac/Linux, edit /etc/hosts:

sudo nano /etc/hosts

On Windows, edit C:\Windows\System32\drivers\etc\hosts (run your editor as Administrator).

Add a line like this:

127.0.0.1   my-agility-app.vercel.app

Replace my-agility-app.vercel.app with whatever domain your app is actually deployed to.

Step 3: Accept the Self-Signed Certificate

Open https://my-agility-app.vercel.app:3000 in your browser. You'll get a certificate warning because the self-signed cert doesn't match the domain. Click through and accept it.

This step matters. If you skip it, the iframe inside Agility will silently fail to load your app. The browser blocks untrusted certs in iframes without any visible error. Visit the URL directly first, accept the cert, then go back to Agility.

Step 4: Load Your App in Agility

Now when Agility tries to load your app in an iframe, the browser resolves the domain to your local machine, and your local dev server responds. You get hot reload, console logs, the whole local dev experience, but running inside the CMS.

When You're Done

Remove the hosts file entry. Otherwise your production app will stop working on your machine (because it'll keep resolving to localhost instead of the real server).

# 127.0.0.1   my-agility-app.vercel.app   <-- comment it out or delete it

Quick Reference

SituationSolutionComplexity
New app, no deployed URL yetngrok tunnel to localhostLow
Existing app, iterating on changesHTTPS dev mode + hosts file spoofMedium

Further Reading