3. Build onboarding, authentication and profile
What we are building
A patient welcome flow with registration, sign-in, profile loading and a clear explanation of four separate choices: account data, health-platform access, wellness reflections and coach sharing.
What you should already have
- The project configured in step 2.
- An app shell with one persistent OvokClient and OvokProvider, following Native quick start and app shell.
- Patient registration enabled with a default Patient AccessPolicy.
The implementation
Compose the SDK's patient registration component in your Expo Router route. The registration workflow creates the Patient/account; do not create a second Patient resource after registration.
import { Register } from "@ovok/native";
import { useRouter } from "expo-router";
import { Alert, Text } from "react-native";
const tenantCode = process.env.EXPO_PUBLIC_TENANT_CODE;
if (!tenantCode) {
throw new Error("Set EXPO_PUBLIC_TENANT_CODE");
}
export default function RegisterScreen() {
const router = useRouter();
return (
<Register>
<Register.Header>
<Register.Header.Title />
<Register.Header.Description />
</Register.Header>
<Register.EmailForm
tenantCode={tenantCode}
onSuccess={() => router.replace("/onboarding/profile")}
onError={(error) => Alert.alert("Registration failed", error.message)}
>
<Register.EmailForm.Inputs />
<Register.EmailForm.RegisterButton />
</Register.EmailForm>
</Register>
);
}
For sign-in, set loginType="Patient", pass the same tenant code and use the Native SDK's SignIn.EmailForm with SignIn.EmailForm.Inputs and SignIn.EmailForm.SigninButton. The canonical authentication guide covers password recovery, MFA, error handling and account routes.
After registration, load the Patient associated with the active session:
import { useCurrentPatientProfile } from "@ovok/core";
export function ProfileGate() {
const { data, loading, error, reload } = useCurrentPatientProfile();
if (loading) return <Text>Loading your profile…</Text>;
if (error) return <Text onPress={reload}>Could not load your profile. Try again.</Text>;
if (!data) return <Text>Your patient profile is not available yet.</Text>;
return <Text>Welcome. Your Ovok profile is ready.</Text>;
}
Add the app-shell translation connection now. Initialize your single i18next instance with an English fallback and no app-owned local translation dictionary, then render the CMS hook once below OvokProvider:
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import { useCmsTranslations } from "@ovok/native";
i18n.use(initReactI18next).init({
fallbackLng: "en",
resources: {},
compatibilityJSON: "v4",
});
function CmsTranslations() {
useCmsTranslations({ tenantCode });
return null;
}
Create published translations documents in Ovok CMS for groups such as onboarding and profile. See Use Ovok CMS with i18n for group naming, language fallback and Console setup.
Mount <CmsTranslations /> once inside OvokProvider in the app layout, before the routed screens.
Explain these choices individually during onboarding:
- Account: credentials and profile needed to use the app.
- Health-platform access: optional read permission; the member can decline and continue.
- Weekly reflections: information the member enters for their own review.
- Coach sharing: a separate, explicit whole-record share in the current documented flow. Explain what it covers and how the patient can revoke it before inviting anyone.
Do not treat these as one consent checkbox. The product owner must define the appropriate privacy/legal notices and consent records for the deployment.
Important Ovok decisions
- Registration creates the Patient/account through Ovok's supported authentication flow.
useCurrentPatientProfileresolves the patient for the current session; do not trust a patient ID passed from a route as proof of identity.- CMS localizes app-owned UI text. The actual questionnaire's question content is FHIR data and is handled separately in step 6.
- Do not expose personal reflections to a coach until the member has completed the configured sharing flow.
Expected result
A synthetic patient can register, sign in, load their own profile and reach the authenticated area. The app has an English fallback and receives UI translations from Ovok CMS.
Common errors and troubleshooting
| Symptom | Check |
|---|---|
| Registration fails before account creation | Confirm tenant code, registration setting and default Patient AccessPolicy. |
| Profile is missing after successful registration | Keep the loading state; call reload and check the active project and session. Do not create a duplicate Patient to hide the error. |
| Sign-in or registration labels are untranslated | Confirm published CMS translation documents use the app's tenant and language. |
| The member thinks health data is mandatory | Make the health connection optional and provide a skip path. |