diff --git a/README.md b/README.md
index 2a31d14a..33afe5be 100644
--- a/README.md
+++ b/README.md
@@ -14,40 +14,40 @@ npm install firebase
### Framework-specific Installation
-Packages have created for both `React` and `Angular`. For now, they're only available as direct downloads from this repository. Add the following to your `package.json` file:
+Packages have been created for both `React` and `Angular`. For now, they're only available as direct downloads from this repository. Add the following to your `package.json` file:
React
- ```json
- {
- "dependencies": {
- "@firebase-ui/react": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-react-0.0.1.tgz",
- "@firebase-ui/core": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-core-0.0.1.tgz",
- "@firebase-ui/styles": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-styles-0.0.1.tgz",
- "@firebase-ui/translations": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-translations-0.0.1.tgz",
- }
+```json
+{
+ "dependencies": {
+ "@firebase-ui/react": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-react-0.0.1.tgz",
+ "@firebase-ui/core": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-core-0.0.1.tgz",
+ "@firebase-ui/styles": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-styles-0.0.1.tgz",
+ "@firebase-ui/translations": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-translations-0.0.1.tgz"
}
- ```
+}
+```
Angular
- FirebaseUI for Angular depends on the [AngularFire](https://github.com/angular/angularfire) package:
-
- ```json
- {
- "dependencies": {
- "@angular/fire": "^19.1.0",
- "@firebase-ui/angular": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-angular-0.0.1.tgz",
- "@firebase-ui/core": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-core-0.0.1.tgz",
- "@firebase-ui/styles": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-styles-0.0.1.tgz",
- "@firebase-ui/translations": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-translations-0.0.1.tgz",
- }
+FirebaseUI for Angular depends on the [AngularFire](https://github.com/angular/angularfire) package:
+
+```json
+{
+ "dependencies": {
+ "@angular/fire": "^19.1.0",
+ "@firebase-ui/angular": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-angular-0.0.1.tgz",
+ "@firebase-ui/core": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-core-0.0.1.tgz",
+ "@firebase-ui/styles": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-styles-0.0.1.tgz",
+ "@firebase-ui/translations": "https://github.com/firebase/firebaseui-web/raw/refs/heads/v7-alpha/releases/firebase-ui-translations-0.0.1.tgz"
}
- ```
+}
+```
@@ -78,48 +78,48 @@ const ui = initializeUI();
React
- FirebaseUI for React requires that your application be wrapped in the `ConfigProvider`, providing the initialized UI configuration. React expects the `FirebaseApp` instance be provided to the `initializeUI` configuration:
+FirebaseUI for React requires that your application be wrapped in the `ConfigProvider`, providing the initialized UI configuration. React expects the `FirebaseApp` instance be provided to the `initializeUI` configuration:
- ```tsx
- import { initializeApp } from 'firebase/app';
- import { initializeUI } from "@firebase-ui/core";
- import { ConfigProvider } from '@firebase-ui/react';
-
- const app = initializeApp({ ... });
- const ui = initializeUI({ app });
-
- createRoot(document.getElementById("root")!).render(
-
-
-
-
-
- );
- ```
+```tsx
+import { initializeApp } from 'firebase/app';
+import { initializeUI } from "@firebase-ui/core";
+import { ConfigProvider } from '@firebase-ui/react';
+
+const app = initializeApp({ .. });
+const ui = initializeUI({ app });
+
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+);
+```
Angular
- FirebaseUI depends on [AngularFire](https://github.com/angular/angularfire) being configured to inject Firebase Auth into your Angular application. Additionally, the `provideFirebaseUI` function is required to inject FirebaseUI into your application:
-
- ```tsx
- import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
- import { provideAuth, getAuth } from '@angular/fire/auth';
- import { provideFirebaseUI } from '@firebase-ui/angular';
- import { initializeUI } from '@firebase-ui/core';
-
- export const appConfig: ApplicationConfig = {
- providers: [
- provideFirebaseApp(() => initializeApp({ ... })),
- provideAuth(() => getAuth()),
- provideFirebaseUI(() => initializeUI({}))
- ...
- ],
- ...
- }
- ```
+FirebaseUI depends on [AngularFire](https://github.com/angular/angularfire) being configured to inject Firebase Auth into your Angular application. Additionally, the `provideFirebaseUI` function is required to inject FirebaseUI into your application:
+
+```tsx
+import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
+import { provideAuth, getAuth } from '@angular/fire/auth';
+import { provideFirebaseUI } from '@firebase-ui/angular';
+import { initializeUI } from '@firebase-ui/core';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideFirebaseApp(() => initializeApp({ .. })),
+ provideAuth(() => getAuth()),
+ provideFirebaseUI(() => initializeUI({}))
+ ..
+ ],
+ ..
+}
+```
@@ -153,45 +153,45 @@ Allows users to sign in with an email and password:
React
- ```tsx
- import { SignInAuthScreen } from '@firebase-ui/react';
+```tsx
+import { SignInAuthScreen } from "@firebase-ui/react";
- function App() {
- return
- }
- ```
+function App() {
+ return ;
+}
+```
- Props: `onForgotPasswordClick` / `onRegisterClick`
+Props: `onForgotPasswordClick` / `onRegisterClick`
- Additionally, allow the user to sign in with an OAuth provider by providing children:
+Additionally, allow the user to sign in with an OAuth provider by providing children:
- ```tsx
- import { SignInAuthScreen, GoogleSignInButton } from '@firebase-ui/react';
+```tsx
+import { SignInAuthScreen, GoogleSignInButton } from "@firebase-ui/react";
- function App() {
- return (
-
-
-
- );
- }
- ```
+function App() {
+ return (
+
+
+
+ );
+}
+```
Angular
- ```tsx
- import { SignUpAuthScreenComponent } from "@firebase-ui/angular";
+```tsx
+import { SignUpAuthScreenComponent } from "@firebase-ui/angular";
- @Component({
- selector: 'app-root',
- imports: [SignUpAuthScreenComponent],
- template: ``,
- })
- export class AppComponent { }
- ```
+@Component({
+ selector: "app-root",
+ imports: [SignUpAuthScreenComponent],
+ template: ``,
+})
+export class AppComponent {}
+```
@@ -255,3 +255,317 @@ The package uses CSS Variables, which can be overridden in your application's CS
```
The default values are based on the [TailwindCSS](https://tailwindcss.com/docs/theme) theme variables. You can override these values with other TailwindCSS theme variables, or custom CSS values.
+
+## FirebaseUI Core Integration
+
+`@firebase-ui/core` is a framework-agnostic layer that manages the complete lifecycle of Firebase Authentication flows. It exposes a reactive store via nanostores that can be wrapped and adapted into any JavaScript framework such as React, Angular, Vue, Svelte, or SolidJS to name a few.
+
+### What FirebaseUI Core Provides
+
+- Manages Firebase Authentication flows (sign-in, sign-out, linking, etc.)
+
+- Reactive UI state via [nanostores](https://github.com/nanostores/nanostores)
+
+- Form schemas using [Zod](https://zod.dev/)
+
+- Pluggable behaviors (e.g. autoAnonymousLogin)
+
+- i18n and translations
+
+- Error parsing and localization
+
+#### Initialize the Core
+
+Call initializeUI() with your Firebase app and configuration options:
+
+```js
+import { initializeUI } from '@firebase-ui/core';
+
+const ui = initializeUI({
+ app: firebaseApp,
+ ..
+});
+```
+
+Configuration Type:
+
+```js
+type FirebaseUIConfigurationOptions = {
+ app: FirebaseApp;
+ locale?: Locale | undefined;
+ translations?: RegisteredTranslations[] | undefined;
+ behaviors?: Partial>[] | undefined;
+ recaptchaMode?: 'normal' | 'invisible' | undefined;
+};
+```
+
+#### Firebase Authentication Flows
+
+**signInWithEmailAndPassword**: Signs in the user based on an email/password credential.
+
+- _ui_: FirebaseUIConfiguration
+- _email_: string
+- _password_: string
+
+**createUserWithEmailAndPassword**: Creates a user account based on an email/password credential.
+
+- _ui_: FirebaseUIConfiguration
+- _email_: string
+- _password_: string
+
+**signInWithPhoneNumber**: Signs in the user based on a provided phone number, using ReCaptcha to verify the sign-in.
+
+- _ui_: FirebaseUIConfiguration
+- _phoneNumber_: string
+- _recaptchaVerifier_: string
+
+**confirmPhoneNumber**: Verifies the phonenumber credential and signs in the user.
+
+- _ui_: FirebaseUIConfiguration
+- _confirmationResult_: [ConfirmationResult](https://firebase.google.com/docs/reference/node/firebase.auth.ConfirmationResult)
+- _verificationCode_: string
+
+**sendPasswordResetEmail**: Sends password reset instructions to an email account.
+
+- _ui_: FirebaseUIConfiguration
+- _email_: string
+
+**sendSignInLinkToEmail**: Send an sign-in links to an email account.
+
+- _ui_: FirebaseUIConfiguration
+- _email_: string
+
+**signInWithEmailLink**: Signs in with the user with the email link. If `autoUpgradeAnonymousCredential` then a pending credential will be handled.
+
+- _ui_: FirebaseUIConfiguration
+- _email_: string
+- _link_: string
+
+**signInAnonymously**: Signs in as an anonymous user.
+
+- _ui_: FirebaseUIConfiguration
+
+**signInWithOAuth**: Signs in with a provider such as Google via a redirect link. If `autoUpgradeAnonymousCredential` then the account will upgraded.
+
+- _ui_: FirebaseUIConfiguration
+- _provider_: [AuthProvider](https://firebase.google.com/docs/reference/node/firebase.auth.AuthProvider)
+
+**completeEmailLinkSignIn**: Completes the signing process based on a user signing in with an email link.
+
+- _ui_: FirebaseUIConfiguration
+- _currentUrl_: string
+
+#### Provide a Store via Context
+
+Using the returned `FirebaseUIConfiguration`, it is reccomended to use local context/providers/dependency-injection to expose the FirebaseUIConfiguration to the application. Here is an example context wrapper which accepts the configuration as a `ui` parameter:
+
+```js
+/** Creates a framework-agnostic context for Firebase UI configuration **/
+export function createFirebaseUIContext(initialConfig) {
+ let config = initialConfig;
+ const subscribers = new Set();
+
+ return {
+ /** Retrieve current config **/
+ getConfig() {
+ return config;
+ },
+
+ /** Update config and notify subscribers **/
+ setConfig(newConfig) {
+ config = newConfig;
+ subscribers.forEach((callback) => callback(config));
+ },
+
+ /** Subscribe to config changes (for use in any framework) **/
+ subscribe(callback) {
+ subscribers.add(callback);
+ /** Optionally call immediately with current config**/
+ callback(config);
+ return () => subscribers.delete(callback);
+ },
+ };
+}
+```
+
+FirebaseUI Configuration Type:
+
+```js
+export type FirebaseUIConfiguration = {
+ app: FirebaseApp,
+ getAuth: () => Auth,
+ setLocale: (locale: Locale) => void,
+ state: FirebaseUIState,
+ setState: (state: FirebaseUIState) => void,
+ locale: Locale,
+ translations: TranslationsConfig,
+ behaviors: Partial>,
+ recaptchaMode: "normal" | "invisible",
+};
+```
+
+Through this approach, you can now achieve global access to the FirebaseUI methods and state.
+
+#### State Management
+
+FirebaseUI Core provides built-in state management to track the current step in the authentication flow. This can be used to drive UI transitions, control rendering, or show progress indicators.
+
+##### Available States
+
+```js
+type FirebaseUIState =
+ | "loading"
+ | "idle"
+ | "signing-in"
+ | "signing-out"
+ | "linking"
+ | "creating-user"
+ | "sending-password-reset-email"
+ | "sending-sign-in-link-to-email";
+```
+
+These represent the current phase of the user experience — such as waiting for input, submitting credentials, or linking accounts.
+
+##### Updating State Manually
+
+The core module automatically updates state based on auth activity, but you can also override it manually if needed:
+
+```js
+/** Set the UI state to "idle" **/
+ui.setState("idle");
+```
+
+##### Reading State in Your App
+
+In a component, you can access the current state through the FirebaseUI configuration:
+
+```js
+/** Sample: Framework-agnostic UI state management **/
+
+/** Create a simple UI state store with an initial state **/
+const uiStore = createUIStateStore({ state: "idle" });
+
+uiStore.subscribe((ui) => {
+ /** Replace `showSpinner` and `showMainApp` with your actual rendering logic **/
+ if (ui.state === "signing-in") {
+ showSpinner();
+ } else {
+ showMainApp();
+ }
+});
+```
+
+### Translations (i18n)
+
+You can pass one or more translations to support localized strings.
+
+```js
+import { english } from "@firebase-ui/translations";
+
+initializeUI({
+ app,
+ locale: "en",
+ translations: [english],
+});
+```
+
+To override or add your own strings:
+
+```js
+const customFr = {
+ locale: "fr",
+ translations: {
+ errors: {
+ invalidEmail: "Adresse e-mail invalide",
+ },
+ },
+};
+```
+
+To use a string at runtime (e.g., in an error message):
+
+```js
+import { getTranslation } from "@firebase-ui/core";
+
+const message = getTranslation(config, "errors", "unknownError");
+```
+
+**When multiple translation sets are passed, FirebaseUI merges them in order — allowing you to layer overrides on top of built-in language packs.**
+
+### Form Schemas
+
+FirebaseUI uses Zod to validate authentication forms. This ensures consistent, strongly typed, and localized error handling across form components.
+
+Each schema can be used standalone or integrated into your custom forms. You can pass in a TranslationsConfig object to localize error messages.
+
+#### Available Schemas
+
+**createEmailFormSchema(translations?)**
+Validates a sign-in or sign-up form using email and password.
+
+- _email_: Must be a valid email address.
+
+- _password_: Must be at least 8 characters.
+
+```js
+import { createEmailFormSchema } from "@firebase-ui/core";
+
+const schema = createEmailFormSchema(translations);
+```
+
+**createForgotPasswordFormSchema(translations?)**
+Validates the forgot password form.
+
+- _email_: Must be a valid email address.
+
+```js
+const schema = createForgotPasswordFormSchema(translations);
+```
+
+**createEmailLinkFormSchema(translations?)**
+Validates the email link authentication form.
+
+- _email_: Must be a valid email address.
+
+```js
+const schema = createEmailLinkFormSchema(translations);
+```
+
+**createPhoneFormSchema(translations?)**
+Validates the phone number authentication form using reCAPTCHA.
+
+- _phoneNumber_: Must be a valid phone number with at least 10 digits.
+
+- _verificationCode_: Optional, must be at least 6 digits if provided.
+
+- _recaptchaVerifier_: Must be an instance of RecaptchaVerifier.
+
+```js
+const schema = createPhoneFormSchema(translations);
+```
+
+#### Handling Form Errors
+
+Handling errors can be managed using [Zods parsing functions](http://zod.dev/basics?ref=ossgallery&id=handling-errors) such as `safeParse`
+
+### Error Handling
+
+The core library provides a function for handling errors.
+
+#### handleFirebaseError()
+
+```js
+export function handleFirebaseError(
+ ui: FirebaseUIConfiguration,
+ error: any,
+ opts?: {
+ enableHandleExistingCredential?: boolean;
+ }
+)
+```
+
+This function will run through a series of checks to catch known Firebase errors:
+
+1. `auth/account-exists-with-different-credential`: Checking the error code to see if an account already exists for the user. If `enableHandleExistingCredential` is enabled the library will update the local storage automtaically before throwing the error.
+
+2. `FirebaseUIError`: Alternatively, a FirebaseUIError will be thrown with the appropriate code.