Dynamic Login/Logout Button in Header Page Menu (Mobile/Desktop)

Dynamic Login/Logout Button in Header for Mobile/Desktop (Version 1.6)

This guide shows how to create a single button in the Header which either logs the user in or logs them out based on their login status and dynamically updates to display the correct verbiage and icon. This guide requires Builder setup and Javascript. You can customize how the button appears (the text/icon) as well if you choose to do so.

Logged In View After We Complete This Process:

![](upload://rFkdYVkJeAUse67KVSybjRjjIIV.png)

Logged Out View After We Complete This Process:

![](upload://iE9ExlsHduNm7JajOLhfYzbIEHp.png)

Builder Setup

Logout Page

  1. Create a blank page which requires login and is accessible to all users. Title the page "Log Out".
  2. Hide the page above from the page menu (this page should only be accessible via javascript).
  3. Take note of this Page's full URL. (Open it in live and copy/paste the full URL somewhere for when we use it later in our javascript).

A Single Login Page for All Users to Login To

  1. You MUST have multiple login pages for each of your user roles.
  2. You MUST have a single login page for all your user roles like this.
  3. Hide the single login page from the page menu (we'll direct our users here later on in our javascript).
  4. Take note of this Page's full URL. (Open it in live and copy/paste the full URL somewhere for when we use it later in our javascript).

A 100% Necessary Blank Page With Absolutely Nothing On It

  1. Title this one "Loading..." and intentionally leave the page blank.
  2. DO NOT REQUIRE A LOGIN TO VIEW THIS PAGE.
  3. Take note of the Page URL for this page. Not the full URL. Just the Page URL like in screenshot below: (write it down somewhere for when we use it later in our javascript).

![](upload://c1fjVcZGnlShuA0YQ0Z9lWoK2yh.png)

Create the "My Account" Dropdown Menu in Your Page Menu

  1. Title it something like "My Account"
  2. Put the "Loading..." page in here
  3. Optional: Make "Change password" and "My Profile" pages and put them in here too for a cleaner user experience

Javascipt

Code for Logout Page

Replace the scene_xx with your scene id number for the Log Out page. Also replace "homepage" with the URL for your company's knack homepage. This will redirect your users back to the home page after logout.

/* Log Out Process
- Update scene_96 to your specific logout page
- Also update the "destination" below to your desired logout redirect page
*/
$(document).on('knack-scene-render.scene_96', function (event, scene) { // Use Scene ID for Your Log Out Page
let KnackScenes = $(".kn-scenes.kn-section");
function redirect (destination = "https://company.knack.com/sitepage/") { // Change URL to Homepage or Other Destination
setTimeout(function(){
window.location = destination;
KnackScenes.show(100);
}, 1000);
}
function logoutUser(button = document.createElement("a")) {
button.className = "kn-log-out";
button.innerHTML = "Click to Log Out";
document.getElementById("kn-" + scene.key).appendChild(button);

button.addEventListener("click", function() {
KnackScenes.hide();
redirect();
});
button.click();
}
if (Knack.session.user) {logoutUser()} else {redirect()}
});

Code for All Scenes

You will need to change the data-kn-slug in this code to match your app. You can find the data-kn-slug easily by checking the Page URL for your Loading... page, like we did in the above steps, and placing a # symbol in front of it for example: data-kn-slug=#loading. You will also need to input the actual URL of your logout and login pages when prompted by the code. 

$(document).on('knack-scene-render.any', function (event, scene) {
DynamicLoginButton();
});

function DynamicLoginButton() {
// Update Data-slug for both items below with Loading Page
const dynamic_Button_Desktop = $("#kn-app-menu nav.tabs li a[data-kn-slug=#loading]"),
dynamic_Button_Mobile = $("#app-menu-list-mobile li.kn-dropdown-menu ul.kn-dropdown-menu-list li a[data-kn-slug=#loading]"),


if (Knack.session.user) {
let Logout = {
url: "https://mycompany.knack.com/mysite#log-out/", // Update URL to Your Logout Page
icon: 'fa fa-sign-out',
text: "Sign Out",
getHTML: function() {
return "<i class='" + this.icon + "'></i>&nbsp;&nbsp;" + this.text;
}
}
dynamic_Button_Desktop.attr("href", Logout.url).html(Logout.getHTML());
dynamic_Button_Mobile.attr("href", Logout.url).html(Logout.getHTML());
} else { // Not Logged In
let Login = {
url: "https://mycompany.knack.com/mysite#login-page/",
icon: 'fa fa-sign-in',
text: "Sign In",
getHTML: function() {
return "<i class='" + this.icon + "'></i>&nbsp;&nbsp;" + this.text;
}
}
dynamic_Button_Desktop.attr("href", Login.url).html(Login.getHTML());
dynamic_Button_Mobile.attr("href", Login.url).html(Login.getHTML());
}
}

@Michael,

It is possible to have both. That's how my site is currently setup.

On my site, I have a "Welcome/Home" page and a few other pages for customers to browse that are not secured by login (you can have as many as you want). I then have multiple login-required pages (each of these pages has different access restrictions based on user role). So, with this setup, we have multiple login-required pages AND multiple non-login pages. This is when we would make a single login page for everyone. 

A "single login page", in this context, is just a login page that we allow everyone to access and then funnel all of our users to (so they don't get prompted to login multiple times or have to go to seperate places for their login). To do that, we need to make a login page and check the box for "Allow access to all users". This process is described best here in the Single Login Page Guide by Knack. Then we need to provide an easily accessible link to that page for our users to use with a text description that makes sense before/after the user has logged in. But how do we do that?

This post was designed to provide an elegant solution to the question above and uses javascript to make that happen. An alternative, non-javascript solution, would be to create menu buttons on each non-login page that would link your users to the single login page (just remember to add this menu button on every new page and be careful with your wording. It wouldn't make much sense to have a "Login" button display when someone is already logged in.).

I am really confused about the single login.

I would like to have a single login but I also want a lot of pages accessible without log in so the search engines can index the site.

I don't seem to be able to have a combination of both available:

1. multiple logins to specific pages

2. single log in to the entire site

Is that correct that it is either one or the other?

 

Michael,

You're right, for this code to work, you will need a single login page. Luckily having multiple login pages is the first step toward creating a single login page

I also made a typo in my original post which could be causing your issue. I accidentally mislabeled the loading page's data-kn-slug so you'll need to go into the javascript and...

Change this:

a[data-kn-slug=#loading...]

To this:

a[data-kn-slug=#loading]

If that doesn't work, that's okay. We just need to make sure the data-kn-slug matches the page url in Knack Builder found here:

![](upload://c1fjVcZGnlShuA0YQ0Z9lWoK2yh.png)

I hope that helps! I also updated my post with these revisions along with other enhancements.

Thanks David!

That considerably speeds up the load time especially since I'm not planning on displaying or using any of the user's attributes in my page menu.

I updated the post to reflect the update..

Great customization, Robert!
You can actually simplify this by checking if Knack.session.user exists. So, just wrap what you have in your success callback with if (Knack.session.user) and wrap the error callback in else, eliminating the need for and slight delay caused by making the API request.

Hi, I tried to implement this however, I couldn't get it to work.

The loading menu item is visible and there is no login item.

I don't have a universal login to the entire site but a log in to individual pages.

Could that be why I can't get it to work? It seems knack hides the log in page. It seems to be only activated once a user tries to access a page that requires a log in. 
If a user is logged in, the logout menu is visible and works.