GuidesComponentsAuth ComponentsSign-In

SignIn.SocialLogins

Container component for grouping social login buttons with consistent styling and layout

  • Stable unknown
  • Release candidate since 1.16.1-rc.3
  • Development since 1.16.1-dev.2111+9796905

Container component that groups social login buttons with consistent horizontal layout and spacing.

Provider requirement

The social-login buttons use the SDK theme for spacing, colors and typography. Render them inside the SDK ThemeProvider (usually imported as ThemeProvider as OvokThemeProvider) and the OvokProvider from @ovok/core/next/react, as shown in the installation guide. A cancelled Apple prompt is treated as a cancellation and does not call onError; successful login sessions retain both the FHIR reference and its display value.

Prerequisites

Before using social login components, you need to complete the following setup steps:

Google Login Setup

  1. Get Google Credentials: Obtain your Google client ID and iOS URL scheme from Google Cloud Console. For further information please follow this guide
  2. Configure App: Update your app.config.js or app.json with the Google Sign-In plugin:
// app.config.js
export default {
  expo: {
    plugins: [
      [
        "@react-native-google-signin/google-signin",
        {
          iosUrlScheme: "com.googleusercontent.apps.YOUR_CLIENT_ID",
        },
      ],
    ],
  },
};

For detailed Google Sign-In configuration, see the Installation Guide.

Apple Login Setup

Apple authentication requires the Apple authentication plugin and a native rebuild. See the Installation Guide.

Ovok Dashboard Configuration

Both Google and Apple login methods require configuration in the Ovok Dashboard:

  1. Navigate to the Ovok Dashboard
  2. Update or Create a ClientApplication with the following extension configuration:
{
  "extension": [
    {
      "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-internal-id",
      "valueString": "google-web-app-id",
      "extension": [
        {
          "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-client-id",
          "valueString": "605727522930-c06g9o9f4t906fqt9bkg6sncdn4lb504.apps.googleusercontent.com"
        },
        {
          "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-provider-type",
          "valueString": "google"
        }
      ]
    }
  ]
}

Configuration Values:

  • external-auth-internal-id: Custom identifier for matching (use this value in the internalId prop)
  • external-auth-client-id:
    • For Google: Your Google client ID from Google Cloud Console
    • For Apple: Your app's bundle identifier, or the Services ID for the web entry
  • external-auth-provider-type: Set to "google" or "apple"

Native client configuration

After configuring the ClientApplication in the Ovok Dashboard, pass its ID as clientId to the native client:

// app/_layout.tsx
import { Ovok } from "@ovok/native/next";
import * as SecureStore from "expo-secure-store";

const ovokClient = new Ovok({
  baseUrl: "https://api.example.com",
  tenantCode: "your-tenant",
  secureStore: SecureStore,
  clientId: "YOUR_CLIENT_APPLICATION_ID",
});

Important: Replace YOUR_CLIENT_APPLICATION_ID with the actual ClientApplication ID from your Ovok Dashboard configuration.

Sign in on the web

On React Native Web the same buttons work with no extra setup in the bundle. The SDK ships web versions of GoogleLogin and AppleLogin (.web platform files), so a web bundle never loads @react-native-google-signin/google-signin or expo-apple-authentication. The buttons look and compose as on a phone; the web needs these props in addition:

ButtonWeb propMeaning
GoogleLogingoogleWebClientIdThe Google Web application client ID. googleIosClientId is ignored.
GoogleLogingoogleRedirectUriOptional. The page Google returns to; defaults to /oauth/google.html on your site.
AppleLoginappleServicesIdThe Apple Services ID. Without it the button renders nothing on the web.
AppleLoginappleRedirectUriOptional. A Return URL of the Services ID; defaults to your site's origin.

Google on the web

Google signs the user in with an OpenID Connect redirect in the same tab: the page goes to Google, Google returns to a static page of yours, and that page sends the tab back to the sign-in screen. Keep GoogleLogin on that screen: when it mounts, it takes Google's answer, checks that it answers this tab's own request, and signs in.

1. Authorize the redirect URI. In the Google Cloud Console, open the OAuth client of type Web application and add the return page to Authorized redirect URIs, for example https://app.example.com/oauth/google.html (and http://localhost:8081/oauth/google.html for local development).

2. Serve the return page as a static file. The SDK exports its HTML as GOOGLE_RETURN_PAGE_HTML, and @ovok/native/auth/google-return-page loads in plain Node, so a build step can write it into the folder your app serves, such as Expo's public/:

// scripts/write-google-return-page.cjs
const { mkdirSync, writeFileSync } = require("node:fs");
const { GOOGLE_RETURN_PAGE_HTML } = require("@ovok/native/auth/google-return-page");

mkdirSync("public/oauth", { recursive: true });
writeFileSync("public/oauth/google.html", GOOGLE_RETURN_PAGE_HTML);

Run it before the web build, for example as "prebuild:web": "node scripts/write-google-return-page.cjs". To serve the page somewhere else, register that URL and pass it as googleRedirectUri.

3. Point Ovok at the Web client. The external-auth-client-id of the Google entry is the Web client ID, and its external-auth-internal-id is the internalId you pass to GoogleLogin.

The page keeps Google's answer in the tab's sessionStorage and replaces itself with the screen the user left, so the ID token never stays in the address bar or the history. The button accepts the answer only when its state and its token's nonce match the request this tab made, and it clears both from storage either way.

Apple on the web

Apple signs the user in with Sign in with Apple JS in a popup. The button loads Apple's script when it mounts, so the popup opens straight from the tap.

1. Create a Services ID. In the Apple Developer account, create a Services ID and enable Sign in with Apple for it. Under Configure, choose the primary App ID and add your domain and the Return URL, for example app.example.com and https://app.example.com. The Return URL is appleRedirectUri, which defaults to the site's origin. Apple does not accept localhost, so test on an HTTPS domain registered for the Services ID.

2. Add a separate Ovok entry for the Services ID. Apple's web tokens have the Services ID as their audience, while the iOS app's tokens have its bundle ID, so one entry cannot verify both. Add the entry to the ClientApplication's extension array, and pass its internalId to AppleLogin on the web:

{
  "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-internal-id",
  "valueString": "apple-web",
  "extension": [
    {
      "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-client-id",
      "valueString": "com.example.web"
    },
    {
      "url": "https://api.ovok.com/fhir/StructureDefinition/external-auth-provider-type",
      "valueString": "apple"
    }
  ]
}

A closed popup and a declined authorization are cancellations and do not call onError. Apple sends the name and email only the first time a user signs in with your app.

One screen for every platform

import { Platform } from "react-native";

<SignIn.SocialLogins.GoogleLogin
  googleIosClientId={googleIosClientId}
  googleWebClientId={googleWebClientId}
  internalId="google"
>
  <SignIn.SocialLogins.GoogleLogin.Icon />
  <SignIn.SocialLogins.GoogleLogin.Text />
</SignIn.SocialLogins.GoogleLogin>

<SignIn.SocialLogins.AppleLogin
  internalId={Platform.OS === "web" ? "apple-web" : "apple"}
  appleServicesId={appleServicesId}
>
  <SignIn.SocialLogins.AppleLogin.Icon />
  <SignIn.SocialLogins.AppleLogin.Text />
</SignIn.SocialLogins.AppleLogin>

useSocialSignIn has no web flow and rejects on the web; render the buttons instead.

Quick Example

import { SignIn, useAppTheme } from "@ovok/native";
import React from "react";
import { Alert, StyleSheet } from "react-native";

// Static styles outside component
const styles = StyleSheet.create({
  socialContainer: {
    alignItems: "center",
  },
});

const SocialLoginSection = () => {
  const theme = useAppTheme();

  const handleSuccess = () => Alert.alert("Signed in");

  const handleError = (error: Error) => Alert.alert("Sign-in failed", error.message);

  return (
    <SignIn.SocialLogins
      style={[
        styles.socialContainer,
        {
          marginVertical: theme.spacing(3),
        },
      ]}
    >
      <SignIn.SocialLogins.GoogleLogin
        googleIosClientId="your-ios-client-id.googleusercontent.com" // This will be used for ios devices
        googleWebClientId="your-web-client-id.googleusercontent.com" // This will be used for android devices
        internalId="google-login" // This is the name that you add in extension of ClientApplication for google provider
        onSuccess={handleSuccess}
        onError={handleError}
      >
        <SignIn.SocialLogins.GoogleLogin.Icon />
        <SignIn.SocialLogins.GoogleLogin.Text>
          Continue with Google
        </SignIn.SocialLogins.GoogleLogin.Text>
      </SignIn.SocialLogins.GoogleLogin>

      <SignIn.SocialLogins.AppleLogin
        internalId="apple-login" // This is the name that you add in extension of ClientApplication for apple provider
        onSuccess={handleSuccess}
        onError={handleError}
      >
        <SignIn.SocialLogins.AppleLogin.Icon />
        <SignIn.SocialLogins.AppleLogin.Text>
          Continue with Apple
        </SignIn.SocialLogins.AppleLogin.Text>
      </SignIn.SocialLogins.AppleLogin>
    </SignIn.SocialLogins>
  );
};

export default SocialLoginSection;

Props

Every prop, with its type and description, is listed in the @ovok/native/auth API reference.

Component Behavior

The component uses horizontal layout with flexDirection: "row", justifyContent: "center", and flexWrap: "wrap" to center social login buttons and allow wrapping on smaller screens.

Styling

Theme Variables Used

  • theme.spacing(6) - Gap spacing between child components used by default

Child Components

Last updated on

On this page