Nano ASP.NET SaaS Boilerplate
Please allow a few seconds if the app is booting from a cold start.
Admin credentials (all tenants): / Password123!
Sample data resets every hour
Nano ASP.NET SaaS Boilerplate
.NET Solution
Vue UI
React UI
Razor Pages
Vue UI

Core Application

App.vue along with main.js together comprise the root of the application.

Root Component

In main.js you can see all of the globally imported libraries. Any key components that need to globally initialize and configure like Pinia, Vue Router, or BoostrapVueNext will have some boilerplate here. You may not even need some elements like Apex charts, but they are here for the component samples.

App.vue is the top level component in the Vue component tree. When it mounts the layout initialization is fired. The layoutStore.init() sets up the theme defaults, sidebar state, and preferences stored in localStorage. Pinia stores like the layoutStore are used to group related code and provide application-wide state.

The second thing App.vue does is check for a token to see if the user is authenticated. If the user is authenticated, it will get the current user’s details from the API using a method from the accountStore, another Pinia store. In either case, the router takes over from here and directs the user to the page they were looking for, or takes them to the login screen.

Vue Router

All routes are managed in routes.js and are grouped as either Boilerplate Routes or Template Resources routes. The boilerplate routes are as follows:

  • Auth routes – login, forgot password, reset password pages
  • Error routes – 400 type errors, catch-all for incorrectly entered URLs
  • Main routes – Products, plus any newly added entities
  • Management routes – Tenant and User management
  • Account routes – the current user profile.

The last three groups require authentication. Any authentication and role requirements are managed as router metadata and handled by the router code in router/index.js.

The Template Resources routes are divided into two groups Base UI and Extended UI. Base UI are the basic Boostrap components like buttons and tabs. These don’t need any extra code to function. Extended UI are the third-party components, icons, and dashboard sample.


Pinia stores are a great way to centralize state and logic in a Vue application. In this application, they are named by the feature they are responsible for:

  • Auth store – contains functions for login, forgot password, reset password and logout
  • Users, Tenants, & Products stores – contain CRUD functionality as well as state for the related views.
  • Account store – contains the current user and functions that manage profile and reset password
  • Layout store – contains theme initialization code that runs when the app mounts. Also, sidebar state, layout color, etc. The layout store uses local storage to persist theme settings.

Pinia is simpler and more intuitive than VueX for state management

With the exception of the layout store, all of the stores make HTTP calls to the server and they do so through the API.


The API in this Vue client is api/agent.js. It is the point of communication between the client app and the server. Here we are using Axios, which is a third-party HTTP client for JS that provides some nice features when working with API requests.

In agent.js a few things are happening:

  • We set the base URL using .env.development & .env.production variables, using Vite’s metadata
  • We use Axios interceptors to append a bearer token to every authenticated request when present, or if not, add a Tenant header with the tenantId.
  • When in the development environment, an artificial 1 second delay is added to every response make testing easier. Otherwise your localhost will load everything instantly and it will be difficult to see and test loading feedback.
  • Interceptors are also used as a catch-all to some 400, 500 level errors

The Axios base contains methods for Get, Post, Put, and Delete. These are the methods that are exposed in agent, an object that can then be used everywhere else, like Pinia stores.

There are also two alternate methods for Post, and Put when dealing with form data. It’s common to use form data when sending up files.

Next Steps

The next sections will look at the pages, components, layout & navigation, and the collection of template resources.

The most important components, data tables, forms and validation have their own section.

The theme style, which could be thought of as its own project, will be explored last. It’s essentially the same for all of the UI projects.