I am using the newer version @aws-amplify/ui-react, not the old version which was aws-amplify-react. In the older version you could extend the SignIn and SignUp pages, change the ui to whatever you want, and essential just call the super methods like in these examples: https://medium.com/@pandeysoni/how-to-setup-customize-amplify-authentication-ui-using-hooks-36442f5fdc or https://blog.kylegalbraith.com/2018/11/29/how-to-easily-customize-the-aws-amplify-authentication-ui/ .
In the new package though I can't seem to figure out how to accomplish the equivalent. Here is my current code using the basic amplify ui:
<AmplifyAuthenticator usernameAlias="email">
<AmplifySignUp
slot="sign-up"
usernameAlias="email"
headerText="Create a new account"
formFields={[
{
type: "email",
label: "Email",
placeholder: "Your company email address",
required: true,
},
{
type: "password",
label: "Password",
placeholder: "Password",
required: true,
},
]}
/>
<AmplifySignIn
slot="sign-in"
usernameAlias="email"
headerText="Sign in to your account"
/>
<AppWithRoutes />
</AmplifyAuthenticator>
If I however change it to:
<AmplifyAuthenticator usernameAlias="email">
<AppWithRoutes />
</AmplifyAuthenticator>
It doesn't seem to change anything other than not using my custom headers and such. So obviously it's pulling a default SignIn/SignUp class. So then I looked here: https://github.com/aws-amplify/amplify-js/blob/bf2f04888ea7e1e5364e1f669bb2847040fde684/packages/amplify-ui-components/src/components/amplify-authenticator/amplify-authenticator.tsx#L204 and found that they use AuthState to determine which auth component to load, and here: https://github.com/aws-amplify/amplify-js/blob/bf2f04888ea7e1e5364e1f669bb2847040fde684/packages/amplify-ui-components/src/components/amplify-authenticator/amplify-authenticator.tsx#L171 they seem to check to see if the auth component slot name exists, and if it doesn't then it returns the default AmplifySignIn class from here: https://github.com/aws-amplify/amplify-js/blob/bf2f04888ea7e1e5364e1f669bb2847040fde684/packages/amplify-ui-components/src/components/amplify-authenticator/amplify-authenticator.tsx#L145 .
My assumption is that if I send in a class with the same slot name that this should determine that the slot is overridden, and no longer return/render the default SignIn page.
interface CustomProps {
slot: string;
}
const CustomSignIn: React.FC<CustomProps> = props => {
const { slot } = props;
return <div>This should show up</div>;
};
<AmplifyAuthenticator usernameAlias="email">
<CustomSignIn slot="sign-in" />
<AppWithRoutes />
</AmplifyAuthenticator>
I still end up with the exact same login page with SignIn, SignUp, nothing customized. Am I just missing something really obvious? Do I need some special handling for the slot parameter? Is this no longer possible? I know that with the new package they allowed for more CSS override and customization, but it is still very limited.
If I do:
<AmplifyAuthenticator usernameAlias="email">
<div slot="sign-in">Hello</div>
<AppWithRoutes />
</AmplifyAuthenticator>
Then it slows just the sign div with the word Hello, like I would expect. So maybe I'm just handling slot wrong? So it looks like div is of type
React.DetailedHTMLProps<React.HTMLAttributes, HTMLDivElement>
And that is where slot is defined. So I changed my CustomSignIn props to be:
interface CustomProps extends HTMLAttributes<HTMLDivElement> {}
It goes back to the default sign-in sign-up instead of correctly overriding. But if I wrap it in the div like so:
<AmplifyAuthenticator usernameAlias="email">
<div slot="sign-in"><CustomSignIn /></div>
<AppWithRoutes />
</AmplifyAuthenticator>
It correctly shows what I'm returning from CustomSignIn. So I can at least get it to render the component I want, but I'd like to start by taking the base AWS UI, extend and tweak it vs completely writing my own.
If anyone has any ideas or knows of any documentation I missed, please let me know. Again, this is with @aws-amplify/ui-react package, NOT aws-amplify-react, which is the legacy version.
Thanks
I've tested it and this should work. You need to put "slot" in standard HTML tags.
const CustomSignIn: React.FC<CustomProps> = props => {
return <div slot="sign-in">This should show up</div>;
};
<AmplifyAuthenticator usernameAlias="email">
<CustomSignIn />
<AppWithRoutes />
</AmplifyAuthenticator>