BETTER-AUTH.

LINE

LINE provider setup and usage.

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 the LINE Login v2.1 reference for details.

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" });