Other Social Providers
Other social providers setup and usage.
Better Auth supports any social provider that implements OAuth 2.0 or OpenID Connect (OIDC) through the Generic OAuth Plugin. You can use a built-in provider helper, install a community provider helper, or configure a provider manually.
Installation
Add the plugin to your auth config
To use the Generic OAuth plugin, add it to your auth config.
import { betterAuth } from "better-auth"
import { genericOAuth } from "better-auth/plugins"
export const auth = betterAuth({
// ... other config options
plugins: [
genericOAuth({
config: [
{
providerId: "provider-id",
clientId: "test-client-id",
clientSecret: "test-client-secret",
discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
// ... other config options
},
// Add more providers as needed
]
})
]
})Create your auth client
import { createAuthClient } from "better-auth/client"
const authClient = createAuthClient()Read more about installation and usage of the Generic OAuth plugin Generic OAuth plugin documentation.
Example Usage
Here's a basic example of configuring a generic OAuth provider:
import { betterAuth } from "better-auth"
import { genericOAuth } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
genericOAuth({
config: [
{
providerId: "provider-id",
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
},
],
}),
],
})Provider Helpers
Provider helpers package provider-specific endpoints, scopes, and profile mapping as reusable GenericOAuthConfig factories.
Built-in Provider Helpers
Better Auth includes helpers for these providers:
- Auth0 -
auth0(options) - Gumroad -
gumroad(options) - HubSpot -
hubspot(options) - Keycloak -
keycloak(options) - LINE -
line(options) - Microsoft Entra ID (Azure AD) -
microsoftEntraId(options) - Okta -
okta(options) - Patreon -
patreon(options) - Slack -
slack(options) - Yandex -
yandex(options)
Here's an example using Slack:
import { betterAuth } from "better-auth"
import { genericOAuth, slack } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
genericOAuth({
config: [
slack({
clientId: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
}),
],
}),
],
})const response = await authClient.signIn.social({
provider: "slack",
callbackURL: "/dashboard",
})Each helper accepts common OAuth options through BaseOAuthProviderOptions, plus these provider-specific fields:
- Auth0: Requires
domain(for example,dev-xxx.eu.auth0.com) - HubSpot: Accepts optional
scopes, which default to["oauth"] - Keycloak: Requires
issuer(for example,https://my-domain/realms/MyRealm) - LINE: Accepts an optional
providerId. Callline()with different provider IDs and credentials to support multiple country-specific channels - Microsoft Entra ID: Requires a concrete tenant GUID. Use the built-in Microsoft social provider for the multi-tenant
"common","organizations", or"consumers"authorities - Okta: Requires
issuer(for example,https://dev-xxxxx.okta.com/oauth2/default)
All helpers accept these common options:
clientIdclientSecrettokenEndpointAuthscopesredirectURIpkcedisableImplicitSignUpdisableSignUpoverrideUserInfoendSessionEndpointpostLogoutRedirectURIdisableProviderLogout
Community Provider Helpers
Provider authors and community maintainers can publish reusable helpers that return a typed GenericOAuthConfig for use with the Generic OAuth plugin.
Community provider helpers are not official or verified by the Better Auth team. Use them at your own discretion and review their source code before integrating them into your application.
Community provider helper listings are coming soon.
Create a Provider Helper
A provider helper accepts credentials and provider-specific options, then returns a GenericOAuthConfig.
import type {
BaseOAuthProviderOptions,
GenericOAuthConfig,
} from "better-auth/plugins/generic-oauth";
export interface ExampleOptions extends BaseOAuthProviderOptions {}
export function example(
options: ExampleOptions,
): GenericOAuthConfig<"example"> {
return {
providerId: "example",
discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
clientId: options.clientId,
clientSecret: options.clientSecret,
tokenEndpointAuth: options.tokenEndpointAuth,
scopes: options.scopes ?? ["openid", "email", "profile"],
redirectURI: options.redirectURI,
};
}Users install the helper from its author and pass it to Generic OAuth.
import { example } from "@example/better-auth";
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
genericOAuth({
config: [
example({
clientId: process.env.EXAMPLE_CLIENT_ID!,
clientSecret: process.env.EXAMPLE_CLIENT_SECRET!,
}),
],
}),
],
});To share a provider helper with the community, see the contribution guidelines.
Configure a Provider Manually
If you need to configure a provider that doesn't have a provider helper, you can configure it manually:
Instagram Example
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";
export const auth = betterAuth({
// ... other config options
plugins: [
genericOAuth({
config: [
{
providerId: "instagram",
clientId: process.env.INSTAGRAM_CLIENT_ID as string,
clientSecret: process.env.INSTAGRAM_CLIENT_SECRET as string,
authorizationUrl: "https://api.instagram.com/oauth/authorize",
tokenUrl: "https://api.instagram.com/oauth/access_token",
scopes: ["user_profile", "user_media"],
},
],
}),
],
});const response = await authClient.signIn.social({
provider: "instagram",
callbackURL: "/dashboard",
});Coinbase Example
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";
export const auth = betterAuth({
// ... other config options
plugins: [
genericOAuth({
config: [
{
providerId: "coinbase",
clientId: process.env.COINBASE_CLIENT_ID as string,
clientSecret: process.env.COINBASE_CLIENT_SECRET as string,
authorizationUrl: "https://www.coinbase.com/oauth/authorize",
tokenUrl: "https://api.coinbase.com/oauth/token",
scopes: ["wallet:user:read"], // and more...
},
],
}),
],
});const response = await authClient.signIn.social({
provider: "coinbase",
callbackURL: "/dashboard",
});