Authenticator Container, Header & Footer Slots
The Authenticator has several "slots" that you can customize to add messaging & functionality to meet your app's needs.
The Authenticator itself has the following optional slots which are rendered on each subcomponent:
Container
- Wraps theAuthenticator
. Can be overridden by extendingAuthenticator.Container
or with aView
componentFooter
- renders below subcomponent content, no default providedHeader
- renders above subcomponent content, no default provided
The default
Container
component contains keyboard aware scroll behavior.
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { Amplify } from 'aws-amplify';
import {
Authenticator,
useAuthenticator,
useTheme,
} from '@aws-amplify/ui-react-native';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
const MyAppHeader = () => {
const {
tokens: { space, fontSizes },
} = useTheme();
return (
<View>
<Text style={{ fontSize: fontSizes.xxxl, padding: space.xl }}>
My Header
</Text>
</View>
);
};
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button onPress={signOut} title="Sign Out" />;
}
function App() {
const {
tokens: { colors },
} = useTheme();
return (
<Authenticator.Provider>
<Authenticator
// will wrap every subcomponent
Container={(props) => (
// reuse default `Container` and apply custom background
<Authenticator.Container
{...props}
style={{ backgroundColor: colors.pink[20] }}
/>
)}
// will render on every subcomponent
Header={MyAppHeader}
>
<View style={style.container}>
<SignOutButton />
</View>
</Authenticator>
</Authenticator.Provider>
);
}
const style = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
});
export default App;
Subcomponent Header & Footer Slots
Addtionally, the subcomponents themselves have Header
and Footer
slots specific to a subcomponent:
Footer
- renders below subcomponent buttons, above top levelFooter
, no default providedHeader
- renders above subcomponent content, below top levelHeader
, default renders subcomponent title
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { Amplify } from 'aws-amplify';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
const MySignInFooter = () => <Text>My Footer</Text>;
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button onPress={signOut} title="Sign Out" />;
}
function App() {
return (
<Authenticator.Provider>
<Authenticator
components={{
SignUp: (props) => (
// will render only on the SignIn subcomponent
<Authenticator.SignUp {...props} Footer={MySignInFooter} />
),
}}
>
<View style={style.container}>
<SignOutButton />
</View>
</Authenticator>
</Authenticator.Provider>
);
}
const style = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
});
export default App;
Subcomponent Override Slots
The Authenticator
subcomponents can be overridden allowing for advanced use cases:
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { Amplify } from 'aws-amplify';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button onPress={signOut} title="Sign Out" />;
}
const MySignIn = () => {
return (
<View>
<Text>My Sign In</Text>
</View>
);
};
function App() {
return (
<Authenticator.Provider>
<Authenticator
// render override SignIn subcomponent
components={{ SignIn: MySignIn }}
>
<View style={style.container}>
<SignOutButton />
</View>
</Authenticator>
</Authenticator.Provider>
);
}
const style = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
});
export default App;
Override Function Calls
You can override the call to signUp
, signIn
, confirmSignIn
, confirmSignUp
, forgotPassword
and forgotPasswordSubmit
functions.
To override a call you must create a new services
object with an async
handle*
function that returns an aws-amplify
Auth
promise.
Use resetPassword
in place of forgotPassword
in version 1 @aws-amplify/ui-react-native
.
The service object must then be passed into the authenticator
component as a services
prop. For example, let's imagine you'd like to lowercase the username
and the email
attributes during signUp
.
This would be overriden like so:
import React from 'react';
import { Button } from 'react-native';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
import { Amplify } from 'aws-amplify';
import { SignUpInput, signUp } from 'aws-amplify/auth';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button title="Sign Out" onPress={signOut} />;
}
function App() {
return (
<Authenticator.Provider>
<Authenticator
services={{
handleSignUp: ({ username, password, options }: SignUpInput) =>
signUp({
username: username.toLowerCase(),
password,
options: {
...options,
userAttributes: {
...options?.userAttributes,
email: options?.userAttributes?.email?.toLowerCase(),
},
},
}),
}}
>
<SignOutButton />
</Authenticator>
</Authenticator.Provider>
);
}
export default App;
When overriding signUp
in @aws-amplify/ui-react-native
version 1, you must include the autoSignIn
key and set enabled
to true, as shown in the example below.
import React from 'react';
import { Button } from 'react-native';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
import { Amplify, Auth } from 'aws-amplify';
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button title="Sign Out" onPress={signOut} />;
}
const services = {
async handleSignUp(input) {
let { username, password, attributes } = input;
// custom username
username = username.toLowerCase();
attributes.email = attributes.email.toLowerCase();
return Auth.signUp({
username,
password,
attributes,
autoSignIn: {
enabled: true,
},
});
},
};
function App() {
return (
<Authenticator.Provider>
<Authenticator services={services} >
<SignOutButton />
</Authenticator>
</Authenticator.Provider>
);
}
export default App;
Each handle*
function accepts as input the expected input of its corresponding Auth
function, allowing you to override the Auth
function call from within the handle*
function. Here is a table of each override function name, and the values passed as input
.
Auth Function Call | Override Name | input Properties |
---|---|---|
signUp | handleSignUp | {username, password} |
signIn | handleSignIn | {username, password} |
confirmSignIn | handleConfirmSignIn | {challengeResponse} |
confirmSignUp | handleConfirmSignUp | {username, confirmationCode} |
resetPassword | handleForgotPassword | {username} |
confirmResetPassword | handleForgotPasswordSubmit | {username, newPassword, confirmationCode} |
Function Call | Override Name | formData Properties |
---|---|---|
Auth.signUp | handleSignUp | {username, password, attributes} |
Auth.signIn | handleSignIn | {username, password} |
Auth.confirmSignIn | handleConfirmSignIn | {user, code, mfaType} |
Auth.confirmSignUp | handleConfirmSignUp | {username, code} |
Auth.forgotPassword | handleForgotPassword | {username} |
Auth.forgotPasswordSubmit | handleForgotPasswordSubmit | {username, code, password} |
Internationalization (I18n)
The Authenticator
ships with translations for:
en
– English (default)zh
– Chinesenl
– Dutchfr
– Frenchde
– Germanhe
– Hebrewid
– Indonesianit
– Italianja
– Japaneseko
– Koreannb
- Norwegianpl
– Polishpt
– Portugueseru
– Russianes
– Spanishsv
– Swedishth
- Thaitr
– Turkishua
– Ukrainian
These translations can be customized using the Amplify JS' I18n
module:
import { I18n } from 'aws-amplify/utils';
import { translations } from '@aws-amplify/ui';
I18n.putVocabularies(translations);
I18n.setLanguage('fr');
I18n.putVocabularies({
fr: {
'Sign In': 'Se connecter',
'Sign Up': "S'inscrire",
},
es: {
'Sign In': 'Registrarse',
'Sign Up': 'RegÃstrate',
},
});
The list of available keys are available here.
Confirm Sign Up Page Translations
The confirm sign up page has a few specialized strings that can be translated. These include:
`Your code is on the way. To log in, enter the code we emailed to`
`Your code is on the way. To log in, enter the code we texted to`
`Your code is on the way. To log in, enter the code we sent you. It may take a minute to arrive.`
`It may take a minute to arrive.`
If you see any missing translations or would like to contribute a new language, we greatly appreciate contributions to translations we have here.
Labels & Text
Using the same techniques as Internationalization (I18n), you can customize the labels and text of the components:
Sign In
I18n.putVocabulariesForLanguage('en', {
'Sign In': 'Login', // Tab header
'Sign in': 'Log in', // Button label
'Sign in to your account': 'Welcome Back!',
Username: 'Enter your username', // Username label
Password: 'Enter your password', // Password label
'Forgot your password?': 'Reset Password',
});
Sign Up
I18n.putVocabulariesForLanguage('en', {
'Create Account': 'Register', // Link text
'Create a new account': 'New User', // Header text
'Confirm Password': 'Confirm your password', // Confirm Password label
Email: 'Enter your email',
'Phone Number': 'Enter your phone number',
});
Forgot Password
I18n.putVocabulariesForLanguage('en', {
'Reset your password': 'Forgot your password?',
'Enter your username': 'Username or Email',
'Send code': 'Reset my password',
'Back to Sign In': 'Back to Login',
});
Setup TOTP
I18n.putVocabulariesForLanguage('en', {
Code: '2FA Code',
Confirm: 'Confirm 2FA',
'Back to Sign In': 'Back to Login',
});
Form Field Customization
Extend or override the existing fields for an Authenticator
subcomponent by passing an array of field option objects to the fields
prop:
import React from 'react';
import { Button, StyleSheet, View } from 'react-native';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
import { Amplify } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button onPress={signOut} title="Sign Out" />;
}
function App() {
return (
<Authenticator.Provider>
<Authenticator
components={{
SignUp: ({ fields, ...props }) => (
<Authenticator.SignUp
{...props}
fields={[
...fields,
{
name: 'preferred_username',
label: 'Preferred Username',
type: 'default',
placeholder: 'Enter your preferred username',
},
]}
/>
),
}}
>
<View style={style.container}>
<SignOutButton />
</View>
</Authenticator>
</Authenticator.Provider>
);
}
const style = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
});
export default App;
Label hidden
Default fields include label
values. To render the fields without labels:
import React from 'react';
import { Button, StyleSheet, View } from 'react-native';
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
import { Amplify } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
function SignOutButton() {
const { signOut } = useAuthenticator();
return <Button onPress={signOut} title="Sign Out" />;
}
function App() {
return (
<Authenticator.Provider>
<Authenticator
components={{
SignIn: ({ fields, ...props }) => (
<Authenticator.SignIn
{...props}
fields={fields.map((field) => ({ ...field, labelHidden: true }))}
/>
),
}}
>
<View style={style.container}>
<SignOutButton />
</View>
</Authenticator>
</Authenticator.Provider>
);
}
const style = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
});
export default App;
Styling
Theme Provider
You can update the style of the Authenticator by wrapping it with a ThemeProvider. Then create a theme object, with all your font customizations.
import React from 'react';
import { Authenticator, ThemeProvider } from '@aws-amplify/ui-react-native';
import { Amplify } from 'aws-amplify';
import config from './aws-exports';
Amplify.configure(config);
function App() {
return (
<ThemeProvider
theme={{
tokens: {
colors: {
primary: {
10: '{colors.pink.10}',
20: '{colors.pink.20}',
40: '{colors.pink.40}',
60: '{colors.pink.60}',
80: '{colors.pink.80}',
90: '{colors.pink.90}',
100: '{colors.pink.100}',
},
},
},
}}
>
<Authenticator.Provider>
<Authenticator />
</Authenticator.Provider>
</ThemeProvider>
);
}
export default App;
If you have TypeScript enabled, all the object keys will be present when creating the theme object. This will help speed up your development time while creating themes.
Dark mode
Amplify UI comes with a default dark mode implementation
import React from 'react';
import { useColorScheme } from 'react-native';
import {
Authenticator,
defaultDarkModeOverride,
ThemeProvider,
} from '@aws-amplify/ui-react-native';
import { Amplify } from 'aws-amplify';
import config from './aws-exports';
Amplify.configure(config);
function App() {
const colorMode = useColorScheme();
return (
<ThemeProvider
colorMode={colorMode}
theme={{
tokens: {
colors: {
primary: {
10: '{colors.pink.10}',
20: '{colors.pink.20}',
40: '{colors.pink.40}',
60: '{colors.pink.60}',
80: '{colors.pink.80}',
90: '{colors.pink.90}',
100: '{colors.pink.100}',
},
},
},
overrides: [defaultDarkModeOverride],
}}
>
<Authenticator.Provider>
<Authenticator />
</Authenticator.Provider>
</ThemeProvider>
);
}
export default App;