Test/playground application for the better-auth-telegram plugin. Demonstrates all three authentication flows: Login Widget, Mini App, and OIDC.
- Open Telegram and find @BotFather
- Send
/newbotand follow the instructions - Save the Bot Token (format:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz) - Save the Bot Username (format:
your_bot_username)
cd test
npm install
# Copy and edit environment files
cp .env.local.example .env.localEdit .env.local with your bot credentials:
TELEGRAM_BOT_TOKEN="your_bot_token_here"
TELEGRAM_BOT_USERNAME="your_bot_username_here"Note: Prisma CLI reads from
.env, not.env.local. Create a.envfile too:echo 'DATABASE_URL="file:./prisma/dev.db"' > .env
npx prisma db pushSend /setdomain to @BotFather and set it based on your setup:
| Setup | Domain to set | Auth flows supported |
|---|---|---|
| localhost only | localhost |
Login Widget |
| ngrok (recommended) | your-subdomain.ngrok-free.app |
Login Widget + OIDC |
Option A: localhost only (Login Widget only)
npm run dev
# Open http://localhost:3000Option B: With ngrok (all auth flows including OIDC)
OIDC requires a publicly accessible HTTPS URL because Telegram's OAuth server needs to redirect back to your app. ngrok tunnels your localhost to a public URL.
# Terminal 1: Start ngrok
ngrok http 3000
# Copy the https://xxxx.ngrok-free.app URL, then update .env.local:
# BETTER_AUTH_URL="https://xxxx.ngrok-free.app"
# BETTER_AUTH_TRUSTED_ORIGINS="https://xxxx.ngrok-free.app"
# NEXT_PUBLIC_APP_URL="https://xxxx.ngrok-free.app"
# Terminal 2: Start the app
npm run dev
# Open your ngrok URL in the browserImportant: After starting ngrok, update the BotFather
/setdomainto your ngrok domain. Free ngrok URLs change on restart — you'll need to update.env.localand BotFather each time.
Sign in via the embedded Telegram button on the home page. Uses HMAC-SHA-256 verification of the widget data.
Auto-authentication inside Telegram Mini Apps. To test:
- Create a Mini App via @BotFather using
/newapp - Set the Web App URL to
[your-url]/miniapp - Open the bot in Telegram and launch the Mini App
OAuth 2.0 Authorization Code flow with PKCE via oauth.telegram.org. Navigate to /oidc and click the button. Requires ngrok (or any public HTTPS URL).
test/
├── app/
│ ├── api/auth/[...all]/ # Better Auth API routes
│ ├── dashboard/ # Protected dashboard
│ ├── miniapp/ # Mini App test page
│ ├── oidc/ # OIDC test page
│ └── page.tsx # Home page with login
├── components/
│ ├── TelegramLoginButton.tsx # Login widget component
│ └── SessionDisplay.tsx # Session info display
├── lib/
│ ├── auth.ts # Server-side auth config
│ └── auth-client.ts # Client-side auth
├── prisma/
│ └── schema.prisma # Database schema
└── .env.local.example # Environment variables template
- Open your app URL
- Click "Login with Telegram"
- Authenticate in Telegram
- Verify redirect to
/dashboard - Check user data display (username, photo, Telegram ID)
- Refresh the page — should stay logged in
- Open in a new tab — should have session
- Close and reopen browser — session should persist (7 day expiry)
- On the dashboard click "Sign Out"
- Verify redirect to home
- Try accessing
/dashboard— should show "No active session"
- Create a Mini App via @BotFather using
/newapp - Set the Web App URL to your app's
/miniapppath - Open the bot in Telegram and launch the Mini App
- Auto-authentication should happen and redirect to dashboard
- Start ngrok and update
.env.local+ BotFather domain - Navigate to
/oidc - Click "Sign in with Telegram OIDC"
- Authorize on Telegram's OAuth page
- Verify redirect to dashboard with session
# Get Telegram config
curl http://localhost:3000/api/auth/telegram/config
# Expected: {"botUsername":"your_bot_username","testMode":false}- Check that you set
/setdomainin @BotFather to match your current URL - For localhost use exactly:
localhost(no http://) - For ngrok: set the full ngrok subdomain (e.g.
xxxx.ngrok-free.app) - The Login Widget may not work on desktop with ngrok free tier — try mobile
Make sure you're using better-auth-telegram v1.2.1+ which includes the origin parameter fix.
- Check browser console for errors
- Verify the bot domain matches your current URL
- Try clearing browser cache
- Verify
TELEGRAM_BOT_TOKENin.env.localis correct - Verify
TELEGRAM_BOT_USERNAMEis without@ - Check that auth_date is not too old (max 24h)
# Delete the database and let Prisma recreate it
rm prisma/dev.db
npx prisma db push
npm run devPrisma CLI reads .env, not .env.local. Create a separate .env file:
echo 'DATABASE_URL="file:./prisma/dev.db"' > .env- Next.js 16 with Turbopack
- Better Auth with Prisma adapter
- better-auth-telegram plugin
- Prisma with SQLite
- Tailwind CSS v4
- Better Auth Docs
- Telegram Login Widget Docs
- Telegram Mini Apps Docs
- Telegram OIDC Docs
- Plugin Source Code
MIT