Test Twitch OAuth login locally
Sign in with Twitch on localhost by registering a stable HTTPS OAuth Redirect URL from a Horizon tunnel, with Auth.js in Next.js.
Test "Sign in with Twitch" on your laptop, with an OAuth Redirect URL Twitch can reach.
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 Twitch account
- A Next.js App Router app with Auth.js set up. The Auth.js guide covers
AUTH_SECRETand the route handler.
Start a tunnel
Use -s with a subdomain you reserved. Without it, the subdomain is random and changes every run, so the redirect URI you register would point at a dead URL after a restart. 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.
Register the app in Twitch
- Log in to the Twitch developer console.
- Select the Applications tab, then Register Your Application.
- Set Name. It must be unique.
- Set OAuth Redirect URLs to
https://my-app.hrzn.run/api/auth/callback/twitch. - Select a Category.
- Complete the CAPTCHA and select Create.
- Open your app and select Manage. Copy the Client ID, then select New Secret and copy the secret.
Twitch redirects to the first OAuth Redirect URL if you add several. Keep the tunnel URL first while you test.
Configure Auth.js
Auth.js reads the Twitch credentials from AUTH_TWITCH_ID and AUTH_TWITCH_SECRET. AUTH_TRUST_HOST=true makes Auth.js trust X-Forwarded-Host, so it builds the callback from the public host. Horizon sets Host to localhost:3000.
AUTH_SECRET=replace-with-the-generated-secret
AUTH_TRUST_HOST=true
AUTH_TWITCH_ID=replace-with-the-client-id
AUTH_TWITCH_SECRET=replace-with-the-client-secretimport NextAuth from "next-auth";
import Twitch from "next-auth/providers/twitch";
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [Twitch],
});import { handlers } from "@/auth";
export const { GET, POST } = handlers;Add a sign-in button, then start the app on port 3000.
import { signIn } from "@/auth";
export default function Home() {
return (
<form
action={async () => {
"use server";
await signIn("twitch");
}}
>
<button type="submit">Sign in with Twitch</button>
</form>
);
}npm run devSign in
Open https://my-app.hrzn.run. On the first visit, select Continue to site on the Before you continue page. Then select Sign in with Twitch.
Check it works
Twitch shows its authorization screen. After you approve, your browser lands back on https://my-app.hrzn.run.
Your Horizon terminal prints a line for the callback:
GET 302 /api/auth/callback/twitchTroubleshooting
Twitch doesn't accept the redirect URL
Twitch expects the redirect_uri your app sends to be one of the registered OAuth Redirect URLs.
- Check that the URL is exactly
https://my-app.hrzn.run/api/auth/callback/twitch. - Check that
AUTH_TRUST_HOST=trueis set and that you restartednpm run dev. Without it, Auth.js can build alocalhostcallback. - Check that the subdomain matches the one you pass to
-s.
Twitch sends you to the wrong URL
With several OAuth Redirect URLs, Twitch redirects to the first one. Move the tunnel URL to the top of the list, or remove the others while you test.
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 and the registered URL stays valid. -s needs a subdomain you reserved, see Pricing.
Nothing reaches your app
- Check that the Horizon terminal is still running. If its last line is
Connection lost. Reconnecting…, wait forReconnected. - Check that the app listens on port 3000, the port in your tunnel command.
Next steps
- Read Twitch's guide to registering an app.
- Read the general page, Test OAuth redirect URLs locally.
Test Microsoft sign-in locally
Test Microsoft Entra ID sign-in on localhost with a stable HTTPS redirect URI from a Horizon tunnel and Auth.js.
Test Auth.js (NextAuth v5) login behind a tunnel
Run Auth.js sign-in on localhost behind a Horizon tunnel, with AUTH_TRUST_HOST, AUTH_URL and the right callback path.