Overview
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.
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.
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.
brew install ngrok
npm run dev
This runs on http://localhost:3000 as usual.
ngrok http 3000
ngrok gives you a URL like https://abcd-1234.ngrok-free.app. Copy it.
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.
ngrok-skip-browser-warning header in your 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.
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.
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.
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.
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.
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
| Situation | Solution | Complexity |
|---|---|---|
| New app, no deployed URL yet | ngrok tunnel to localhost | Low |
| Existing app, iterating on changes | HTTPS dev mode + hosts file spoof | Medium |
@agility/app-sdk reference