# Configuration

The `social_auth` config decides which providers are on, which Google client ids the native SDK uses, and where the browser flow returns to on each platform; `SocialAuthButtons` renders the enabled providers.

- [Full Config Structure](#full-config-structure)
- [Providers](#providers)
- [Callbacks](#callbacks)
- [UI Overrides](#ui-overrides)
- [Button Widget](#button-widget)
- [Keys Owned by Other Packages](#keys-owned-by-other-packages)
- [Minimal Example](#minimal-example)
- [Related Documentation](#related-documentation)

## Full Config Structure

`social:install` writes the config to `lib/config/social_auth.dart`; every value is read at runtime through `Config.get`. This is what `social:install --providers=google,apple,github,microsoft --google-ios-client-id=123-abc.apps.googleusercontent.com --google-server-client-id=123-def.apps.googleusercontent.com --ios-scheme=myapp --android-callback=https://auth.example.com/auth/social` writes:

```dart
// What `dart run magic:dowel social:doctor` checks, and the values it prints
// for the backend: the callbacks below must equal the backend's
// MAGIC_STARTER_SOCIAL_IOS_REDIRECT and MAGIC_STARTER_SOCIAL_ANDROID_REDIRECT.
Map<String, dynamic> get socialAuthConfig => {
  'social_auth': {
    'providers': {
      'google': {
        'enabled': true,
        'ios_client_id': '123-abc.apps.googleusercontent.com',
        'server_client_id': '123-def.apps.googleusercontent.com',
      },
      'apple': {
        'enabled': true,
      },
      'github': {
        'enabled': true,
      },
      'microsoft': {
        'enabled': true,
      },
    },

    'callback': {
      'ios': 'myapp://auth/social',
      'android': 'https://auth.example.com/auth/social',
    },
  },
};
```

`social:doctor` reads this file back with a textual scan, so keep provider entries and `callback` flat maps of string and bool literals.

## Providers

`social_auth.providers.<name>` for `google`, `apple`, `github` and `microsoft`.

| Key | Type | Default | Description |
|:----|:-----|:--------|:------------|
| `enabled` | `bool` | `true` | When `false`, `SocialAuthButtons` skips the provider and `SocialAuth.driver(name)` throws `ProviderNotConfiguredException`. |

### Google

| Key | Type | Default | Description |
|:----|:-----|:--------|:------------|
| `ios_client_id` | `String` | none | The Google iOS OAuth client id. Read on iOS only (Android reads its client from the signing key). It must also be in `Info.plist` as `GIDClientID`; `social:install` writes both. |
| `server_client_id` | `String` | none | The Google web OAuth client id. It is the audience of the ID token the backend verifies, so it must be in `MAGIC_STARTER_SOCIAL_GOOGLE_AUDIENCES`. Without it Google returns no ID token: the driver throws a `SocialAuthException` coded `sdk_error` and logs a message that names this key. |

### Apple, GitHub, Microsoft

No keys beyond `enabled`. Their client ids and secrets live in the backend: the app only opens the sheet (Apple on iOS) or the backend's browser flow (everything else).

## Callbacks

`social_auth.callback.<platform>` is where the backend sends the browser when a browser flow ends. It must equal the backend's redirect target for the same platform.

| Key | Type | Backend env | Description |
|:----|:-----|:------------|:------------|
| `callback.ios` | `String` | `MAGIC_STARTER_SOCIAL_IOS_REDIRECT` | A custom scheme URL: `myapp://auth/social`. The scheme is what the app listens on. An https callback would need iOS 17.4. |
| `callback.android` | `String` | `MAGIC_STARTER_SOCIAL_ANDROID_REDIRECT` | An https App Link: `https://auth.example.com/auth/social`. Its host and path become the Auth Tab's `httpsHost` and `httpsPath`, and the `CallbackActivity` intent filter. Use a dedicated host that no other App Link filter in the app claims. |

There is no web key: the web flow lands on the app's own `/auth.html` (the backend's `MAGIC_STARTER_SOCIAL_WEB_REDIRECT`).

A flow that needs a callback which is empty throws a `SocialAuthException` that names the key (`Set social_auth.callback.ios to the URL the backend redirects ios to.`). A callback is needed by GitHub and Microsoft on iOS and Android, and by Apple on Android. Google and Apple on iOS use native sheets, Google on Android does too, and the web needs no callback key.

## UI Overrides

Read by `SocialAuthButtons` from each provider's entry. When omitted, the widget falls back to the built-in defaults.

| Key | Type | Description |
|:----|:-----|:------------|
| `label` | `String` | Name shown on the button (`Google` becomes `Sign in with Google` through `auth.sign_in_with`). |
| `icon_svg` | `String` | Raw SVG string for the icon. Overrides the built-in one. |
| `icon_class` | `String` | Class applied to the icon element. Google and Microsoft default to `w-5 h-5`; GitHub and Apple default to `fill-slate-900 dark:fill-white`, a fill with no size. A value you set replaces the default instead of adding to it, so repeat the classes you still want. |
| `order` | `int` | Rendering order, lower first. Built-in order is Google 1, Microsoft 2, GitHub 3, Apple 4. On iOS Apple is always first, as Apple's review guidelines expect. |

> [!TIP]
> For a custom provider registered with `SocialAuth.manager.extend()`, call `SocialAuth.manager.registerProviderDefaults()` instead of per-config overrides, so the defaults are available regardless of config state.

## Button Widget

`SocialAuthButtons` renders one button per provider that is enabled and runs on this platform, in `order`, with Apple first on iOS. It renders nothing when no provider qualifies. It is built from Wind widgets, so it needs a `WindTheme` above it (`MagicApplication` provides one).

```dart
import 'package:flutter/widgets.dart';
import 'package:magic_social_auth/magic_social_auth.dart';

Widget buildButtons({
  required String? signingInWith,
  required void Function(String provider) onPressed,
}) {
  return SocialAuthButtons(
    onPressed: onPressed,
    loadingProvider: signingInWith,
    mode: SocialAuthMode.signUp,
    labelBuilder: (provider, mode) => 'Continue with $provider',
  );
}
```

| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `onPressed` | `void Function(String provider)` | required | Called synchronously from the tap with the config name (`google`). Start `SocialAuth.driver(provider).signIn()` here with no `await` before it, or a web popup is blocked. |
| `loadingProvider` | `String?` | `null` | The provider whose flow is running: its button shows a spinner and the others are disabled. An empty string disables every button without a spinner; `null` leaves them all enabled. |
| `mode` | `SocialAuthMode` | `SocialAuthMode.signIn` | `signIn` or `signUp`. Picks the label translation, `auth.sign_in_with` or `auth.sign_up_with`. |
| `labelBuilder` | `String Function(String provider, SocialAuthMode mode)?` | `null` | Builds each label instead of the translation lookup. `provider` is the display label (`Google`, or the config `label`), not the config name. |
| `className` | `String?` | `flex flex-col items-stretch` | Wind classes of the column that holds the buttons. A value replaces the default. |
| `buttonClassName` | `String?` | a full-width, bordered card | Wind classes of every button. A value replaces the default, including the dimmed look of a disabled button, so repeat the classes you still want. |

## Keys Owned by Other Packages

| Key | Owner | Used for |
|:----|:------|:---------|
| `network.drivers.api.base_url` | magic | The backend base URL. The browser flow starts at `<base_url>/auth/social/{provider}/redirect`, and the native and exchange calls go through the same `Http` facade, so the auth interceptor attaches the bearer a connect or confirm needs. |
| `auth.sign_in_with`, `auth.sign_up_with` | your app's translations | Button labels, with a `:provider` placeholder. |

## Minimal Example

Google and GitHub only, no Apple. On a project with an `ios/` folder, `social:doctor` reports Apple as disabled against App Store guideline 4.8 and exits with code 1; the example is valid config, but an iOS app that ships it should enable Apple too.

```dart
Map<String, dynamic> get socialAuthConfig => {
  'social_auth': {
    'providers': {
      'google': {
        'enabled': true,
        'ios_client_id': '123-abc.apps.googleusercontent.com',
        'server_client_id': '123-def.apps.googleusercontent.com',
      },
      'github': {
        'enabled': true,
      },
    },
    'callback': {
      'ios': 'myapp://auth/social',
      'android': 'https://auth.example.com/auth/social',
    },
  },
};
```

Register it in `Magic.init`:

```dart
await Magic.init(
  configFactories: [
    () => appConfig,
    () => socialAuthConfig,
  ],
);
```

> [!NOTE]
> `social:doctor` fails an empty `callback.android` on an Android project as soon as GitHub is enabled, because GitHub signs in through the browser flow there. With only Google enabled the callbacks may stay empty on mobile, since Google signs in natively.

## Related Documentation

- [Installation](https://anilcancakir.com/magic/docs/social_auth/getting-started/installation.md): `social:install` flags and `social:doctor` checks.
- [Drivers](https://anilcancakir.com/magic/docs/social_auth/basics/drivers.md): which driver reads which key.
- [Flows](https://anilcancakir.com/magic/docs/social_auth/basics/flows.md): how the callbacks are used by the browser flow.
- [Architecture overview](https://anilcancakir.com/magic/docs/social_auth/architecture/overview.md): how the manager resolves a provider from this config.
