diff --git a/docs/components/features.tsx b/docs/components/features.tsx
index d7c81dbbb1..62a96b4ee6 100644
--- a/docs/components/features.tsx
+++ b/docs/components/features.tsx
@@ -188,8 +188,9 @@ export default function Features({ stars }: { stars: string | null }) {
"svelteKit",
"astro",
"solidStart",
- "react",
- "hono",
+ // "react",
+ // "hono",
+ "expo",
"tanstack",
]}
/>
diff --git a/docs/components/icons.tsx b/docs/components/icons.tsx
index a5504cadb5..ecdcf89b9b 100644
--- a/docs/components/icons.tsx
+++ b/docs/components/icons.tsx
@@ -398,6 +398,7 @@ export const Icons = {
width="1.2em"
height="1.2em"
viewBox="0 0 32 32"
+ {...props}
>
,
},
+ expo: {
+ name: "Expo",
+ icon: ,
+ },
};
diff --git a/docs/content/docs/installation.mdx b/docs/content/docs/installation.mdx
index b745bcba45..df02289dea 100644
--- a/docs/content/docs/installation.mdx
+++ b/docs/content/docs/installation.mdx
@@ -236,7 +236,7 @@ Create a new file or route in your framework's designated catch-all route handle
Better Auth supports any backend framework with standard Request and Response objects and offers helper functions for popular frameworks.
-
+
```ts title="/app/api/auth/[...all]/route.ts"
import { auth } from "@/lib/auth"; // path to your auth file
@@ -369,6 +369,14 @@ Better Auth supports any backend framework with standard Request and Response ob
});
```
+
+ ```ts title="app/api/auth/[..all]+api.ts"
+ import { auth } from '@/lib/server/auth'; // path to your auth file
+
+ const handler = auth.handler;
+ export { handler as GET, handler as POST };
+ ```
+
diff --git a/docs/content/docs/integrations/expo.mdx b/docs/content/docs/integrations/expo.mdx
index 5138bdfa14..08e850de3c 100644
--- a/docs/content/docs/integrations/expo.mdx
+++ b/docs/content/docs/integrations/expo.mdx
@@ -13,6 +13,15 @@ Expo is a popular framework for building cross-platform apps with React Native.
Before using Better Auth with Expo, make sure you have a Better Auth backend set up. You can either use a separate server or leverage Expo's new [API Routes](https://docs.expo.dev/router/reference/api-routes) feature to host your Better Auth instance.
To get started, check out our [installation](/docs/installation) guide for setting up Better Auth on your server.
+
+ To use the new API routes feature in Expo to host your Better Auth instance you can create a new API route in your Expo app and mount the Better Auth handler.
+
+ ```ts title="app/api/auth/[...auth]+api.ts"
+ import { auth } from "@/lib/auth"; // import Better Auth handler
+
+ const handler = auth.handler;
+ export { handler as GET, handler as POST }; // export handler for both GET and POST requests
+ ```
## Install Better Auth and Expo Plugin
@@ -57,4 +66,159 @@ Expo is a popular framework for building cross-platform apps with React Native.
+## Usage
+### Authenticating Users
+
+With Better Auth initialized, you can now use the `authClient` to authenticate users in your Expo app.
+
+
+
+ ```tsx title="app/sign-in.tsx"
+ import { useState } from 'react';
+ import { View, TextInput, Button } from 'react-native';
+ import { authClient } from './auth-client';
+
+ export default function App() {
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+
+ const handleLogin = async () => {
+ await authClient.signIn.email({
+ email,
+ password,
+ })
+ };
+
+ return (
+
+
+
+
+
+ );
+ }
+ ```
+
+
+ ```tsx title="app/sign-up.tsx"
+ import { useState } from 'react';
+ import { View, TextInput, Button } from 'react-native';
+ import { authClient } from './auth-client';
+
+ export default function App() {
+ const [email, setEmail] = useState('');
+ const [name, setName] = useState('');
+ const [password, setPassword] = useState('');
+
+ const handleLogin = async () => {
+ await authClient.signUp.email({
+ email,
+ password,
+ name
+ })
+ };
+
+ return (
+
+
+
+
+
+
+ );
+ }
+ ```
+
+
+
+For social sign-in, you can use the `authClient.signIn.social` method with the provider name and a callback URL.
+
+```tsx title="app/social-sign-in.tsx"
+
+import { Button } from 'react-native';
+
+export default function App() {
+ const handleLogin = async () => {
+ await authClient.signIn.social({
+ provider: 'google',
+ callbackURL: "/dashboard" // this will be converted to a deep link (eg. `myapp://dashboard`) on native
+ })
+ };
+ return ;
+}
+```
+
+### Session
+
+Better Auth provides a `useSession` hook to access the current user's session in your app.
+
+```tsx title="src/App.tsx"
+
+import { authClient } from '@/lib/auth-client';
+
+export default function App() {
+ const { data: session } = authClient.useSession();
+
+ return Welcome, {data.user.name};
+}
+```
+
+On native, the session data will be cached in SecureStore. This will allow you to remove the need for a loading spinner when the app is reloaded. You can disable this behavior by passing the `disableCache` option to the client.
+
+## Options
+
+
+**storage**: on native you can pass a storage option to the client to change the storage mechanism. By default, the client will use SecureStore.
+
+```ts title="src/auth-client.ts"
+import { createAuthClient } from 'better-auth/react';
+import AsyncStorage from '@react-native-async-storage/async-storage';
+
+const authClient = createAuthClient({
+ basURL: 'http://localhost:8081',
+ storage: AsyncStorage
+});
+```
+
+**scheme**: scheme is used to deep link back to your app after a user has authenticated using oAuth providers. By default, Better Auth tries to read the scheme from the `app.json` file. If you need to override this, you can pass the scheme option to the client.
+
+```ts title="src/auth-client.ts"
+import { createAuthClient } from 'better-auth/react';
+
+const authClient = createAuthClient({
+ basURL: 'http://localhost:8081',
+ scheme: 'myapp'
+});
+```
+
+**disableCache**: By default, the client will cache the session data in SecureStore. You can disable this behavior by passing the `disableCache` option to the client.
+
+```ts title="src/auth-client.ts"
+import { createAuthClient } from 'better-auth/react';
+
+const authClient = createAuthClient({
+ basURL: 'http://localhost:8081',
+ disableCache: true
+});
+```
\ No newline at end of file
diff --git a/packages/expo/src/client.ts b/packages/expo/src/client.ts
index 91efb6425a..98757b531a 100644
--- a/packages/expo/src/client.ts
+++ b/packages/expo/src/client.ts
@@ -43,6 +43,7 @@ interface ExpoClientOptions {
getItem: (key: string) => string | null;
};
storagePrefix?: string;
+ disableCache?: boolean;
}
interface StoredCookie {
@@ -128,7 +129,10 @@ export const expoClient = (opts: ExpoClientOptions) => {
store?.notify("$sessionSignal");
}
- if (context.request.url.toString().includes("/get-session")) {
+ if (
+ context.request.url.toString().includes("/get-session") &&
+ !opts.disableCache
+ ) {
const data = context.data;
storage.setItem(localCacheName, JSON.stringify(data));
}