diff --git a/docs/data/toolpad/core/all-components/all-components.md b/docs/data/toolpad/core/all-components/all-components.md
index 7d4652725bb..c32844330c6 100644
--- a/docs/data/toolpad/core/all-components/all-components.md
+++ b/docs/data/toolpad/core/all-components/all-components.md
@@ -8,3 +8,4 @@
- [Dashboard Layout](/toolpad/core/react-dashboard-layout/)
- [Page Container](/toolpad/core/react-page-container/)
- [Sign-in Page](/toolpad/core/react-sign-in-page/)
+- [Sign-up Page](/toolpad/core/react-sign-up-page/)
diff --git a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js
index 536b3b76da4..4651293269b 100644
--- a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Credentials' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx
index f3d758e7263..028ec4fadee 100644
--- a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
+import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Credentials' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js
index 01d5cfe3684..b5c072efcaf 100644
--- a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
diff --git a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx
index 07e0fb1b9c4..ba36183446f 100644
--- a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
+import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
diff --git a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js
index 7e5269208e4..2f44fd91e64 100644
--- a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { hiIN } from '@toolpad/core/locales';
const providers = [
diff --git a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx
index 28cb13b4ef8..8450ec95d5d 100644
--- a/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/LocaleSignInPage.tsx
@@ -4,7 +4,7 @@ import {
SignInPage,
type AuthProvider,
type AuthResponse,
-} from '@toolpad/core/SignInPage';
+} from '@toolpad/core/AuthPage';
import { hiIN } from '@toolpad/core/locales';
const providers = [
diff --git a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js
index 73800c4d07b..28866594029 100644
--- a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { AppProvider } from '@toolpad/core/AppProvider';
import { useTheme } from '@mui/material/styles';
diff --git a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx
index f7e674890a2..8f11ee5a94a 100644
--- a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx
@@ -4,7 +4,7 @@ import {
SignInPage,
SupportedAuthProvider,
AuthResponse,
-} from '@toolpad/core/SignInPage';
+} from '@toolpad/core/AuthPage';
import { AppProvider } from '@toolpad/core/AppProvider';
import { useTheme } from '@mui/material/styles';
diff --git a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js
index 575370713a5..de983fc559b 100644
--- a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js
+++ b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Email and password' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx
index 373d8f60c03..0fe83f99d43 100644
--- a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx
@@ -4,7 +4,7 @@ import {
SignInPage,
type AuthProvider,
type AuthResponse,
-} from '@toolpad/core/SignInPage';
+} from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Email and password' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.js
index 508b1b47cdf..93208f4c351 100644
--- a/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
diff --git a/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.tsx
index 5b7bee73947..ec65e9ab28d 100644
--- a/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/OAuthSignInPage.tsx
@@ -1,10 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import {
- AuthResponse,
- SignInPage,
- type AuthProvider,
-} from '@toolpad/core/SignInPage';
+import { AuthResponse, SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
diff --git a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js
index ec39c35ddda..5b0aa402e88 100644
--- a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
const providers = [{ id: 'passkey', name: 'Passkey' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx
index 352bdc93677..88624c5563b 100644
--- a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage, AuthProvider } from '@toolpad/core/SignInPage';
+import { SignInPage, AuthProvider } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
// preview-start
const providers = [{ id: 'passkey', name: 'Passkey' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js
index 7272ae9cf59..322991d687a 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js
@@ -2,7 +2,7 @@ import * as React from 'react';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx
index 7272ae9cf59..322991d687a 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js
index e9b32bcb3c5..cd841e45633 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js
@@ -16,7 +16,7 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Email and Password' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx
index b2f8f3e7e50..925e6134455 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx
@@ -16,7 +16,7 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Email and Password' }];
diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js
index ad29307d2bd..1bb7c2ab001 100644
--- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { createTheme } from '@mui/material/styles';
import { useColorSchemeShim } from 'docs/src/modules/components/ThemeContext';
import { getDesignTokens, inputsCustomizations } from './customTheme';
diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx
index 19bff6a4b4f..73fd301eaff 100644
--- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx
@@ -4,7 +4,7 @@ import {
SignInPage,
type AuthProvider,
type AuthResponse,
-} from '@toolpad/core/SignInPage';
+} from '@toolpad/core/AuthPage';
import { createTheme } from '@mui/material/styles';
import { useColorSchemeShim } from 'docs/src/modules/components/ThemeContext';
import { getDesignTokens, inputsCustomizations } from './customTheme';
diff --git a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
index b315ac2ad87..1365d81dd78 100644
--- a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
+++ b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
@@ -18,7 +18,7 @@ The `SignInPage` component is a quick way to generate a ready-to-use authenticat
```tsx
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
export default function App() {
return (
@@ -36,6 +36,12 @@ export default function App() {
## OAuth
+:::warning
+
+This function works similarly to the sign-up flowγto authenticate users, but is focused on signing in existing accounts rather than creating new ones. For details on the sign-up flow, see the [Sign-up Page documentation](/toolpad/core/components/sign-up-page/).
+
+:::
+
The `SignInPage` component can be set up with an OAuth provider by passing in a list of providers in the `providers` prop, along with a `signIn` function that accepts the `provider` as a parameter.
{{"demo": "OAuthSignInPage.js", "iframe": true, "height": 600}}
@@ -177,7 +183,7 @@ To have a fully built "Sign in with GitHub" page appear at the `/auth/signin` ro
```tsx title="./app/auth/signin/page.tsx"
// ...
import * as React from 'react';
-import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
+import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { AuthError } from 'next-auth';
import { providerMap, signIn } from '../../../auth';
@@ -294,6 +300,12 @@ Beyond the [global localization options](/toolpad/core/introduction/base-concept
The `SignInPage` component has versions with different layouts for authentication - one column, two column and others such. The APIs of these components are identical. This is in progress.
+### π§ SignUp
+
+A dedicated `SignUpPage` component is planned to provide a seamless registration experience for new users. This will support multiple authentication providers and allow for custom fields, validation, and branding, similar to the `SignInPage`. Stay tuned for updates and check the [Sign-up Page documentation](/toolpad/core/components/sign-up-page/) for the latest information.
+
## π§ Other authentication flows
-Besides the `SignInPage` , the team is planning work on several other components that enable new workflows such as [sign up](https://github.com/mui/toolpad/issues/4068) and [password reset](https://github.com/mui/toolpad/issues/4265).
+Additional authentication flows such as password reset, multi-factor authentication (MFA), and account recovery are on the roadmap. These features aim to enhance security and user experience. Follow the [Toolpad GitHub issues](https://github.com/mui/toolpad/issues) for progress and upcoming releases.
+
+Besides the `SignInPage` , the team is planning work on several other components that enable new workflows such as [password reset](https://github.com/mui/toolpad/issues/4265).
diff --git a/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.js b/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.js
new file mode 100644
index 00000000000..ac2e8763dda
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.js
@@ -0,0 +1,35 @@
+import * as React from 'react';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { SignUpPage } from '@toolpad/core/AuthPage';
+import { useTheme } from '@mui/material/styles';
+
+// preview-start
+const providers = [{ id: 'credentials', name: 'Email and Password' }];
+// preview-end
+
+const signIn = async (provider, formData) => {
+ const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ alert(
+ `Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}`,
+ );
+ resolve();
+ }, 300);
+ });
+ return promise;
+};
+
+export default function CredentialsSignUpPage() {
+ const theme = useTheme();
+ return (
+ // preview-start
+
+
+
+ // preview-end
+ );
+}
diff --git a/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.tsx b/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.tsx
new file mode 100644
index 00000000000..4d90fb071a1
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.tsx
@@ -0,0 +1,38 @@
+import * as React from 'react';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { SignUpPage, type AuthProvider } from '@toolpad/core/AuthPage';
+import { useTheme } from '@mui/material/styles';
+
+// preview-start
+const providers = [{ id: 'credentials', name: 'Email and Password' }];
+// preview-end
+
+const signIn: (provider: AuthProvider, formData: FormData) => void = async (
+ provider,
+ formData,
+) => {
+ const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ alert(
+ `Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}`,
+ );
+ resolve();
+ }, 300);
+ });
+ return promise;
+};
+
+export default function CredentialsSignUpPage() {
+ const theme = useTheme();
+ return (
+ // preview-start
+
+
+
+ // preview-end
+ );
+}
diff --git a/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.tsx.preview b/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.tsx.preview
new file mode 100644
index 00000000000..2e78c08f2d0
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/CredentialsSignUpPage.tsx.preview
@@ -0,0 +1,11 @@
+const providers = [{ id: 'credentials', name: 'Email and Password' }];
+
+// ...
+
+
+
+
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.js b/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.js
new file mode 100644
index 00000000000..34f8d536801
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.js
@@ -0,0 +1,39 @@
+import * as React from 'react';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { SignUpPage } from '@toolpad/core/AuthPage';
+import { useTheme } from '@mui/material/styles';
+
+const providers = [{ id: 'credentials', name: 'Email and password' }];
+
+const signUp = async (provider, formData) => {
+ const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ const email = formData?.get('email');
+ const password = formData?.get('password');
+ alert(
+ `Signing up with "${provider.name}" and credentials: ${email}, ${password}`,
+ );
+ // preview-start
+ resolve({
+ error: 'Invalid credentials.',
+ });
+ // preview-end
+ }, 300);
+ });
+ return promise;
+};
+
+export default function NotificationsSignUpPageError() {
+ const theme = useTheme();
+ return (
+ // preview-start
+
+
+
+ // preview-end
+ );
+}
diff --git a/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.tsx b/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.tsx
new file mode 100644
index 00000000000..1b355513223
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.tsx
@@ -0,0 +1,46 @@
+import * as React from 'react';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import {
+ SignUpPage,
+ type AuthProvider,
+ type SignUpActionResponse,
+} from '@toolpad/core/AuthPage';
+import { useTheme } from '@mui/material/styles';
+
+const providers = [{ id: 'credentials', name: 'Email and password' }];
+
+const signUp: (
+ provider: AuthProvider,
+ formData?: FormData,
+) => Promise | void = async (provider, formData) => {
+ const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ const email = formData?.get('email');
+ const password = formData?.get('password');
+ alert(
+ `Signing up with "${provider.name}" and credentials: ${email}, ${password}`,
+ );
+ // preview-start
+ resolve({
+ error: 'Invalid credentials.',
+ });
+ // preview-end
+ }, 300);
+ });
+ return promise;
+};
+
+export default function NotificationsSignUpPageError() {
+ const theme = useTheme();
+ return (
+ // preview-start
+
+
+
+ // preview-end
+ );
+}
diff --git a/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.tsx.preview b/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.tsx.preview
new file mode 100644
index 00000000000..3f42987e696
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/NotificationsSignUpPageError.tsx.preview
@@ -0,0 +1,13 @@
+resolve({
+ error: 'Invalid credentials.',
+});
+
+// ...
+
+
+
+
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.js b/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.js
new file mode 100644
index 00000000000..eccecc97253
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.js
@@ -0,0 +1,38 @@
+import * as React from 'react';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { SignUpPage } from '@toolpad/core/AuthPage';
+import { useTheme } from '@mui/material/styles';
+
+// preview-start
+const providers = [
+ { id: 'github', name: 'GitHub' },
+ { id: 'google', name: 'Google' },
+ { id: 'facebook', name: 'Facebook' },
+ { id: 'twitter', name: 'Twitter' },
+ { id: 'linkedin', name: 'LinkedIn' },
+];
+
+// preview-end
+
+const signUp = async (provider) => {
+ // preview-start
+ const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ console.log(`Sign up with ${provider.id}`);
+ resolve({ error: 'This is a fake error' });
+ }, 500);
+ });
+ // preview-end
+ return promise;
+};
+
+export default function OAuthSignUpPage() {
+ const theme = useTheme();
+ return (
+ // preview-start
+
+
+
+ // preview-end
+ );
+}
diff --git a/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.tsx b/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.tsx
new file mode 100644
index 00000000000..939d2be356f
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.tsx
@@ -0,0 +1,42 @@
+import * as React from 'react';
+import { AppProvider } from '@toolpad/core/AppProvider';
+import {
+ AuthProvider,
+ SignUpActionResponse,
+ SignUpPage,
+} from '@toolpad/core/AuthPage';
+import { useTheme } from '@mui/material/styles';
+
+// preview-start
+const providers = [
+ { id: 'github', name: 'GitHub' },
+ { id: 'google', name: 'Google' },
+ { id: 'facebook', name: 'Facebook' },
+ { id: 'twitter', name: 'Twitter' },
+ { id: 'linkedin', name: 'LinkedIn' },
+];
+
+// preview-end
+
+const signUp = async (provider: AuthProvider): Promise => {
+ // preview-start
+ const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ console.log(`Sign up with ${provider.id}`);
+ resolve({ error: 'This is a fake error' } as SignUpActionResponse);
+ }, 500);
+ }) as Promise;
+ // preview-end
+ return promise;
+};
+
+export default function OAuthSignUpPage() {
+ const theme = useTheme();
+ return (
+ // preview-start
+
+
+
+ // preview-end
+ );
+}
diff --git a/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.tsx.preview b/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.tsx.preview
new file mode 100644
index 00000000000..50c1ebf86b0
--- /dev/null
+++ b/docs/data/toolpad/core/components/sign-up-page/OAuthSignUpPage.tsx.preview
@@ -0,0 +1,22 @@
+const providers = [
+ { id: 'github', name: 'GitHub' },
+ { id: 'google', name: 'Google' },
+ { id: 'facebook', name: 'Facebook' },
+ { id: 'twitter', name: 'Twitter' },
+ { id: 'linkedin', name: 'LinkedIn' },
+];
+
+// ...
+
+const promise = new Promise((resolve) => {
+ setTimeout(() => {
+ console.log(`Sign up with ${provider.id}`);
+ resolve({ error: 'This is a fake error' } as SignUpActionResponse);
+ }, 500);
+}) as Promise;
+
+// ...
+
+
+
+
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-up-page/sign-up-page.md b/docs/data/toolpad/core/components/sign-up-page/sign-up-page.md
index ae978f3779a..207d36c3794 100644
--- a/docs/data/toolpad/core/components/sign-up-page/sign-up-page.md
+++ b/docs/data/toolpad/core/components/sign-up-page/sign-up-page.md
@@ -1,15 +1,104 @@
---
productId: toolpad-core
title: Sign-up Page
+components: SignUpPage
---
# Sign-up Page π§
-
A customizable sign-up component that abstracts away the pain needed to wire together a secure sign-up/register page for your application..
+
A customizable sign-up component that abstracts away the pain needed to wire together a secure sign-up/register page for your application.
+
+:::info
+If this is your first time using Toolpad Core, it's recommended to read about the [basic concepts](/toolpad/core/introduction/base-concepts/) first.
+:::
:::warning
-The Sign-up component isn't available yet, but you can upvote [**this GitHub issue**](https://github.com/mui/toolpad/issues/4068) to see it arrive sooner.
+This feature is currently experimental and may change in future releases.
+:::
+
+The `SignUpPage` component is a quick way to generate a ready-to-use registration page with multiple OAuth providers, or a credentials from.
+
+## Basic Usage
+
+```tsx
+import { AppProvider } from '@toolpad/core/AppProvider';
+import { SignUpPage } from '@toolpad/core/AuthPage';
+
+export default function App() {
+ return (
+
+ {
+ // Your sign in logic
+ }}
+ />
+
+ );
+}
+```
+
+## OAuth
+
+:::warning
+
+This function uses the same logic as the sign-in flow, but instead of authenticating an existing user, it creates a new user account with the selected provider. Make sure your `signUp` function handles user creation and any required validation or error handling for a smooth registration experience.
-Don't hesitate to leave a comment there to influence what gets built.
-Especially if you already have a use case for this component, or if you're facing a pain point with your current solution.
:::
+
+The `SignUpPage` component can be set up with an OAuth provider by passing in a list of providers in the `providers` prop, along with a `signUp` function that accepts the `provider` as a parameter.
+
+{{"demo": "OAuthSignUpPage.js", "iframe": true, "height": 600}}
+
+:::info
+
+The following OAuth providers are supported and maintained by default:
+
+- Google
+- GitHub
+- Facebook
+- Microsoft (Entra ID)
+- Apple
+- Auth0
+- AWS Cognito
+- GitLab
+- Instagram
+- LINE
+- Okta
+- FusionAuth
+- Twitter
+- TikTok
+- LinkedIn
+- Slack
+- Spotify
+- Twitch
+- Discord
+- Keycloak
+
+Find details on how to set up each provider in the [Auth.js documentation](https://authjs.dev/getting-started/authentication/oauth).
+:::
+
+## Credentials
+
+:::warning
+The Credentials provider is not the most secure way to authenticate users. It's recommended to use any of the other providers for a more robust solution.
+:::
+
+To use the Credentials provider, add it to the `providers` array and implement your own sign-up logic.
+
+{{"demo": "CredentialsSignUpPage.js", "iframe": true, "height": 600}}
+
+### Alerts
+
+The `signUp` prop takes a function which can either return `void` or a `Promise` which resolves with an `SignUpActionResponse` object of the form:
+
+```ts
+interface SignUpActionResponse {
+ error?: string;
+ success?: string;
+}
+```
+
+{{"demo": "NotificationsSignUpPageError.js", "iframe": true, "height": 600}}
+
+This renders an alert with the `error` string as the message.
diff --git a/docs/data/toolpad/core/integrations/nextjs-approuter.md b/docs/data/toolpad/core/integrations/nextjs-approuter.md
index 993f6964071..063aa582ded 100644
--- a/docs/data/toolpad/core/integrations/nextjs-approuter.md
+++ b/docs/data/toolpad/core/integrations/nextjs-approuter.md
@@ -181,7 +181,7 @@ Use the `SignInPage` component to add a sign-in page to your app. For example, `
```tsx title="app/auth/signin/page.tsx"
import * as React from 'react';
-import { SignInPage, type AuthProvider } from '@toolpad/core/SignInPage';
+import { SignInPage, type AuthProvider } from '@toolpad/core/AuthPage';
import { AuthError } from 'next-auth';
import { providerMap, signIn } from '../../../auth';
diff --git a/docs/data/toolpad/core/integrations/nextjs-pagesrouter.md b/docs/data/toolpad/core/integrations/nextjs-pagesrouter.md
index 6eac0cbe05d..ff72ddab7a8 100644
--- a/docs/data/toolpad/core/integrations/nextjs-pagesrouter.md
+++ b/docs/data/toolpad/core/integrations/nextjs-pagesrouter.md
@@ -337,7 +337,7 @@ Use the `SignInPage` component to add a sign-in page to your app. For example, `
import * as React from 'react';
import type { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import Link from '@mui/material/Link';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import { signIn } from 'next-auth/react';
import { useRouter } from 'next/router';
import { auth, providerMap } from '../../auth';
diff --git a/docs/data/toolpad/core/integrations/react-router.md b/docs/data/toolpad/core/integrations/react-router.md
index fa7218fdb51..ece06062c55 100644
--- a/docs/data/toolpad/core/integrations/react-router.md
+++ b/docs/data/toolpad/core/integrations/react-router.md
@@ -461,7 +461,7 @@ You can protect any page or groups of pages through this mechanism.
```tsx title="src/pages/signIn.tsx"
'use client';
import * as React from 'react';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
import LinearProgress from '@mui/material/LinearProgress';
import { Navigate, useNavigate } from 'react-router';
import { useSession, type Session } from '../SessionContext';
diff --git a/docs/data/toolpad/core/introduction/base-concepts.md b/docs/data/toolpad/core/introduction/base-concepts.md
index 1330fb1fd23..3bdc1103757 100644
--- a/docs/data/toolpad/core/introduction/base-concepts.md
+++ b/docs/data/toolpad/core/introduction/base-concepts.md
@@ -81,7 +81,7 @@ Toolpad Core uses slots for component customization. Slots allow you to override
Here's an example using the `SignInPage` component:
```tsx
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage } from '@toolpad/core/AuthPage';
function MyComponent() {
return (