It's going to happen. You will be writing an app and it will require a login form to be displayed before displaying any other content. This is a common scenario and I have handled it various ways in the past. Now that I'm using FreshMVVM for my Xamarin Forms projects, I had to figure out how to present a login form using the navigation framework provided by FreshMVVM. As it turns out, the solution was really easy and clean. This post assumes familiarity with FreshMVVM.

The typical scenario goes like this, you want to always check for credentials (is the user logged in?) and present your login form when the app launches if needed. Most likely, you don't want your login page to be the MainPage of your app but you do want it to run first. The way I see it, there are two options:

Option 1: Modal Dialog

When the app launches, you check for credentials in your in your MainPage. If the user needs to login, you push a modal view onto the stack, the user enters their credentials, you log them in and pop the modal off the stack. Sounds simple.

This method might work for some situations, but in my case, my MainPage displays data that can only be loaded after a successful login and there's no clean way to reload the MainPage after the login modal is popped from the stack. Okay, there probably are ways to do this, but it'll get messy.

Option 2: Multiple Navigation Stacks

This option sounds complicated, but it's not. FreshMVVM allows you to create multiple navigation stacks and you can name them for later reference. It goes like this: you create one navigation stack for your login and a second navigation stack for the rest of your app's functionality. The MainPage is assigned to the login page initially, so when your app first runs, it presents the login page using its associated navigation stack.

Once the user successfully logs in, you switch the navigation stack to your non-login stack and your real MainPage takes over, loading the data for the user.

The Code

I put a really basic example of this navigation stack switching here on GitHub but let's take a look at how to set this up and how it works.

private void InitializeNaviagation()
    var loginPage = FreshPageModelResolver.ResolvePageModel<LoginPageModel>();
    var loginStack = new FreshNavigationContainer(loginPage, NavStacks.LoginNavStack);

    var mainPage = FreshPageModelResolver.ResolvePageModel<MainPageModel>();
    var mainStack = new FreshNavigationContainer(mainPage, NavStacks.MainNavStack);

    MainPage = loginPage;
public class NavStacks
    public static string LoginNavStack = "LoginNavStack";
    public static string MainNavStack = "MainNavStack";

First, we initialize our navigation in App.cs. This method is called in the App constructor. And then, we have a simple class with two static strings for our navigation stack names.

As you can see, when we initialize the navigation, there are two stacks: one for the login and one for the rest of the app. The important thing is, we assign the login page as the MainPage so when the app first runs, it uses our login page and its navigation stack initially. That's how we first present the login view.

public class LoginPageModel : FreshBasePageModel
    public string Username { get; set; }
    public string Password { get; set; }

    public Command LoginCommand => new Command(Login);

    private void Login()
        if (Username == "Bob" && Password == "letmein")
            CoreMethods.DisplayAlert("Login Error", "The username or password is incorect.", "Okay");

In our login page model we have our login command which simply checks for valid credentials and then it does something special. Instead of just navigating somewhere else, it switches out the root navigation to use the main navigation stack instead of the login navigation stack. This results in the login view disappearing and the main view loading. There's no weird attempts at reloading the main page after the login and no hoops to jump through.

I really like this and had to use it recently while adding Azure ADAL login support to an app. My use of it is more complex than this simple example, but this is enough to get the idea across.