diff --git a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor
index 6efa217c28..3bb2e7a94c 100644
--- a/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor
+++ b/src/Websites/Platform/src/Bit.Websites.Platform.Client/Pages/Templates/Templates01OverviewPage.razor
@@ -22,15 +22,10 @@
bit Boilerplate is a feature-rich project template for both Visual studio and the .NET CLI.
It comes with a lot of features right out of the box that are required for a real world application.
-
- Watch our YouTube playlist to get more familiar with bit Boilerplate project template
-
- here
- :
-
Database
-
-
- Configure the database to work with the apps built with the bit project templates.
-
-
-
-
- Connection String
-
- You can change connection string at appsettings.json file in Server project.
-
-
-
- If you have selected 'Other' for the database parameter while building the project, install appropriate EntityFrameworkCore package for your intended database such as PostgreSQL,
- and then in the Server\Startup\Services.cs file, perform the relevant settings for the related package in the services.AddDbContext section.
-
-
-
-
- Migration
-
- Set Server as the Startup Project in solution explorer and also set it as the Default Project in Package Manager Console and run the following commands:
-
- Add-Migration InitialMigration -OutputDir Data\Migrations -Context AppDbContext
- Update-Database -Context AppDbContext
-
-
- Note: If you encounter any problem in running these commands, first make sure that the solution builds successfully.
-
-
- Or open a terminal in your Server project directory and run followings:
- dotnet ef migrations add InitialMigration --context AppDbContext --output-dir Data/Migrations
- dotnet ef database update --context AppDbContext
-
-
-
-
-
Run
-
-
- To run the apps built with the bit project templates use the following instructions.
-
-
-
-
- How?
-
- After you've done the configuration, you can run the application. Set Server project as startup and run, you can see the swagger dashboard in the first view.
-
-
-
-
-
- Simply login with following credentials:
-
- username: test@bitplatform.dev
password: 123456
-
-
-
- Next steps!
-
-
- You have successfully built and run your project using the bit platform project templates ❤️
-
-
- In the upcoming sections, you will get acquainted with Blazor app models that will help you produce outputs for Android, iOS, Windows, macOS, and Web!
-
-
- Furthermore, in the Web app deployment type section, you'll understand how easily you can choose between PWA or SPA and with/without Pre Rendering!
-
-
- Stay with us!
-
-
-
-
-
-
-
Blazor app models
-
-
- Blazor seamlessly operates on web browsers using WebAssembly and extends its capabilities to Android, iOS, Windows, and macOS through the .NET runtime, with full access to native platform features and third-party libraries developed in Swift, Objective-C, Kotlin, and Java.
-
- Notably, Blazor offers pre-rendering in order to be seo friendly.
-
-
-
-
-
- Blazor Server
-
- With the Blazor Server hosting model, the app is executed on the server from within an ASP.NET Core app. UI updates, event handling,
- and JavaScript calls are handled over a SignalR connection using the WebSockets protocol.
-
- To use to Blazor Server:
-
-
- - Open the file Core/Services/AppRenderMode.cs and change the Current field to BlazorServer.
-
- public static IComponentRenderMode Current => BlazorServer
- - Set the "Server" project as the startup project.
- - Run the application.
- - When the browser opens, remove "swagger/index.html" from the URL address bar to view the app UI instead of the swagger UI.
-
-
-
-
-
- Blazor WebAssembly
-
- Blazor WebAssembly (WASM) apps run client-side in the browser on a WebAssembly-based .NET runtime. The Blazor app, its dependencies,
- and the .NET runtime are downloaded to the browser. The app is executed directly on the browser UI thread. UI updates and event handling occur within the same process.
-
- To use the Blazor WebAssembly:
-
-
- - Open the file Core/Services/AppRenderMode.cs and change the Current field to BlazorWebAssembly.
-
- public static IComponentRenderMode Current => BlazorWebAssembly
- - Set the "Server" project as the startup project.
- - Select Boilerplate.Server-BlazorWebAssembly launchSettings profile instead of Boilerplate.Server-Swagger
-
-
-
- - Run the application.
- - When the browser opens, remove "swagger/index.html" from the URL address bar to view the app UI instead of the swagger UI.
-
-
-
-
-
- Blazor Auto
-
- Blazor seamlessly combines Blazor Server and WebAssembly.
- This approach enhances user interaction initially through Blazor Server, while simultaneously downloading Blazor WebAssembly for subsequent visits, reducing server load.
-
- To use the Blazor Auto:
-
-
- - Open the file Core/Services/AppRenderMode.cs and change the Current field to Auto.
-
- public static IComponentRenderMode Current => Auto
- - Set the "Server" project as the startup project.
- - Select Boilerplate.Server-Swagger launchSettings profile instead of Boilerplate.Server-BlazorWebAssembly.
- - Run the application.
- - When the browser opens, remove "swagger/index.html" from the URL address bar to view the app UI instead of the swagger UI.
-
-
-
- Note: The provided code employs Blazor Server during development for an optimal debugging experience, while opting for Auto in production due to its superior user experience in most scenarios.
- public static IComponentRenderMode Current =>
BuildConfigurationModeDetector.Current.IsDebug() ? BlazorServer : Auto;
-
-
-
-
- Blazor Maui - Hybrid
-
- Blazor can also be used to build native client apps using a hybrid approach. Hybrid apps are native apps that leverage web technologies for their functionality.
- In a Blazor Hybrid app, Razor components run directly in the native app (not on WebAssembly).
-
- Blazor Hybrid is on top of .NET MAUI and has access to all native features of supported platforms (Android, iOS, macOS and Windows)
-
- To switch to Blazor Hybrid mode:
-
-
- - Set the "Server" project as the startup project.
- - Select Boilerplate.Server-Swagger launchSettings profile instead of Boilerplate.Server-BlazorWebAssembly.
- - Set "Maui" project as startup project and choose your Android, iOS, Windows, macOS emulator or device
-
-
-
- - Change ApiServerAddress in Client/Boilerplate.Client.Core/appsettings.json to make sure your Android / iOS device can reach your computer.
- - Right click on the solution file and open Properties
- - Configure multiple-startup project by choosing Server and Maui projects and click on Ok
-
-
-
- - Run the project
-
-
-
-
-
-
Deployment type
-
-
- bit project templates support multiple deployment type for their web applications.
-
-
-
- Supported deployment types are:
-
-
-
-
- Spa (Default configuration)
-
- It's referring to a Typical
Single Page Application (SPA) without pre-rendering.
-
-
Note: We'd recommend using next options for production and use Spa only for development / debugging.
-
-
-
-
- SpaPrerendered
-
-
Server-side rendering (SSR),
- is the ability of an application to contribute by displaying the web-page on the server instead of rendering it in the browser.
- Server-side sends a fully rendered page to the client; Blazor pre-renders page and sends it as a static page, then later the page becomes an interactive Blazor app.
- This behavior is intended to serve pages quickly to search engines with time-based positioning.
- Statically prerender the component along with a marker to indicate the component should later be rendered interactively by the Blazor app. It improve SEO.
-
- It's referring to a Typical Spa with pre-rendering.
-
-
Demo:
bitplatform.dev
-
- In order to enable prerendering, simply set
PrerenderEnabled in Core/Services/AppRenderMode.cs to
true
-
-
public static readonly bool PrerenderEnabled = true;
-
-
-
-
- Pwa
-
- A Blazor WebAssembly app built as a
Progressive Web App
- (PWA) uses modern browser APIs to enable many of the capabilities of a native client app, such as working offline, running in its own app window,
- launching from the host's operating system, receiving push notifications, and automatically updating in the background.
-
-
Demo:
adminpanel.bitplatform.dev
-
- In order to enable pwa, simply set
PwaEnabled in Directory.Build.props to
true
-
-
<PwaEnabled>true</PwaEnabled>
-
-
-
-
- PwaPrerendered
-
-
Server-side rendering (SSR),
- is the ability of an application to contribute by displaying the web-page on the server instead of rendering it in the browser.
- Server-side sends a fully rendered page to the client; Blazor pre-renders page and sends it as a static page, then later the page becomes an interactive Blazor app.
- This behavior is intended to serve pages quickly to search engines with time-based positioning.
- Statically prerender the component along with a marker to indicate the component should later be rendered interactively by the Blazor app. It improve SEO.
-
- It's referring to a Typical Pwa with pre-rendering.
-
-
Demo:
todo.bitplatform.dev
-
- In order to enable pwa pre-render, simply enable both pwa and pre-render.
-
-
-
-
- PrerenderedOnly
-
- Statically renders the component with the specified parameters. It's recommended when the target is building a static page like a landing page.
-
- In order to enable pre-render only, simply remove @("@")rendermode=renderMode from Server/Components/App.razor file.
-
-
-
-
-
-
Cache mechanism
-
-
- bit project templates provide features in order handle the caching appropriately in different modes.
-
-
-
-
- Pwa or PwaPrerender
-
- In Pwa mode, a manifest is generated and all files will be downloaded by Pwa with the help of this manifest.
- In this case, the Pwa app can work in offline mode, and for example, we can leverage ef-core and SQLite in the browser,
- which will work offline, and after going online, it can synchronize the generated data with the server if necessary.
-
-
- If a file is changed (such as font, photo, etc.), the latest changes will be automatically downloaded.
-
-
- Note: that if you do not need a file, be sure to delete it so that it is no longer downloaded by Pwa.
-
-
- Note: Pwa and PwaPrerender are our recommendation for production environment.
-
-
-
-
- Spa, SapPrerender and PrerenderOnly
-
- In Spa mode, if a js, css, or wasm file gets changed, the new version will be automatically requested by the browser if you use <Script> and <Link> instead of <script> and <link>,
- but for other file types such as fonts and images,
- the file name must also be changed to ensure that the client is updated.
-
-
-
-
-
-
DevOps
-
-
- bit project templates provide features to add support for DevOps using GitHub actions.
-
-
-
-
- CI
-
- CI pipeline which is located in .github/workflows/ci.yml ensures that every change that is committed into
- develop branch won't break project build.
-
-
-
-
- CD
-
- CD pipeline located in .github/workflows/cd.yml builds and deploys every change committed in the main branch into production.
-
-
- By default, the CD pipeline produces
.aab and
.apk for android,
.ipa for iOS,
.exe for Windows and,
.pkg for macOS.
- It also creates a zip folder that contains Server + Blazor (WebAssembly/Server/Auto) required files and an
-
EF core migrations bundle
- to migrate your database. This pipeline also uploads all of the produced artifacts to the GitHub Actions artifacts.
-
-
- You can manually deploy the artifacts into corresponding locations (App Stores, Virtual Private Servers), or you can write more scripts to automate these processes.
- For example, we've created a deploy phase for Server + Blazor that updates the database using the migrations bundle and optionally deploy artifacts to azure web apps.
-
-
- The CD pipeline includes the following variables:
-
- env:
- API_SERVER_ADDRESS: 'https://todo.bitplatform.dev/api/' # The API backend URL that clients use to connect to the server.
- APP_SERVICE_NAME: 'app-service-td-test' # Azure Web App name (If you want to deploy your project to the Azure Web App)
-
- And it also includes the following
GitHub actions secrets.
- It's important to mention that since the GitHub Actions secrets does not support storing files,
- to store secret files (such as pfx files), you need to convert the files' content to base64 and store the encoded result value as secret values.
-
- # IdentityCertificate.pfx (See Identity settings section of https://bitplatform.dev/templates/settings)
-API_IDENTITY_CERTIFICATE_FILE_BASE64
-API_IDENTITY_CERTIFICATE_PASSWORD
--_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-# Database
-DB_CONNECTION_STRING
--_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-# Azure App Service (Optional)
-AZURE_APP_SERVICE_PUBLISH_PROFILE # https://learn.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel
--_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-# Android
-ANDROID_RELEASE_KEYSTORE_FILE_BASE64
-ANDROID_RELEASE_SIGNING_PASSWORD
-ANDROID_RELEASE_KEYSTORE_PASSWORD
-APPLICATION_VERSION
-APPLICATION_DISPLAY_VERSION
--_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-# iOS https://www.andreasnesheim.no/setting-up-ci-for-your-net-maui-ios-app-with-github-actions/
-APPSTORE_CODE_SIGNING_CERTIFICATE_FILE_BASE64
-APPSTORE_CODE_SIGNING_CERTIFICATE_FILE_PASSWORD
-APPSTORE_API_KEY_ISSUER_ID
-APPSTORE_API_KEY_ID
-APPSTORE_API_KEY_PRIVATE_KEY
-IOS_CODE_SIGN_PROVISION
-APPLICATION_VERSION
-APPLICATION_DISPLAY_VERSION
--_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-
- We have a plan to automate the deployment of .ipa and .aab files to the Apple Store & Google Play in the near future. So stay tuned!
-
-
-
-
-
-
-
Platform integration
-
-
- Use native platform features in project templates:
-
-
-
-
- Overview
-
- In the bit platform, you have the ability to use JavaScript features across all operating systems (except during Prerendering).
-
- Additionally, there's access to Java and Kotlin capabilities in Android, and Swift and Objective-C in iOS and macOS.
- C# .NET itself has good access to Windows OS features.
-
- If you wish to use JavaScript, write the relevant function in app.ts and call it using JSRuntime. There are some examples in the project template, for example, for reading and writing in the cookie.
-
-
-
-
- Dependency injection sample
-
- Suppose we plan to read contacts on Android and iOS and save and sync them to the server. In the Windows, macOS and web versions, we'll fetch and display them from the server.
-
-
- First define an interface named IContactsService in the src\Client\Boilerplate.Client.Core/Services/Contracts and implement it separately in the following locations:
-
- src/Client/Boilerplate.Client.Maui/Platforms/Android named AndroidContactsService
-
- And
-
- src/Client/Boilerplate.Client.Maui/Platforms/iOS named iOSContactsService
-
-
- Then register them in the following locations:
-
- src/Client/Boilerplate.Client.Maui/Platforms/Android/Extensions/IServiceCollectionExtensions
- services.AddTransient<IContactsService, AndroidContactsService>();
- src/Client/Boilerplate.Client.Maui/Platforms/iOS/Extensions/IServiceCollectionExtensions
- services.AddTransient<IContactsService, iOSContactsService>();
- In each platform folder you've access to all native platform features!
-
- Implement that interface once more in src\Client\Boilerplate.Client.Core/Services/ that leverages http client to get synced contacts from the server,
- and register that in src/Client/Boilerplate.Client.Core/Extensions/IServiceCollectionExtensions
- services.TryAddTransient<IContactsService, AndroidContactsService>();
- Using TryAdd, we're registering that service for all app models, unless one of them registers another implementation with Add instead of TryAdd.
- So Web, Windows and macOS versions of the app are using this shared implementaion that gets synced contacts from the sever, but Android and iOS have their own implementations.
-
-
-
-
- Sample code:
-
-
- src/Client/Boilerplate.Client.Core/Services/Contracts
- public class ContactData
-{
- public string Name { get;set; }
-}
-
-public interface IContactsService
-{
- Task<List<ContactData>> GetContactData();
-}
-
- src/Client/Boilerplate.Client.Maui/Platforms/Android/Contracts
- public class AndroidContactsService : IContactsService
-{
- public async Task<List<ContactData>> GetContactData()
- {
- // here you've access to all android platform features!
-
- var uri = ContactsContract.Contacts.ContentUri!;
-
- string[] projection = {
- ContactsContract.Contacts.InterfaceConsts.Id,
- ContactsContract.Contacts.InterfaceConsts.DisplayName,
- ContactsContract.Contacts.InterfaceConsts.PhotoId,
- };
-
- // Whenever you need android's context, just use MauiApplication.Current
-
- var cursor = MauiApplication.Current.ContentResolver!.Query(uri, projection, null, null, null);
-
- // save contacts to the server's database
-
- // return contacts
- }
-}
-
-
-
- Native UI (Xaml)
-
- Lastly, you might want to use Xaml Controls, like the well-known MediaElement from the Maui Community Toolkit.
-
- In this case, inject IPubService on your razor page, publish a message, and inject IPubSubService in the constructor of the MainPage class in src/Client/Boilerplate.Client.Maui/MainPage.xaml.cs.
-
- Then subscribe to the relevant key and display your new Xaml page using App.Current.MainPage.PushAsync.
-
-
-
-
- Advanced scenarios
-
- If needed, for using Kotlin, Swift, Objective-C, or Java libraries, you can utilize
.NET MAUI Binding Libraries. This tool helps you have a C# Wrapper for your Kotlin, Java, Swift, Objective-C library, giving you full access.
-
- For further advanced scenarios, you can integrate Blazor content with XAML controls or even display Native controls created in Kotlin or Swift.
-
- There are interesting resources online. For instance, an
article showcases how to display SwiftUI controls in your iOS project.
-
- You can also place a razor page once in the web project and once in the app project with the same route, but different C# codes. The appropriate page will be displayed at runtime!
-
-
-
-
-
-
-
-
Settings
-
-
- Other configurations available in the bit project templates are as follows:
-
-
-
-
- Identity settings
-
- bit project templates uses ASP.NET Core Identity + bearer authentication and you can change their settings.
- You can find these settings in the appsettings.json file in the Server project.
-
- "IdentitySettings": {
- "Issuer": "Boilerplate",
- "Audience": "Boilerplate",
- "IdentityCertificatePassword": "P@ssw0rdP@ssw0rd", // It can also be configured using: dotnet user-secrets set "AppSettings:IdentitySettings:IdentityCertificatePassword" "P@ssw0rdP@ssw0rd"
- "BearerTokenExpiration": "0.01:00:00", // Format: D.HH:mm:ss
- "RefreshTokenExpiration": "14.00:00:00", // Format: D.HH:mm:ss
- "PasswordRequireDigit": "false",
- "PasswordRequiredLength": "6",
- "PasswordRequireNonAlphanumeric": "false",
- "PasswordRequireUppercase": "false",
- "PasswordRequireLowercase": "false",
- "RequireUniqueEmail": "true",
- "ConfirmationEmailResendDelay": "0.00:02:00", // Format: D.HH:mm:ss
- "ResetPasswordEmailResendDelay": "0.00:02:00" // Format: D.HH:mm:ss
-}
-
- Note: IdentityCertificatePassword referring to the password of the
- IdentityCertificate.pfx file in the Server project.
- To store the public key and other necessary information for validating incoming JWT tokens, a PFX file is employed.
- The same PFX file is utilized to empower the ASP.NET Core Data Protection API.
- Various methods exist for creating a PFX file. You may choose to follow your preferred approach for generating PFX files.
- Alternatively, you can execute the following command, specifying the desired password and path for your PFX file.
-
- dotnet dev-certs https --export-path IdentityCertificate.pfx --password P@ssw0rdP@ssw0rd
- Note: Replace P@ssw0rdP@ssw0rd with strong password and use that as IdentityCertificatePassword's value in appsettings.json
-
-
-
- Email settings
-
- bit project templates use
FluentEmail to send emails.
- You can change the SMTP provider settings in the
appsettings.json file in the Server project.
-
- In dev environment, bit saves the sent emails as a
.eml file in the
-
src/Boilerplate.Server/bin/Debug/net8.0/sent-emails path, and developers can easily view them in any
eml viewer.
-
- You can also use any test smtp server such as
ethereal.email or any production ready smtp server such as
-
SendGrid
-
- "EmailSettings": {
- "Host": "smtp.ethereal.email",
- "Port": "587",
- "DefaultFromEmail": "alva.schiller52@ethereal.email",
- "DefaultFromName": "Alva Schiller",
- "UserName": "alva.schiller52@ethereal.email",
- "Password": "4PyGY8cDQ8mvu6h7qB"
-}
-
- Note: You can find email templates used for email confirmation and reset password in the Components directory of the Server project.
-
-
-
-
- User profile image settings
-
- bit project templates save user profile image in Attachments\Profiles directory
- of Environment.SpecialFolder.ApplicationData as default, you can change this path as you need from the appsettings.json file in the Server project.
-
- "UserProfileImagesDir": "Attachments/Profiles/"
-
-
-
- Health check settings
-
- bit project templates support Health Checks for reporting the health of app infrastructure components.
- Health checks APIs are exposed as an HTTP endpoint. You can change the settings of this feature in the
- appsettings.json file in the Server project.
-
- "HealthCheckSettings": {
- "EnableHealthChecks": true
-}
-
-
-
-
-
-
Multilingualism
-
-
- bit project templates provide features in order add support for Multilingualism.
-
-
-
-
- How?
-
- To activate the Multilingual feature of the app, set the EnableMultilingual to true in the src/Directory.Build.props file.
-
-
- To add a new Culture, add it to the list of SupportedCultures in the CultureInfoManager class and add the corresponding translations
- in a new AppStrings.[culture-name].resx file named based on the new culture's name (e.g AppStrings.fr.resx for French).
-
-
- You also can customize the details of each culture in the CreateCultureInfo method, and the implementations of the bit platform templates
- will apply these changes in all of the supported platforms: Web, Android, iOS, macOS, Windows and even in Pre-Rendering.
-
-
- The required translations of the DTO's Validation Annotations will come from the values inside the AppStrings.resx file by default.
- But you can add separate .resx files and use them instead by adding the DtoResourceTypeAttribute on the DTO classes. For example,
- to use a custom .resx file named CustomersManagement.resx for a specific DTO, the attribute used on that DTO should look like this:
-
- [DtoResourceType(typeof(CustomersManagement)]
-public class CustomerDto
-{
- ...
-}
-
- You can also inject the specific StringLocalizer of this custom .resx file like this:
-
- [AutoInject] private IStrignLocalizer<CustomersManagement> _customersManagementLocalizer;
-
- And use it to access the translations inside that page.
-
-
-
-
-
-