Share a Next.js dev server
Share a Next.js dev server (next dev) through a Horizon tunnel, with the allowedDevOrigins setting that stops the blocked cross-origin warning.
Open your next dev server from a phone, a teammate's laptop or a webhook sender, with an HTTPS URL that reaches your machine.
Before you begin
- Node.js 18 or later
- A Horizon account and the CLI (see Getting started)
- A reserved subdomain for
-s. Reserve one on the Subdomains page. - A Next.js app that runs with
next dev
Allow the tunnel origin
Next.js blocks cross-origin requests to dev-only assets and endpoints by default. A browser on https://my-app.hrzn.run sends that hostname as its Origin, so Next.js doesn't recognize it. Add the hostname to allowedDevOrigins.
module.exports = {
allowedDevOrigins: ["my-app.hrzn.run"],
}Write the hostname only. Next.js ignores the scheme, port and path, so leave out https://. Restart next dev after you edit the file.
Start a tunnel
Use -s with a subdomain you reserved. Reserved subdomains are a paid feature, see Pricing.
hrzn tunnel http://localhost:3000 -s my-appHORIZON: Tunnel connected
URL https://my-app.hrzn.run (reserved)
Forwarding http://localhost:3000
Request log https://hrzn.run/dashboard/tunnels/my-appKeep this terminal open.
Open the URL
Open https://my-app.hrzn.run in a browser. A first-time browser visitor sees the Before you continue page. Select Continue to site.
Check it works
The page loads and the Horizon terminal prints one line per request:
GET 200 /Edit a page file and save. The browser updates without a reload. WebSockets pass through the tunnel, and Next.js uses one for this.
Server Actions
Horizon sets Host to localhost:3000. The browser sends Origin: https://my-app.hrzn.run. Next.js compares the host in Origin with the app's host, which it takes from x-forwarded-host first and from host second. Horizon forwards the public host in X-Forwarded-Host, so the two match and you need no extra setting.
If an action fails, see Troubleshooting.
Troubleshooting
Blocked cross-origin request to Next.js dev resource
The full message starts with Blocked cross-origin request to Next.js dev resource /_next/... from "my-app.hrzn.run". The tunnel hostname isn't in allowedDevOrigins. Add it as shown above and restart next dev. The browser then gets a 403 with the body Unauthorized for those requests until you do.
x-forwarded-host header with value ... does not match origin header
Next.js prints `x-forwarded-host` header with value `...` does not match `origin` header with value `...` from a forwarded Server Actions request. Aborting the action. The two hosts differ, so Next.js stops the action. Compare the two values in the message. If the origin value is my-app.hrzn.run, add it to serverActions.allowedOrigins:
module.exports = {
allowedDevOrigins: ["my-app.hrzn.run"],
experimental: {
serverActions: {
allowedOrigins: ["my-app.hrzn.run"],
},
},
}x-forwarded-host or host headers are not provided
Next.js prints this when a Server Actions request has neither header. Horizon sends both, so look for another proxy between the browser and your app.
The URL changed after a restart
You started the tunnel without -s, so Horizon gave you a new random subdomain. Restart with -s my-app, then update allowedDevOrigins if the hostname differs.
Next steps
- Read the Next.js reference for
allowedDevOriginsandserverActions.