LINE

Get your LINE credentials

  1. Create a channel in the LINE Developers Console.
  2. Note your Channel ID (client_id) and Channel secret (client_secret).
  3. In the channel settings, add your Redirect URI, e.g. http://localhost:3000/api/auth/callback/line for local development.
  4. Enable required scopes (at least openid; add profile, email if 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.

auth.ts
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".

auth-client.ts
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.

auth-client.ts
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:

auth.ts
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:

auth-client.ts
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" });

On this page