LINE
Get your LINE credentials
- Create a channel in the LINE Developers Console.
- Note your Channel ID (client_id) and Channel secret (client_secret).
- In the channel settings, add your Redirect URI, e.g.
http://localhost:3000/api/auth/callback/linefor local development. - Enable required scopes (at least
openid; addprofile,emailif you need name, avatar, email).
See LINE Login v2.1 reference for details: [https://developers.line.biz/en/reference/line-login/#issue-access-token]
Configure the provider
Add your LINE credentials to socialProviders.line in your auth configuration.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
socialProviders: {
line: {
clientId: process.env.LINE_CLIENT_ID as string,
clientSecret: process.env.LINE_CLIENT_SECRET as string,
// redirectURI: "https://your.app/api/auth/callback/line", // uncomment to use a custom redirect URI
// scope: ["custom"], // uncomment to add additional scopes
// disableDefaultScope: true, // uncomment to replace default scopes [`openid`, `profile`, `email`]
},
},
});Usage
Sign In with LINE
Use the client signIn.social with provider: "line".
import { createAuthClient } from "better-auth/client";
const authClient = createAuthClient();
async function signInWithLINE() {
const res = await authClient.signIn.social({ provider: "line" });
}Sign In with LINE using ID Token (optional)
If you obtain the LINE ID token on the client, you can sign in directly without redirection.
await authClient.signIn.social({
provider: "line",
idToken: {
token: "<LINE_ID_TOKEN>",
accessToken: "<LINE_ACCESS_TOKEN>",
},
});Notes
- Default scopes include
openid profile email. Adjust as needed via provider options. - Verify redirect URI exactly matches the value configured in LINE Developers Console.
- LINE ID token verification uses the official endpoint and checks audience and optional nonce per spec.
Designing a login button? Follow LINE's button guidelines.
Multi-Channel Support
LINE requires separate OAuth channels for different countries (Japan, Thailand, Taiwan, etc.), each with its own clientId and clientSecret. The standard socialProviders.line configuration only supports a single channel.
To support multiple countries/channels, use the Generic OAuth plugin with the line() helper function. This allows you to configure multiple LINE providers with different providerIds:
import { betterAuth } from "better-auth";
import { genericOAuth, line } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
genericOAuth({
config: [
// Japan channel
line({
providerId: "line-jp",
clientId: process.env.LINE_JP_CLIENT_ID,
clientSecret: process.env.LINE_JP_CLIENT_SECRET,
}),
// Thailand channel
line({
providerId: "line-th",
clientId: process.env.LINE_TH_CLIENT_ID,
clientSecret: process.env.LINE_TH_CLIENT_SECRET,
}),
// Taiwan channel
line({
providerId: "line-tw",
clientId: process.env.LINE_TW_CLIENT_ID,
clientSecret: process.env.LINE_TW_CLIENT_SECRET,
}),
],
}),
],
});When signing in, use the appropriate providerId (e.g., "line-jp", "line-th", "line-tw") to identify which channel to use:
import { createAuthClient } from "better-auth/client";
import { genericOAuthClient } from "better-auth/client/plugins";
const authClient = createAuthClient({
plugins: [genericOAuthClient()],
});
// Sign in with Japan channel
await authClient.signIn.social({ provider: "line-jp" });
// Sign in with Thailand channel
await authClient.signIn.social({ provider: "line-th" });