Amplify UI
Take advantage of the amplify UI for authentication tools in Gatsby without amplify theme
Contents
Amplify Resources
Executive Overview
Amazon amplify-ui has some great building blocks to jumpstart your development with secure authentication themed to your site. Using AWS Cognito as a backend, you can always swap it out with more custom code in the future.
Tech Overview
Secure front-end coupled with AWS Cognito backend.
Install
Requirements
- npm add aws-amplify @aws-amplify/ui-react
Basic use
-import { AmplifyAuthenticator } from '@aws-amplify/ui-react';
+import { Authenticator } from '@aws-amplify/ui-react';
+import '@aws-amplify/ui-react/styles.css';
...
- <AmplifyAuthenticator>
<ThemeProvider theme={theme}><CssBaseline enableColorScheme />
+ <Authenticator>
+ {({ signOut }) => { return (
...
+
+ )}}
+ </Authenticator>
</ThemeProvider>
- </AmplifyAuthenticator>
Headless
Headless allows pages to be excluded from authentication and provides a method for using hooks to get authentication information without invoking the Auth amplify api. Headless changes include setting up a provider that wraps the app in gatsby-browser:
import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
...
export const wrapPageElement = ({ element, props }) => {
return (
<Authenticator.Provider>
<Layout {...props}>
{element}
</Layout>
</Authenticator.Provider>
gatsby-ssr also needs changes to reflect the new DOM structure in gatsby-browser: (note the lack of css import)
import { Authenticator } from '@aws-amplify/ui-react';
...
export const wrapPageElement = ({ element,props }) => {
return (
<Authenticator.Provider>
<Layout {...props}>
{element}
</Layout>
</Authenticator.Provider>
)};
changes to the layout component include adding the useAuthenticator hook (to get auth information without invoking auth api) and accessing the location name which we will use to explicitly bypass authent on some pages.
Note: use authStatus to make sure the page re-renders when authStatus changes. The user object cannot be used because the user object doesn't undergo any shallow changes when the authentication status changes.
layout.tsx:
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react';
const Layout = ({ children }: LayoutProps) => {
const Layout = ({ children, location }: LayoutProps) => {
const { authStatus } = useAuthenticator(context => [context.authStatus]);
...
return(
<Authenticator> {({ signOut }) => { return (
{ (authStatus !== 'authenticated' && location?.pathname !== '/') ?
? <Authenticator /> :
... rest of page as normal
Authenticator parms
hideSignUp={true}
useAuthenticator
values
- signOut function
- toResetPassword function
- user
- username
- error
- validationErrors
Jest mocks
mocks/@aws-amplify/ui-react.js
import React from 'react';
export const Authenticator = props => {
return (<div data-testid='authenticator'>{props.children}</div>);
}
export const useAuthenticator = props => {
const user = {
username: 'testusr',
}
return ({ user });
}
Customize Colors
use this pattern in your layout component:
const root = window.document.documentElement;
root.style.setProperty('--amplify-colors-background-primary', '#f2eee2');
or if you prefer add via css. Example:
:root {
--amplify-primary-color: #eeeeee;
--amplify-primary-contrast: #444464;
--amplify-primary-shade: #444444;
--amplify-primary-tint: #444444;
}
add --amplify-
to the following:
-
colors-background-primary - background
-
colors-border-primary', 'var(--amplify-colors-blue-90)');
-
colors-border-focus', 'var(--amplify-colors-blue-60)');
-
components-button-primary-background-color', 'var(--amplify-colors-blue-60)');
-
components-button-primary-hover-background-color', 'var(--amplify-colors-blue-80)');
-
components-button-primary-active-background-color', 'var(--amplify-colors-blue-20)');
-
colors-font-primary', 'var(--amplify-colors-black)');
-
colors-font-interactive', 'var(--amplify-colors-blue-60)');
-
components-button-color', 'var(--amplify-colors-blue-60)');
-
components-button-hover-color', 'var(--amplify-colors-blue-60)');
-
components-button-hover-border-color', 'var(--amplify-colors-blue-90)');
-
components-button-hover-background-color', '#f5ce28');
-
components-button-link-hover-color', 'var(--amplify-colors-blue-60)');
-
components-button-link-hover-background-color', '#f5ce28');