Author : MD TAREQ HASSAN | Updated : 2020/08/02
Things you should do before starting a project
See: Best practices for starting a new project
Scaffolding new project in Visual Studio
- New Project
- At start of VS “Create New Project” (or File > New > Project)
- Blazor App > Blazor WebAssembly
- Scaffolding Options
- Authentication: setup authentication
- Advanced
- ASP.NET Core hosted: if you want to host API in the backend
- Progressive Web Application: If you want to develop your blazor app as PWA
- In wwwroot folder:
- css folder:
- keep only
app.css
- remove all other css i.e.
bootstrap.min.css
because we are gonna use CDN
- keep only
- open-iconic folder: remove because we are gonna use CDN
- sample-data folder: keep/remove according to your need
- css folder:
Bootstrap
- Edit
wwwroot/index.html
to add CDN for JS and CSS files (cloudflare CDN will be used) - Bootstrap css and js
- See: bootstrap starter template
- CDN link (check latest): https://cdnjs.com/libraries/twitter-bootstrap
<!DOCTYPE html>
<html>
<head>
<!-- ... ... ... -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha512-MoRNloxbStBcD8z3M/2BmnT+rg4IsMxPkXaGh2zD6LGNNFE80W3onsAhRcMAMrSoyWL9xD7Ert0men7vR8LUZg==" crossorigin="anonymous" />
<!-- ... ... ... -->
</head>
<body>
<!-- ... ... ... -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.bundle.min.js" integrity="sha512-kBFfSXuTKZcABVouRYGnUo35KKa1FBrYgwG4PAx7Z2Heroknm0ca2Fm2TosdrrI356EDHMW383S3ISrwKcVPUw==" crossorigin="anonymous"></script>
<!-- ... ... ... -->
</body>
</html>
Loading animation
- Blazor WebAssembly
- Custom component can not be used because it takes time to load dlls and therefore loading component would not show at begining (but we need loading animation at begining, so using custom component is not possible)
- Pure css solution should be used
- See: Pure CSS loading screen
- Blazor Server
- Custom component can be used
- See: Loading spinner in Blazor Server
CDN link (check latest): https://cdnjs.com/libraries/spinkit
<!-- link -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/spinkit/2.0.1/spinkit.min.css" />
<!-- usage -->
<div class="sk-circle sk-center mb-sm-3">
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
</div>
Toast
bootstrap.bundle.min.js
already contains Toast feature- Since it take time to laod Blazor WebAssembly DLLs, to make ‘Toast’ work we need to add some delay
In case of Blazor apps, place Toast in MainLayout
<!-- Toast -->
<div class="toast mt-sm-2 fade hide" role="alert" data-delay="2500" data-animation="true" aria-live="assertive" aria-atomic="true" style="position: absolute; top: 0; right: 0; z-index:1000; min-width: 25%;">
<div class="toast-header bg-success text-white">
<strong class="mr-sm-auto">Success</strong>
<button type="button" class="ml-2 mb-1 close text-white" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="toast-body bg-light">Body goes here...</div>
</div>
<!-- Delay -->
<script>
$(function () {
//console.log("ready!");
//$('#toast').toast('show');
setTimeout(
function () {
$('#toast').toast('show');
}, 500);
});
</script>
Icons
Bootstrap icons
<!-- link -->
<!-- usage -->
<i class="bi-alarm"></i>
<i class="bi-alarm" style="font-size: 2rem; color: cornflowerblue;"></i>
Open Iconic with Bootstrap
CDN link (check latest): https://cdnjs.com/libraries/open-iconic
<!-- link -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/open-iconic/1.1.1/font/css/open-iconic-bootstrap.min.css" integrity="sha512-UyNhw5RNpQaCai2EdC+Js0QL4RlVmiq41DkmCJsRV3ZxipG2L0HhTqIf/H9Hp8ez2EnFlkBnjRGJU2stW3Lj+w==" crossorigin="anonymous" />
<!-- usage -->
<span class="oi oi-play-circle" title="Play Icon" aria-hidden="true"></span>
FontAwesome
- CDN link (check latest): https://cdnjs.com/libraries/font-awesome
- Kit: https://fontawesome.com/start ```html
## Index html
`wwwroot/index.html`
```cs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Blazor WebAssembly CRUD</title>
<base href="/" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha512-MoRNloxbStBcD8z3M/2BmnT+rg4IsMxPkXaGh2zD6LGNNFE80W3onsAhRcMAMrSoyWL9xD7Ert0men7vR8LUZg==" crossorigin="anonymous" />
<!-- for icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/open-iconic/1.1.1/font/css/open-iconic-bootstrap.min.css" integrity="sha512-UyNhw5RNpQaCai2EdC+Js0QL4RlVmiq41DkmCJsRV3ZxipG2L0HhTqIf/H9Hp8ez2EnFlkBnjRGJU2stW3Lj+w==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" crossorigin="anonymous" />
<!-- Spinkit: for loading animation -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/spinkit/2.0.1/spinkit.min.css" integrity="sha512-kRYkjiYH/VXxoiaDK2oGNMKIi8VQVfie1lkYGX3kmfzWNR2kfaF5ze0885W3/eE6lIiURBsZA91M/WNvCajHMw==" crossorigin="anonymous" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>
<div class="container d-flex min-vh-100">
<div class="m-auto">
<div class="sk-circle sk-center mb-sm-3">
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
<div class="sk-circle-dot"></div>
</div>
<h2 class="text-sm-center">loading...</h2>
</div>
</div>
</app>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.bundle.min.js" integrity="sha512-kBFfSXuTKZcABVouRYGnUo35KKa1FBrYgwG4PAx7Z2Heroknm0ca2Fm2TosdrrI356EDHMW383S3ISrwKcVPUw==" crossorigin="anonymous"></script>
<script>
$(function () {
//console.log("ready!");
//$('#toast').toast('show');
setTimeout(
function () {
$('#toast').toast('show');
}, 500);
});
</script>
</body>
</html>
MainLayout
See: MainLayout in Blazor
Repository
InMemory repo
Service
- Search functionality using strategy design pattern
Index page component
- Scrollable compact table: