Amplify-js: Add Navigation bar on top of signin screen using withAuthenticator in React app

Created on 2 Jan 2019  路  6Comments  路  Source: aws-amplify/amplify-js

Hi,

I am trying to implement custom Navigation bar using withAuthenticator in amplify app with react js. Here is my custom navbar component.

import React, { Component } from "react";
import { Nav, Navbar, NavDropdown, MenuItem, NavItem } from "react-bootstrap";
export default class Topmenu extends Component {
    render() {
        return (
  <Navbar>
  <Navbar.Header>
    <Navbar.Brand>
      <a href="#home">React-Bootstrap</a>
    </Navbar.Brand>
  </Navbar.Header>
  <Nav pullRight>
    <NavItem eventKey={1} href="#">
      Link
    </NavItem>
    <NavItem eventKey={2} href="#">
      Link
    </NavItem>
    <NavDropdown eventKey={3} title="Dropdown" id="basic-nav-dropdown">
      <MenuItem eventKey={3.1}>Action</MenuItem>
      <MenuItem eventKey={3.2}>Another action</MenuItem>
      <MenuItem eventKey={3.3}>Something else here</MenuItem>
      <MenuItem divider />
      <MenuItem eventKey={3.4}>Separated link</MenuItem>
    </NavDropdown>
  </Nav>
</Navbar>
        );
    }
}

First, i tried to implement it as a Theme in withAuthenticator. Here is the code

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { withAuthenticator } from 'aws-amplify-react';
import Theme from 'Topmenu.js';
class App extends Component {

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
        </header>
      </div>
    );
  }
}

export default withAuthenticator(App,false,[<SignIn/>,
  <ConfirmSignIn/>,
  <RequireNewPassword/>,
  <VerifyContact/>,
  <ForgotPassword/>,
  <TOTPSetup/>],null,{Theme});

Output
I didnt find navbar rendered on signin screen.

Second, i tried to add the navbar like this

export default withAuthenticator(App,false,[<SignIn/>,
  <ConfirmSignIn/>,
  <RequireNewPassword/>,
  <VerifyContact/>,
  <ForgotPassword/>,
  <Theme/>,     ----Navbar
  <TOTPSetup/>]);

Here the Theme component(i.e.navbar) is coming at the button of the SignIn Screen rather than coming on the top.

Any help is appreciated
Thanks

React UI

Most helpful comment

Hi @Private-SO,

Based on your wording, I am not 100% sure if you want the navbar built into the sign-in screen or built into the app once signed in. The navbar that you can override in the withAuthenticator is the navbar that exists once the user signs in.

From my understanding it sounds like what you want is the navbar to live outside of the withAuthenticator HOC (on the sign-in screen). To achieve this you would do the following:

...
import { withAuthenticator } from 'aws-amplify-react';
...
class AppHome extends Component {
  ...
}
export default withAuthenticator(AppHome);

Then in your App component:

import Topmenu from './Topmenu';
import AppHome from './AppHome';
...
class App extends Component {
  render() {
    return (
      <div className="App">
        <Topmenu />
        <AppHome />
      </div>
    );
  }
}

This would display the navbar you have built above the Authenticator/sign-in screen.

Let me know if this helps or if I have misunderstood what you are asking for.

All 6 comments

Hi @Private-SO,

Based on your wording, I am not 100% sure if you want the navbar built into the sign-in screen or built into the app once signed in. The navbar that you can override in the withAuthenticator is the navbar that exists once the user signs in.

From my understanding it sounds like what you want is the navbar to live outside of the withAuthenticator HOC (on the sign-in screen). To achieve this you would do the following:

...
import { withAuthenticator } from 'aws-amplify-react';
...
class AppHome extends Component {
  ...
}
export default withAuthenticator(AppHome);

Then in your App component:

import Topmenu from './Topmenu';
import AppHome from './AppHome';
...
class App extends Component {
  render() {
    return (
      <div className="App">
        <Topmenu />
        <AppHome />
      </div>
    );
  }
}

This would display the navbar you have built above the Authenticator/sign-in screen.

Let me know if this helps or if I have misunderstood what you are asking for.

Thanks @jordanranz . That's exactly i am looking for.

I dont know whether this is correct platform to ask this question, But the navbar remains on the top even i signed in. Is there a way to remove it as soon as i signed in . Why because usually we will have onclick event, upon clicking it will change the state . But here i dont have access to signin button because i am using withAuthenticator.

Any suggestions ?
Thanks

Awesome! Glad that worked.

There are two ways to check if a user is signed in or not. You can either call Auth.currentAuthenticatedUser() described here, which will succeed with the user object if the user is signed in or throw an error if the user is not signed in OR you can listen for auth events using the Hub class with documentation here

Using the information above you can set a state variable to conditionally render the navbar component.

Thanks @jordanranz

One question
Why can't <App.js> render context when i kept <App.js> in withAuthenticator(); . Because i want to maintain my auth state in App container.

import React, { Component } from "react";
import Text from "./text.js";
import { withAuthenticator } from "aws-amplify-react";

class App extends Component {
  render() {
    <div className="App">
      <Text />
    </div>;
  }
}

export default withAuthenticator(App, false);

Where <Text/> is just a

import React, { Component } from "react";

export default class text extends Component {
  render() {
    return (
      <div className="App">
        <h1>hello</h1>
      </div>
    );
  }
}

Output

My Signin Page is not displaying the hello text on top.

Do i need to follow only your way for acheiving it like you had said in above comments or Am i missing anything ?
Thanks

Hey @Private-SO,

Since you are wrapping your App component in the withAuthenticator HOC, the component specified in the App component (and anything else within the App component's render() function will only render once you have signed in. You can read a bit more about HOCs here.

To render something outside of the Sign In screen applied by the withAuthenticator HOC you must render it outside of the component that is wrapped with the HOC. This is what my example above is doing.

Thanks @jordanranz

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DougWoodCDS picture DougWoodCDS  路  3Comments

epicfaace picture epicfaace  路  3Comments

ldgarcia picture ldgarcia  路  3Comments

karlmosenbacher picture karlmosenbacher  路  3Comments

cgarvis picture cgarvis  路  3Comments