From b8fe89b1cac2cf4a6bfe6adcb3434f2f82ef44dc Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 16:57:56 +0300 Subject: [PATCH 01/10] docs: refine React modern template guidance Co-authored-by: Cursor --- docs/en/cli/index.md | 134 +++++++++++++++------------- docs/en/framework/ui/react/index.md | 26 +++--- 2 files changed, 85 insertions(+), 75 deletions(-) diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md index b7327bdf98..fd56aa0809 100644 --- a/docs/en/cli/index.md +++ b/docs/en/cli/index.md @@ -9,6 +9,8 @@ ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or [ABP Studio](../studio/index.md) features. +This document describes `Volo.Abp.Studio.Cli`, the ABP CLI package that works with the ABP Studio template system. Modern templates, including React UI support, are available through this package. If you need to run the legacy `Volo.Abp.Cli`, pass `--old` at the end of the command. + ## Installation ABP CLI is a [dotnet global tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools). Install it using a command line window: @@ -29,53 +31,53 @@ While each command may have a set of options, there are some global options that - `--skip-cli-version-check` or `-scvc`: Skips checking the latest version of the ABP CLI. If you don't specify, it will check the latest version and shows a warning message if there is a newer version of the ABP CLI. - `--skip-extension-version-check` or `-sevc`: Skips checking the latest version of the ABP CLI extensions. If you don't specify, it will check the latest version and download the latest version if there is a newer version of the ABP CLI extensions. -- `--old`: ABP CLI has two variations: `Volo.Abp.Studio.Cli` and `Volo.Abp.Cli`. New features/templates are added to the `Volo.Abp.Studio.Cli`. But if you want to use the old version, you can use this option **at the end of your commands**. For example, `abp new Acme.BookStore --old`. +- `--old`: ABP CLI has two variations: `Volo.Abp.Studio.Cli` and `Volo.Abp.Cli`. New features and templates are added to `Volo.Abp.Studio.Cli`. If you want to use the old version, use this option **at the end of your commands**. For example, `abp new Acme.BookStore --old`. - `--help` or `-h`: Shows help for the specified command. ## Commands Here is the list of all available commands before explaining their details: -- `**[help](../cli#help)`**: Shows help on the usage of the ABP CLI. -- `**[cli](../cli#cli)`**: Update or remove ABP CLI. -- `**[new](../cli#new)**`: Generates a new solution based on the ABP [startup templates](../solution-templates/index.md). Use `--modern` to create solutions with the modern template system (React UI). -- `**[new-module](../cli#new-module)**`: Generates a new module based on the given template. Use `--modern` to use modern module templates. -- `**[new-package](../cli#new-package)**`: Generates a new package based on the given template. -- `**[update](../cli#update)**`: Automatically updates all ABP related NuGet and NPM packages in a solution. -- `**[clean](../cli#clean)**`: Deletes all `BIN` and `OBJ` folders in the current folder. -- `**[add-package](../cli#add-package)**`: Adds an ABP package to a project. -- `**[add-package-ref](../cli#add-package-ref)**`: Adds package to given project. -- `**[install-module](../cli#install-module)**`: Adds a [multi-package application module](../modules/index.md) to a given module. -- `**[install-local-module](../cli#install-local-module)**`: Installs a local module to given module. -- `**[list-modules](../cli#list-modules)**`: Lists names of application modules. -- `**[list-templates](../cli#list-templates)**`: Lists the names of available templates to create a solution. -- `**[get-source](../cli#get-source)**`: Downloads the source code of a module. -- `**[add-source-code](../cli#add-source-code)**`: Downloads the source code and replaces package references with project references. -- `**[init-solution](../cli#init-solution)**`: Creates ABP Studio configuration files for a given solution. -- `**[kube-connect](../cli#kube-connect)**`: Connects to kubernetes environment. (*Available for* ***Business*** *or higher licenses*) -- `**[kube-intercept](../cli#kube-intercept)`**: Intercepts a service running in Kubernetes environment. (*Available for* ***Business*** *or higher licenses*) -- `**[list-module-sources](../cli#list-module-sources)`**: Lists the remote module sources. -- `**[add-module-source](../cli#add-module-source)*`*: Adds a remote module source. -- `**[delete-module-source](../cli#delete-module-source)**`: Deletes a remote module source. -- `**[generate-proxy](../cli#generate-proxy)**`: Generates client side proxies to use HTTP API endpoints. -- `**[remove-proxy](../cli#remove-proxy)**`: Removes previously generated client side proxies. -- `**[switch-to-preview](../cli#switch-to-preview)**`: Switches to the latest preview version of the ABP. -- `**[switch-to-nightly](../cli#switch-to-nightly)**`: Switches to the latest [nightly builds](../release-info/nightly-builds.md) of the ABP related packages on a solution. -- `**[switch-to-stable](../cli#switch-to-stable)**`: Switches to the latest stable versions of the ABP related packages on a solution. -- `**[switch-to-local](../cli#switch-to-local)**`: Changes NuGet package references on a solution to local project references. -- `**[upgrade](../cli#upgrade)**`: It converts the application to use pro modules. -- `**[translate](../cli#translate)**`: Simplifies to translate localization files when you have multiple JSON [localization](../framework/fundamentals/localization.md) files in a source control repository. -- `**[login](../cli#login)**`: Authenticates on your computer with your [abp.io](https://abp.io/) username and password. -- `**[login-info](../cli#login-info)**`: Shows the current user's login information. -- `**[logout](../cli#logout)**`: Logouts from your computer if you've authenticated before. -- `**[bundle](../cli#bundle)**`: Generates script and style references for ABP Blazor and MAUI Blazor project. -- `**[install-libs](../cli#install-libs)**`: Install NPM Packages for MVC / Razor Pages and Blazor Server UI types. -- `**[clear-download-cache](../cli#clear-download-cache)**`: Clears the templates download cache. -- `**[check-extensions](../cli#check-extensions)**`: Checks the latest version of the ABP CLI extensions. -- `**[install-old-cli](../cli#install-old-cli)**`: Installs old ABP CLI. -- `**[mcp-studio](../cli#mcp-studio)**`: Starts ABP Studio MCP bridge for AI tools (requires ABP Studio running). -- `**[generate-razor-page](../cli#generate-razor-page)**`: Generates a page class that you can use it in the ASP NET Core pipeline to return an HTML page. -- `**[generate-jwks](../cli#generate-jwks)**`: Generates an RSA key pair (JWKS public key + PEM private key) for OpenIddict `private_key_jwt` client authentication. +- [help](../cli#help): Shows help on the usage of the ABP CLI. +- [cli](../cli#cli): Update or remove ABP CLI. +- [new](../cli#new): Generates a new solution based on the ABP [startup templates](../solution-templates/index.md). Use `--modern` to create solutions with the modern template system and React UI. +- [new-module](../cli#new-module): Generates a new module based on the given template. Use `--modern` to use modern module templates. +- [new-package](../cli#new-package): Generates a new package based on the given template. +- [update](../cli#update): Automatically updates all ABP related NuGet and NPM packages in a solution. +- [clean](../cli#clean): Deletes all `BIN` and `OBJ` folders in the current folder. +- [add-package](../cli#add-package): Adds an ABP package to a project. +- [add-package-ref](../cli#add-package-ref): Adds package to given project. +- [install-module](../cli#install-module): Adds a [multi-package application module](../modules/index.md) to a given module. +- [install-local-module](../cli#install-local-module): Installs a local module to given module. +- [list-modules](../cli#list-modules): Lists names of application modules. +- [list-templates](../cli#list-templates): Lists the names of available templates to create a solution. +- [get-source](../cli#get-source): Downloads the source code of a module. +- [add-source-code](../cli#add-source-code): Downloads the source code and replaces package references with project references. +- [init-solution](../cli#init-solution): Creates ABP Studio configuration files for a given solution. +- [kube-connect](../cli#kube-connect): Connects to Kubernetes environment. (*Available for* ***Business*** *or higher licenses*) +- [kube-intercept](../cli#kube-intercept): Intercepts a service running in Kubernetes environment. (*Available for* ***Business*** *or higher licenses*) +- [list-module-sources](../cli#list-module-sources): Lists the remote module sources. +- [add-module-source](../cli#add-module-source): Adds a remote module source. +- [delete-module-source](../cli#delete-module-source): Deletes a remote module source. +- [generate-proxy](../cli#generate-proxy): Generates client side proxies to use HTTP API endpoints. +- [remove-proxy](../cli#remove-proxy): Removes previously generated client side proxies. +- [switch-to-preview](../cli#switch-to-preview): Switches to the latest preview version of the ABP. +- [switch-to-nightly](../cli#switch-to-nightly): Switches to the latest [nightly builds](../release-info/nightly-builds.md) of the ABP related packages on a solution. +- [switch-to-stable](../cli#switch-to-stable): Switches to the latest stable versions of the ABP related packages on a solution. +- [switch-to-local](../cli#switch-to-local): Changes NuGet package references on a solution to local project references. +- [upgrade](../cli#upgrade): It converts the application to use pro modules. +- [translate](../cli#translate): Simplifies to translate localization files when you have multiple JSON [localization](../framework/fundamentals/localization.md) files in a source control repository. +- [login](../cli#login): Authenticates on your computer with your [abp.io](https://abp.io/) username and password. +- [login-info](../cli#login-info): Shows the current user's login information. +- [logout](../cli#logout): Logouts from your computer if you've authenticated before. +- [bundle](../cli#bundle): Generates script and style references for ABP Blazor and MAUI Blazor project. +- [install-libs](../cli#install-libs): Install NPM Packages for MVC / Razor Pages and Blazor Server UI types. +- [clear-download-cache](../cli#clear-download-cache): Clears the templates download cache. +- [check-extensions](../cli#check-extensions): Checks the latest version of the ABP CLI extensions. +- [install-old-cli](../cli#install-old-cli): Installs old ABP CLI. +- [mcp-studio](../cli#mcp-studio): Starts ABP Studio MCP bridge for AI tools (requires ABP Studio running). +- [generate-razor-page](../cli#generate-razor-page): Generates a page class that you can use it in the ASP NET Core pipeline to return an HTML page. +- [generate-jwks](../cli#generate-jwks): Generates an RSA key pair (JWKS public key + PEM private key) for OpenIddict `private_key_jwt` client authentication. ### help @@ -117,7 +119,9 @@ abp cli clear-cache ### new -Generates a new solution based on the ABP [startup templates](../solution-templates). See [new solution create sample commands](new-command-samples.md) +Generates a new solution based on the ABP [startup templates](../solution-templates). See [new solution create sample commands](new-command-samples.md). + +The `new` command uses the ABP Studio template system by default. Add `--modern` to create a solution from the modern template system. Modern templates are React-first and are not available through the legacy CLI (`--old`). Usage: @@ -138,9 +142,9 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md #### Options -- `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates a application solution. Available templates: - - `**empty`**: Empty solution template. - - `**app*`*: Application template. Additional options: +- `--template` or `-t`: Specifies the template name. Default template name is `app`, which generates an application solution. Available templates: + - **`empty`**: Empty solution template. + - **`app`**: Application template. Additional options: - `--ui-framework` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks: - `mvc`: ASP.NET Core MVC. There are some additional options for this template: - `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios. (*Available for* ***Team*** *or higher licenses*) @@ -148,10 +152,10 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md - `--tiered`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*) - `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application. - `blazor-webapp`: Blazor Web App UI. There are some additional options for this template: - - `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project. + - `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and each runs on different endpoints. If not specified, you will have a single endpoint for your web project. - `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application. - `blazor`: Blazor UI. There are some additional options for this template: - - `--tiered`The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*) + - `--tiered`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*) - `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application. - `blazor-server`: Blazor Server UI. There are some additional options for this template: - `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project. (*Available for* ***Team*** *or higher licenses*) @@ -174,12 +178,12 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md - `--without-cms-kit`: When you add a public website to your solution, it automatically includes the [CmsKit](./../modules/cms-kit-pro/index.md) module. If you don't want to include *CmsKit*, you can use this parameter. - `--separate-tenant-schema`: Creates a different DbContext for tenant schema. If not specified, the tenant schema is shared with the host schema. This option is only included in PRO templates. - `--sample-crud-page` or `-scp`: It adds the [BookStore](./../tutorials/book-store/index.md) sample to your solution. - - `--theme` or `-th`: Specifes the theme. Default theme is `leptonx`. Available themes: + - `--theme` or `-th`: Specifies the theme. Default theme is `leptonx`. Available themes: - `leptonx`: LeptonX Theme. (*Available for* ***Team*** *or higher licenses*) - `leptonx-lite`: LeptonX-Lite Theme. - `basic`: Basic Theme. - - `--use-open-source-template`or `-uost`: Uses the open-source template. (*Available for* ***Team*** *or higher licenses*) - - `**app-nolayers`**: Single-layer application template. Additional options: + - `--use-open-source-template` or `-uost`: Uses the open-source template. (*Available for* ***Team*** *or higher licenses*) + - **`app-nolayers`**: Single-layer application template. Additional options: - `--ui-framework` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks: - `mvc`: ASP.NET Core MVC. There are some additional options for this template: - `angular`: Angular UI. There are some additional options for this template: @@ -194,12 +198,12 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md - `--skip-migrations` or `-sm`: Skips the creating initial database migration step. - `--skip-migrator` or `-smr`: Skips the run database migrator step. - `--sample-crud-page` or `-scp`: It adds the [BookStore](./../tutorials/book-store/index.md) sample to your solution. - - `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes: + - `--theme`: Specifies the theme. Default theme is `leptonx`. Available themes: - `leptonx`: LeptonX Theme. (*Available for* ***Team*** *or higher licenses*) - `leptonx-lite`: LeptonX-Lite Theme. - `basic`: Basic Theme. - - `--use-open-source-template`or `-uost`: Uses the open-source template. (*Available for* ***Team*** *or higher licenses*) - - `**microservice`**: Microservice solution template (*Available for* ***Business*** *or higher licenses*). Additional options: + - `--use-open-source-template` or `-uost`: Uses the open-source template. (*Available for* ***Team*** *or higher licenses*) + - **`microservice`**: Microservice solution template (*Available for* ***Business*** *or higher licenses*). Additional options: - `--ui-framework` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks: - `mvc`: ASP.NET Core MVC. There are some additional options for this template: - `angular`: Angular UI. There are some additional options for this template: @@ -215,7 +219,7 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md - `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers: - `ef`: Entity Framework Core. - `mongodb`: MongoDB. - - `--theme`: Specifes the theme. Default theme is `leptonx`. Available themes: + - `--theme`: Specifies the theme. Default theme is `leptonx`. Available themes: - `leptonx`: LeptonX Theme. - `basic`: Basic Theme. - `--public-website`: Public Website is a front-facing website for describing your project, listing your products and doing SEO for marketing purposes. Users can login and register on your website with this website. This option is only included in PRO templates. @@ -234,7 +238,7 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md - `--dont-run-install-libs`: Skip installing client side packages. - `--dont-run-bundling`: Skip bundling for Blazor packages. - `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files. -- `--no-social-logins` or `-nsl`: Skipts the social login configuration. +- `--no-social-logins` or `-nsl`: Skips the social login configuration. - `--no-multi-tenancy`: Disables multi-tenancy support in the generated solution. - `--no-tests` or `-ntp`: Does not add test projects. - *Module Options*: You can skip some modules if you don't want to add them to your solution, or include if you want them (*Available for* ***Team*** *or higher licenses*). Available commands: @@ -257,14 +261,14 @@ The following options apply only when `--modern` is used: | Option | Description | Templates | | --- | --- | --- | -| `--shadcn-theme ` | Shadcn/UI color theme. See [Shadcn Theme Values](#shadcn-theme-values). | all `--modern` templates | -| `--admin-password ` | Initial admin user password. | all `--modern` templates | +| `--shadcn-theme ` | Sets the shadcn/ui color theme for the generated React apps. See [Shadcn Theme Values](#shadcn-theme-values). | all `--modern` templates | +| `--admin-password ` | Sets the initial admin user password. | all `--modern` templates | | `--modular` | Generates a modular monolith variant. | `app-nolayers --modern` | -| `--services ` | Comma-separated additional microservice names (for example: `Ordering,Shipping`). | `microservice --modern` | +| `--services ` | Adds extra microservice names as a comma-separated list (for example, `Ordering,Shipping`). | `microservice --modern` | #### Modern Templates -Add `--modern` to any template to use its modern variant. Modern templates use a different template source (shipped with ABP Studio) compared to legacy templates (which use NuGet extension packages). They are **React-first** and have a narrower set of supported options. +Add `--modern` to a supported template to use its modern variant. Modern templates use a different template source, shipped with ABP Studio, compared to legacy templates that use NuGet extension packages. They are **React-first** and have a narrower set of supported options. ```bash abp new Acme.BookStore --template app --modern @@ -272,19 +276,19 @@ abp new Acme.BookStore --template app-nolayers --modern abp new Acme.BookStore --template microservice --modern ``` - | Template + `--modern` | UI Framework | Mobile | | ----------------------- | ---------------------------------------------------------- | ------------------------ | | `app --modern` | `react` (default) or `no-ui` | `none` or `react-native` | | `app-nolayers --modern` | `react` (default) or `no-ui` | `none` or `react-native` | | `microservice --modern` | `react` (default, includes React Admin Console) or `no-ui` | `none` or `react-native` | - > Blazor, Angular, MVC, and MAUI Blazor UI frameworks are **not** supported with `--modern`. The `maui` mobile option is also not supported with `--modern`. > > Options that are not supported by a modern template are ignored with a warning in the CLI output. > -> `--modern` can also be used with `--ready-config-path` and `--solution-history-id`. In these cases, the template in the JSON configuration is mapped to its modern variant. +> `--modern` can also be used with `--ready-config-path` (`-rcp`) and `--solution-history-id` (`-shi`). In these cases, the template in the JSON configuration or solution history record is mapped to its modern variant. See [Using Existing Configuration](new-command-samples.md#using-existing-configuration) for configuration-file and solution-history examples. + +For `app --modern` and `app-nolayers --modern`, the generated solution includes a `react/` folder for your application. The ABP Admin Console is hosted by the backend through the `Volo.Abp.AdminConsole` package and is served from `/admin-console/`; there is no separate `apps/react-admin-console/` folder. When using `--template microservice --modern`, the generated solution includes: @@ -311,9 +315,15 @@ abp new Acme.BookStore --template microservice --modern # Modern microservice with no UI abp new Acme.BookStore --template microservice --modern --ui-framework no-ui +# Modern single-layer modular monolith +abp new Acme.BookStore --template app-nolayers --modern --modular + # Modern microservice with PostgreSQL abp new Acme.BookStore --template microservice --modern --database-management-system postgresql +# Modern microservice with additional services +abp new Acme.BookStore --template microservice --modern --services Ordering,Shipping + # Modern microservice with React Native mobile abp new Acme.BookStore --template microservice --modern --mobile react-native ``` diff --git a/docs/en/framework/ui/react/index.md b/docs/en/framework/ui/react/index.md index cb712d961d..e74239ea40 100644 --- a/docs/en/framework/ui/react/index.md +++ b/docs/en/framework/ui/react/index.md @@ -9,9 +9,9 @@ ## Introduction -ABP provides a **React UI** option for building modern, client-side web applications. The React UI is part of the **modern template system** and is only available when creating a solution with the `--modern` flag via the [ABP CLI](../../../cli/index.md) or through the **Modern Wizard** in [ABP Studio](../../../studio/index.md). +ABP provides a **React UI** option for building modern, client-side web applications. The React UI is part of the **modern template system** and is available when you create a solution through the **Modern Wizard** in [ABP Studio](../../../studio/index.md) or with `abp new --modern` using [ABP CLI](../../../cli/index.md). -> React UI is **not** available in the legacy (non-modern) templates. You must use the modern template system to get a React-based solution. See [Creating a Solution](#creating-a-solution) below. +> React UI is **not** available in the legacy (non-modern) templates. Use `Volo.Abp.Studio.Cli` or ABP Studio's modern template flow to create a React-based solution. The legacy CLI path (`--old`) does not create modern React solutions. The React UI is built on a modern, industry-standard stack: @@ -28,13 +28,13 @@ The React UI is built on a modern, industry-standard stack: ## React App and Admin Console -Every modern React solution consists of two parts: **your React application** and the **ABP Admin Console**. +When you create a modern solution with React UI, it contains two UI surfaces: **your React application** and the **ABP Admin Console**. ### React App (Your Application) This is **your application** — the user-facing SPA that you own and customize freely. It comes with: -- A sample **Books CRUD page** (when `--sample-crud-page` is used) demonstrating how to build a full create/read/update/delete page with the ABP backend +- A sample **Books CRUD page** when the template is generated with sample CRUD support, demonstrating how to build a full create/read/update/delete page with the ABP backend - A plain **Users page** as a minimal reference - Pre-configured authentication via OIDC against the ABP Auth Server - Pre-configured HTTP client (Axios) with ABP API integration @@ -43,7 +43,7 @@ This is where you build your business-specific pages and features. The location of the React app differs by template type: -- **Layered (`app --modern`) and Single-layer (`app-nolayers --modern`)**: the React app lives at the **root of the solution** (alongside the backend projects). +- **Layered (`app --modern`) and Single-layer (`app-nolayers --modern`)**: the React app lives in the `react/` folder at the solution root. - **Microservice (`microservice --modern`)**: the React app lives at `apps/react/`. ### React Admin Console (`Volo.Abp.AdminConsole`) @@ -74,7 +74,7 @@ In both cases the Admin Console is accessible from the main React app via a navi ### Using ABP CLI -Pass the `--modern` flag to `abp new`: +Install or update `Volo.Abp.Studio.Cli`, then pass the `--modern` flag to `abp new`: ````bash # Layered app with React UI (default when --modern is used) @@ -99,11 +99,11 @@ To create a solution without any UI (API-only backend): abp new Acme.BookStore --template app --modern --ui-framework no-ui ```` -See the [ABP CLI documentation](../../../cli/index.md#modern-templates) for the full list of options. +See the [ABP CLI documentation](../../../cli/index.md#modern-templates) for the full list of modern templates, supported UI/mobile combinations, and modern-only options like `--shadcn-theme`, `--admin-password`, `--modular`, and `--services`. ### Using ABP Studio -Open ABP Studio and use the **New Solution** wizard. Select the **Modern** template variant and choose **React** as the UI framework. The wizard guides you through all available options and generates the solution. +Open ABP Studio and use the **New Solution** wizard. Choose the modern template flow, select the solution type you want to create, and use **React** as the UI framework. The wizard shows the options supported by the selected modern template and generates the solution with the same modern template system used by `abp new --modern`. ## Solution Structure @@ -111,7 +111,7 @@ The layout of the React-related files depends on the template type. ### Layered and Single-layer Templates -For `app --modern` and `app-nolayers --modern`, the React app lives at the root of the solution alongside the backend projects. The Admin Console is embedded in the backend via the `Volo.Abp.AdminConsole` NuGet package — there is no separate React Admin Console folder. +For `app --modern` and `app-nolayers --modern`, the React app lives in the `react/` folder at the solution root. The Admin Console is embedded in the backend via the `Volo.Abp.AdminConsole` NuGet package; there is no separate React Admin Console folder. ``` Acme.BookStore/ @@ -172,7 +172,7 @@ Acme.BookStore/ ### Runtime Configuration (`dynamic-env.json`) -The React app reads its runtime configuration from `public/dynamic-env.json`. This file is loaded at startup and allows you to change settings without rebuilding the application — useful for different environments (development, staging, production). +The React app reads its runtime configuration from `public/dynamic-env.json`. This file is loaded at startup and allows you to change settings without rebuilding the application, which is useful for different environments like development, staging, and production. ```json { @@ -346,7 +346,7 @@ npm run test:coverage 1. Start the backend (from ABP Studio or `dotnet run` in the `*.HttpApi.Host` project). 2. Navigate to the React app directory and start the dev server. -For **layered and single-layer** templates, the React app is at the solution root: +For **layered and single-layer** templates, the React app is in the `react/` folder at the solution root: ````bash cd react @@ -354,7 +354,7 @@ npm install npm run dev ```` -For the **microservice** template, it is under `apps/`: +For the **microservice** template, the React app is under `apps/`: ````bash cd apps/react @@ -382,7 +382,7 @@ The output is placed in `dist/` and can be served by any static file host or CDN ## Accessing the Admin Console -The Admin Console is accessible from within the main React app. After logging in, you will find a link to the Admin Console in the navigation. Clicking it opens the Admin Console, which is served by the backend at `/admin-console/*`. +The Admin Console is accessible from within the main React app. After logging in, you will find a link to the Admin Console in the navigation. In layered and single-layer solutions it is served by the backend at `/admin-console/*`; in microservice solutions it is served as a standalone React app through the Web Gateway. The Admin Console provides full management capabilities for: From 1be9915bf10bc6e2acaa79ef476c5b6332e823cb Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 17:02:32 +0300 Subject: [PATCH 02/10] docs: rename legacy template wording to classic Co-authored-by: Cursor --- docs/en/cli/differences-between-old-and-new-cli.md | 4 ++-- docs/en/cli/index.md | 8 ++++---- docs/en/framework/ui/react/index.md | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/en/cli/differences-between-old-and-new-cli.md b/docs/en/cli/differences-between-old-and-new-cli.md index 440b785797..2d1cef6f3b 100644 --- a/docs/en/cli/differences-between-old-and-new-cli.md +++ b/docs/en/cli/differences-between-old-and-new-cli.md @@ -7,9 +7,9 @@ # Old ABP CLI vs New ABP CLI -ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or ABP Studio features. With **v8.2+**, the old/legacy ABP CLI has been replaced with a new [CLI](index.md) system to align with the new templating system and [ABP Studio](../studio/index.md). Also, some superior features/commands have been introduced with the new CLI, such as `kube-connect` and `kube-intercept` commands. +ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or ABP Studio features. With **v8.2+**, the old/classic ABP CLI has been replaced with a new [CLI](index.md) system to align with the new templating system and [ABP Studio](../studio/index.md). Also, some superior features/commands have been introduced with the new CLI, such as `kube-connect` and `kube-intercept` commands. -In this guide, you will learn the motivation behind this change, some questions that you may have, how to use the old/legacy CLI, its features, and more... +In this guide, you will learn the motivation behind this change, some questions that you may have, how to use the old/classic CLI, its features, and more... ## Reason For The Change diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md index fd56aa0809..a848320549 100644 --- a/docs/en/cli/index.md +++ b/docs/en/cli/index.md @@ -9,7 +9,7 @@ ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or [ABP Studio](../studio/index.md) features. -This document describes `Volo.Abp.Studio.Cli`, the ABP CLI package that works with the ABP Studio template system. Modern templates, including React UI support, are available through this package. If you need to run the legacy `Volo.Abp.Cli`, pass `--old` at the end of the command. +This document describes `Volo.Abp.Studio.Cli`, the ABP CLI package that works with the ABP Studio template system. Modern templates, including React UI support, are available through this package. If you need to run the classic `Volo.Abp.Cli`, pass `--old` at the end of the command. ## Installation @@ -121,7 +121,7 @@ abp cli clear-cache Generates a new solution based on the ABP [startup templates](../solution-templates). See [new solution create sample commands](new-command-samples.md). -The `new` command uses the ABP Studio template system by default. Add `--modern` to create a solution from the modern template system. Modern templates are React-first and are not available through the legacy CLI (`--old`). +The `new` command uses the ABP Studio template system by default. Add `--modern` to create a solution from the modern template system. Modern templates are React-first and are not available through the classic CLI (`--old`). Usage: @@ -252,7 +252,7 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md - `-chat`: Includes the Chat module. - `--ai-management`: Includes the AI Management module. - `--ai-providers`: Specifies AI providers (comma-separated). Available values: `Ollama`, `OpenAI`. Requires `--ai-management`. -- `--legacy`: Generates a legacy solution. +- `--legacy`: Generates a classic solution. - `trust-version`: Trusts the user's version and does not check if the version exists or not. If the template with the given version is found in the cache, it will be used, otherwise throws an exception. ##### Modern Template Options @@ -268,7 +268,7 @@ The following options apply only when `--modern` is used: #### Modern Templates -Add `--modern` to a supported template to use its modern variant. Modern templates use a different template source, shipped with ABP Studio, compared to legacy templates that use NuGet extension packages. They are **React-first** and have a narrower set of supported options. +Add `--modern` to a supported template to use its modern variant. Modern templates use a different template source, shipped with ABP Studio, compared to classic templates that use NuGet extension packages. They are **React-first** and have a narrower set of supported options. ```bash abp new Acme.BookStore --template app --modern diff --git a/docs/en/framework/ui/react/index.md b/docs/en/framework/ui/react/index.md index e74239ea40..e5fd471543 100644 --- a/docs/en/framework/ui/react/index.md +++ b/docs/en/framework/ui/react/index.md @@ -11,7 +11,7 @@ ABP provides a **React UI** option for building modern, client-side web applications. The React UI is part of the **modern template system** and is available when you create a solution through the **Modern Wizard** in [ABP Studio](../../../studio/index.md) or with `abp new --modern` using [ABP CLI](../../../cli/index.md). -> React UI is **not** available in the legacy (non-modern) templates. Use `Volo.Abp.Studio.Cli` or ABP Studio's modern template flow to create a React-based solution. The legacy CLI path (`--old`) does not create modern React solutions. +> React UI is **not** available in the classic (non-modern) templates. Use `Volo.Abp.Studio.Cli` or ABP Studio's modern template flow to create a React-based solution. The classic CLI path (`--old`) does not create modern React solutions. The React UI is built on a modern, industry-standard stack: From ee566ff683d04876424e258f6fa042a3355c2ee3 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 17:51:57 +0300 Subject: [PATCH 03/10] docs: add React environment and testing guides Co-authored-by: Cursor --- .../ui/react/environment-variables.md | 121 ++++++++++++++ docs/en/framework/ui/react/unit-testing.md | 150 ++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 docs/en/framework/ui/react/environment-variables.md create mode 100644 docs/en/framework/ui/react/unit-testing.md diff --git a/docs/en/framework/ui/react/environment-variables.md b/docs/en/framework/ui/react/environment-variables.md new file mode 100644 index 0000000000..2b84b0c4d0 --- /dev/null +++ b/docs/en/framework/ui/react/environment-variables.md @@ -0,0 +1,121 @@ +```json +//[doc-seo] +{ + "Description": "Learn how runtime configuration and environment variables work in ABP React UI applications." +} +``` + +# Environment Variables + +ABP React UI applications use a runtime configuration file and Vite environment variables together. The template is preconfigured by ABP Studio's modern wizard, available with ABP Studio **v3.0+**, so a newly created solution already contains working local values for the API, Auth Server, OpenIddict client, and Admin Console link. + +You usually change these values when moving the application to another environment such as staging or production. + +## Configuration Sources + +The React template reads configuration from these places: + +- `dynamic-env.json`: runtime configuration that can be changed without rebuilding the application. +- `public/dynamic-env.json`: the file served by the app. The Vite build copies the root `dynamic-env.json` into this location when it exists. +- `src/env.ts`: local fallback values used when runtime configuration is not loaded. +- `.env` files / shell variables: Vite variables such as `VITE_API_URL`, `VITE_AUTH_URL`, and `VITE_APP_URL`. + +For layered and single-layer modern templates, the React app is in the `react/` folder. For the microservice modern template, it is in `apps/react/`. + +## `dynamic-env.json` + +The runtime configuration file has the same purpose as Angular's dynamic environment configuration: it lets you deploy the same build artifact to different environments and change the API or authentication endpoints at runtime. + +```json +{ + "application": { + "baseUrl": "https://localhost:3000", + "name": "Acme.BookStore" + }, + "oAuthConfig": { + "issuer": "https://localhost:44301/", + "redirectUri": "https://localhost:3000", + "clientId": "Acme_BookStore_App", + "scope": "offline_access openid profile email phone AuthServer IdentityService AdministrationService" + }, + "apis": { + "default": { + "url": "https://localhost:44300", + "rootNamespace": "Acme.BookStore" + } + }, + "adminConsoleUrl": "https://localhost:44307" +} +``` + +The template loads `/dynamic-env.json` first and then tries `/getEnvConfig` for compatibility with environments that expose the file through that endpoint. + +## Available Values + +| Key | Description | +| --- | --- | +| `application.baseUrl` | Public URL of the React application. It is used as a fallback for OAuth redirect URLs. | +| `application.name` | Application name. | +| `application.logoUrl` | Optional logo URL for application branding. | +| `oAuthConfig.issuer` | Auth Server / OpenIddict authority URL. | +| `oAuthConfig.redirectUri` | Redirect URI registered for the React OpenIddict client. | +| `oAuthConfig.clientId` | OpenIddict client ID. The main React app uses `_App`. | +| `oAuthConfig.scope` | OAuth scopes requested by the SPA. | +| `apis.default.url` | Backend API base URL. In microservice solutions, this normally points to the Web Gateway. | +| `apis.default.rootNamespace` | Root namespace used by generated API code and module-specific clients. | +| `adminConsoleUrl` | Origin of the Admin Console app. The React template uses it to open `/admin-console`. | + +The `DynamicEnv` type also includes fields such as `production`, `oAuthConfig.requireHttps`, `oAuthConfig.responseType`, `oAuthConfig.strictDiscoveryDocumentValidation`, and `oAuthConfig.skipIssuerCheck`. The template's OIDC setup always uses the Authorization Code flow by setting `responseType` to `code`. + +## Vite Variables + +The React template uses Vite and reads environment variables with `loadEnv(mode, process.cwd(), '')`, so variables are not limited to the `VITE_` prefix inside `vite.config.ts`. + +The important variables for developers are: + +| Variable | Description | +| --- | --- | +| `VITE_API_URL` | Overrides the backend API or gateway URL used by the dev proxy and runtime fallback. | +| `VITE_AUTH_URL` | Overrides the Auth Server URL used by the dev proxy and runtime fallback. If omitted, the dev proxy can fall back to `VITE_API_URL`. | +| `VITE_APP_URL` | Overrides the React app URL used as the OAuth redirect URI fallback. | + +Example: + +```bash +VITE_API_URL=https://api.bookstore.example.com +VITE_AUTH_URL=https://auth.bookstore.example.com +VITE_APP_URL=https://bookstore.example.com +``` + +## What ABP Studio Preconfigures + +When a React solution is created with ABP Studio v3.0+ or `abp new --modern`, the template fills these values from the generated solution configuration: + +- Local launch ports for the React app, Web Gateway/API host, Auth Server, and Admin Console. +- The OpenIddict client ID, usually `_App`. +- OAuth scopes based on the selected modules, such as Identity, Administration, SaaS, Audit Logging, GDPR, File Management, AI Management, Language Management, or Chat. +- `adminConsoleUrl` when the template includes a separate Admin Console application. + +For local development, these generated values should work without manual changes. For production, update the API URL, Auth Server URL, redirect URI, client ID if you changed the seeded client, and any environment-specific scopes. + +## Development Proxy + +In development, `vite.config.ts` proxies these paths: + +- `/api` to `VITE_API_URL` or the generated API/gateway URL. +- `/connect` to `VITE_AUTH_URL`, `VITE_API_URL`, or the generated Auth Server URL. +- `/getEnvConfig` to `VITE_API_URL` or the generated API/gateway URL. + +This allows the React app to call same-origin paths during development while the backend services run on their own ports. + +## Deployment + +For deployment, prefer changing `dynamic-env.json` instead of rebuilding the React application for each environment. The file should be served with `application/json` content type and should not be rewritten to `index.html` by SPA fallback rules. + +If your server exposes `/getEnvConfig`, configure it to return the same JSON content as `dynamic-env.json`. + +## See Also + +- [React UI](./index.md) +- [Authorization](./authorization.md) +- [HTTP Requests](./http-requests.md) diff --git a/docs/en/framework/ui/react/unit-testing.md b/docs/en/framework/ui/react/unit-testing.md new file mode 100644 index 0000000000..46a3089eeb --- /dev/null +++ b/docs/en/framework/ui/react/unit-testing.md @@ -0,0 +1,150 @@ +```json +//[doc-seo] +{ + "Description": "Learn how to run and write unit tests in ABP React UI applications with Vitest and React Testing Library." +} +``` + +# Unit Testing React UI + +ABP React UI templates are preconfigured for unit testing. A solution created with ABP Studio v3.0+ or `abp new --modern --ui-framework react` includes Vitest, jsdom, React Testing Library, and jest-dom. + +You can add a test file and run the test command without adding extra test infrastructure. + +## Test Stack + +The React template uses: + +| Package | Purpose | +| --- | --- | +| `vitest` | Test runner and assertion library. | +| `jsdom` | Browser-like DOM environment for component tests. | +| `@testing-library/react` | Render React components and query the DOM like a user. | +| `@testing-library/jest-dom` | Extra DOM assertions such as `toBeInTheDocument`. | + +The template also includes `src/test/setup.ts`, which imports `@testing-library/jest-dom/vitest` and initializes the React i18n setup. + +## Configuration + +The test configuration is in `vitest.config.ts`: + +```ts +import { defineConfig } from 'vitest/config' +import react from '@vitejs/plugin-react' +import path from 'path' + +export default defineConfig({ + plugins: [react()], + test: { + environment: 'jsdom', + setupFiles: ['./src/test/setup.ts'], + include: ['src/**/*.{test,spec}.{ts,tsx}'], + globals: true, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, +}) +``` + +Tests can import application files with the same `@/` alias used by the app. + +## Running Tests + +Install dependencies once: + +```bash +npm install +``` + +Run tests in watch mode: + +```bash +npm run test +``` + +Run tests once, which is useful for CI: + +```bash +npm run test:run +``` + +The template's `package.json` maps these commands to `vitest` and `vitest run`. + +## Example Test + +The template includes example tests under `src/`. For example, `src/pages/home/HomePage.test.tsx` renders the home page and mocks the authentication hook: + +```tsx +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { render, screen } from '@testing-library/react' +import { HomePage } from './HomePage' +import * as auth from '@/lib/auth/AuthContext' + +vi.mock('@/lib/auth/AuthContext', () => ({ + useAuth: vi.fn(), +})) + +describe('HomePage', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it('renders login prompt when not authenticated', () => { + vi.mocked(auth.useAuth).mockReturnValue({ + isAuthenticated: false, + isLoading: false, + user: null, + login: vi.fn(), + logout: vi.fn(), + navigateToLogin: vi.fn(), + getAccessToken: vi.fn(), + } as unknown as ReturnType) + + render() + expect(screen.getByText('Welcome')).toBeInTheDocument() + expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument() + }) +}) +``` + +This style keeps the test focused on visible behavior. Dependencies that would require real authentication, network calls, or browser redirects are mocked. + +## Writing a Component Test + +Create a `*.test.tsx` file next to the component: + +```tsx +import { render, screen } from '@testing-library/react' +import { describe, expect, it } from 'vitest' +import { Button } from '@/components/ui/button' + +describe('Button', () => { + it('renders its content', () => { + render() + expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument() + }) +}) +``` + +Prefer queries such as `getByRole`, `getByLabelText`, and `getByText` because they describe what the user can see or do. + +## Writing a Service or Hook Test + +For non-component logic, use Vitest directly. The template includes tests for routing guards, permissions, authentication context, and Axios interceptors. + +When testing API code, mock the shared Axios instance or the lower-level dependency instead of calling a real backend. When testing permission behavior, mock the application configuration client or use the exported permission helpers. + +## Interpreting Output + +Vitest reports each test file, failed assertions, stack traces, and a summary of passed/failed tests. In watch mode, it reruns affected tests when files change. In `test:run` mode, Vitest exits with a non-zero status code if any test fails, which makes it suitable for CI pipelines. + +If a component test fails because an ABP service is not initialized, mock the hook or provider used by the component. For example, pages that call `useAuth()` or `usePermissions()` should provide a controlled mock for those hooks unless the test is specifically verifying the provider. + +## See Also + +- [Components](./components/index.md) +- [Authorization](./authorization.md) +- [Permission Management](./permission-management.md) From 6c3715450e5e44489ba1d3e7324ff05a030e192f Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 17:53:46 +0300 Subject: [PATCH 04/10] docs: add React core UI guides Co-authored-by: Cursor --- docs/en/framework/ui/react/authorization.md | 183 +++++++++++++++ docs/en/framework/ui/react/http-requests.md | 213 ++++++++++++++++++ docs/en/framework/ui/react/localization.md | 158 +++++++++++++ .../ui/react/permission-management.md | 171 ++++++++++++++ 4 files changed, 725 insertions(+) create mode 100644 docs/en/framework/ui/react/authorization.md create mode 100644 docs/en/framework/ui/react/http-requests.md create mode 100644 docs/en/framework/ui/react/localization.md create mode 100644 docs/en/framework/ui/react/permission-management.md diff --git a/docs/en/framework/ui/react/authorization.md b/docs/en/framework/ui/react/authorization.md new file mode 100644 index 0000000000..4f6d673d87 --- /dev/null +++ b/docs/en/framework/ui/react/authorization.md @@ -0,0 +1,183 @@ +```json +//[doc-seo] +{ + "Description": "Learn how authentication and authorization are configured in ABP React UI applications." +} +``` + +# Authorization in React UI + +OAuth is preconfigured in ABP React UI templates. When you create a React solution with ABP Studio v3.0+ or `abp new --modern --ui-framework react`, the template includes OpenID Connect settings, an OpenIddict client, route guards, and authentication hooks. + +The React app authenticates against the ABP Auth Server using the **Authorization Code flow with PKCE**, which is the recommended flow for browser-based applications. + +## Packages + +The template uses these packages for authentication: + +| Package | Purpose | +| --- | --- | +| `@volo/abp-oidc-auth` | Framework-agnostic OIDC client helpers for ABP/OpenIddict backends. | +| `@volo/abp-react-oidc-auth` | React adapter for the ABP OIDC client. | +| `oidc-client-ts` | Underlying OIDC protocol implementation. | + +The package list also includes `@volo/abp-app-config` and `@volo/abp-react-app-config`, which are used to fetch application configuration and permissions after authentication. + +## OAuth Configuration + +The OIDC settings are resolved from runtime configuration first and fall back to `src/env.ts`. + +```ts +export function getOAuthConfig(): { + issuer: string + redirectUri: string + clientId: string + scope: string + responseType: 'code' +} { + return { + issuer: loadedConfig?.oAuthConfig?.issuer ?? env.oauth.issuer, + redirectUri: loadedConfig?.oAuthConfig?.redirectUri ?? env.oauth.redirectUri, + clientId: loadedConfig?.oAuthConfig?.clientId ?? env.oauth.clientId, + scope: loadedConfig?.oAuthConfig?.scope ?? env.oauth.scope, + responseType: 'code', + } +} +``` + +The important configuration values are: + +- `oAuthConfig.issuer`: Auth Server / OpenIddict authority URL. +- `oAuthConfig.redirectUri`: URL where the Auth Server redirects after login. +- `oAuthConfig.clientId`: OpenIddict client ID, normally `_App`. +- `oAuthConfig.scope`: Scopes requested by the React app. + +See [Environment Variables](./environment-variables.md) for the full runtime configuration model. + +## Initializing Authentication + +The app loads runtime configuration before initializing OIDC: + +```tsx +async function bootstrap() { + await loadRuntimeConfig() + initUserManager() + createRoot(document.getElementById('root')!).render( + + + + ) +} +``` + +`initUserManager()` creates the ABP React OIDC client: + +```ts +client = createAbpReactOidcAuth({ + authority: config.issuer, + clientId: config.clientId, + redirectUri: config.redirectUri, + postLogoutRedirectUri: config.redirectUri, + scope: config.scope, + responseType: config.responseType, + automaticSilentRenew: true, + userStoreType: 'localStorage', + userStorePrefix: `oidc.${config.clientId}`, + silentRedirectUri: `${window.location.origin}/silent-renew.html`, +}) +``` + +The template stores the OIDC user in local storage and enables silent renewal with `public/silent-renew.html`. + +## Auth Provider and Hook + +`AuthProvider` wraps the app and handles the OIDC callback: + +```tsx +export function AuthProvider({ children }: { children: ReactNode }) { + const authClient = getAuthClient() + + useEffect(() => { + const params = new URLSearchParams(window.location.search) + if (!params.has('code') || !params.has('state')) return + void authClient.handleSigninCallback().then(() => + window.history.replaceState({}, document.title, window.location.pathname) + ) + }, []) + + return {children} +} +``` + +Use `useAuth()` in components: + +```tsx +import { useAuth } from '@/lib/auth/AuthContext' + +export function LoginButton() { + const { isAuthenticated, isLoading, login, logout, user } = useAuth() + + if (isLoading) return null + + return isAuthenticated ? ( + + ) : ( + + ) +} +``` + +## Route Protection + +The React template uses TanStack Router. Protected routes use `beforeLoad` guards. + +```ts +const identityLayoutRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/identity', + component: IdentityLayout, + beforeLoad: authGuard, +}) +``` + +`authGuard` checks the current OIDC user and redirects unauthenticated users to the Auth Server: + +```ts +export async function authGuard({ location }: GuardContext) { + const user = await userManager.getUser() + if (!user || user.expired) { + await userManager.signinRedirect({ + state: { returnUrl: location.href }, + }) + throw new Error('Redirecting to login') + } +} +``` + +Routes that also require a permission use `createPermissionGuard`: + +```ts +const usersRoute = createRoute({ + getParentRoute: () => identityLayoutRoute, + path: 'users', + component: UsersPage, + beforeLoad: createPermissionGuard('AbpIdentity.Users'), +}) +``` + +Permission checks are explained in [Permission Management](./permission-management.md). + +## OpenIddict Clients + +The generated OpenIddict clients depend on the template: + +- Layered and single-layer modern templates use the main React client, normally `_App`. +- Microservice modern templates also include an Admin Console client, normally `_AdminConsole`, because the Admin Console is a separate React app. + +If you change URLs after generation, update both the runtime configuration and the corresponding OpenIddict client redirect URLs. + +## See Also + +- [Environment Variables](./environment-variables.md) +- [Permission Management](./permission-management.md) +- [Authorization](../../../framework/fundamentals/authorization/index.md) diff --git a/docs/en/framework/ui/react/http-requests.md b/docs/en/framework/ui/react/http-requests.md new file mode 100644 index 0000000000..2c01884635 --- /dev/null +++ b/docs/en/framework/ui/react/http-requests.md @@ -0,0 +1,213 @@ +```json +//[doc-seo] +{ + "Description": "Learn how HTTP requests are made in ABP React UI applications with Axios, runtime configuration, and ABP interceptors." +} +``` + +# HTTP Requests + +ABP React UI templates use [Axios](https://axios-http.com/) for HTTP requests. The generated app contains a shared Axios instance with ABP-specific request and response interceptors, plus typed API modules for backend endpoints. + +The shared client is defined in `src/lib/api/axios.ts` and exported as `api`. + +## Base URL + +The Axios base URL is resolved at request time from runtime configuration: + +```ts +export function getApiBaseUrl(): string { + const apiUrl = getApiUrl() + if (apiUrl.startsWith('http://') || apiUrl.startsWith('https://')) { + return apiUrl.replace(/\/$/, '') + '/api' + } + if (import.meta.env.DEV) { + return '/api' + } + return apiUrl.replace(/\/$/, '') + '/api' +} +``` + +The API URL comes from: + +1. `dynamic-env.json` -> `apis.default.url` +2. `VITE_API_URL` +3. `src/env.ts` generated fallback + +In microservice solutions, `apis.default.url` normally points to the Web Gateway. In layered and single-layer solutions, it normally points to the HTTP API host. + +## Shared Axios Instance + +The template creates one shared instance: + +```ts +export const api = axios.create({ + baseURL: '', + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'Content-Type': 'application/json', + }, +}) +``` + +Use this instance for application API modules instead of creating new Axios clients. It centralizes ABP headers, authentication, tenant handling, language handling, and redirects. + +## Request Interceptor + +Before each request, the template: + +- Sets `baseURL` from runtime configuration. +- Adds `Authorization: Bearer ` from the OIDC user. +- Adds `__tenant` when the user has selected a tenant. +- Adds `Accept-Language` from i18next. +- Keeps default AJAX headers such as `X-Requested-With`. + +```ts +api.interceptors.request.use(async (config) => { + config.baseURL = getApiBaseUrl() + + const user = await userManager.getUser() + if (user?.access_token) { + config.headers.Authorization = `Bearer ${user.access_token}` + } + + const tenantId = sessionStorage.getItem('abp_tenant_id') + if (tenantId && !config.headers.__tenant) { + config.headers.__tenant = tenantId + } + + if (i18n?.language) { + config.headers['Accept-Language'] = + config.headers['Accept-Language'] ?? i18n.language + } + + return config +}) +``` + +## Response Interceptor + +The response interceptor handles common authorization failures: + +- `401 Unauthorized`: redirects to login unless `skipAuthRedirect` is set. +- `403 Forbidden`: redirects to `/403` unless `skip403Redirect` is set. +- Other errors are rejected so the caller can handle them. + +```ts +api.interceptors.response.use( + (response) => response, + async (error) => { + const status = error.response?.status + + if (status === 401 && !error.config?.skipAuthRedirect) { + await userManager.signinRedirect() + return Promise.reject(new Error('Unauthorized - redirecting to login')) + } + + if (status === 403 && !error.config?.skip403Redirect) { + window.location.href = '/403' + return Promise.reject(new Error('Forbidden')) + } + + return Promise.reject(error) + } +) +``` + +Use `skipAuthRedirect` or `skip403Redirect` for calls where the component should handle the error itself. + +## Typed API Modules + +The template organizes backend calls under `src/lib/api/`. For example, the Books sample defines DTOs and functions in `books.ts`: + +```ts +import { api } from './axios' + +export interface PagedResultDto { + items: T[] + totalCount: number +} + +export interface BookDto { + id: string + name?: string + price: number +} + +export async function getBooks(): Promise> { + const { data } = await api.get>('/app/book', { + params: { + maxResultCount: 10, + skipCount: 0, + }, + }) + return data +} +``` + +Notice that the API module calls `/app/book`, not `/api/app/book`. The shared Axios base URL already includes the `/api` prefix when needed. + +## Using Requests from Components + +The template uses TanStack Query for server state: + +```tsx +const { data, isLoading } = useQuery({ + queryKey: ['books', skipCount], + queryFn: () => + getBooks({ + maxResultCount: 10, + skipCount, + sorting: 'creationTime desc', + }), +}) +``` + +Mutations use `useMutation` and invalidate related queries after success: + +```tsx +const createMutation = useMutation({ + mutationFn: createBook, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['books'] }) + toast.success(t('AbpUi::SavedSuccessfully')) + }, +}) +``` + +## Adding a New API Module + +Create a file under `src/lib/api/`: + +```ts +import { api } from './axios' + +export interface ProductDto { + id: string + name: string +} + +export async function getProducts(): Promise { + const { data } = await api.get('/app/product') + return data +} +``` + +Then consume it from a component with TanStack Query: + +```tsx +const productsQuery = useQuery({ + queryKey: ['products'], + queryFn: getProducts, +}) +``` + +## Development Proxy + +In development, Vite proxies `/api`, `/connect`, and `/getEnvConfig`. This lets the React app use same-origin paths while calls are forwarded to the backend, Auth Server, or gateway configured by `VITE_API_URL` and `VITE_AUTH_URL`. + +## See Also + +- [Environment Variables](./environment-variables.md) +- [Authorization](./authorization.md) +- [Permission Management](./permission-management.md) diff --git a/docs/en/framework/ui/react/localization.md b/docs/en/framework/ui/react/localization.md new file mode 100644 index 0000000000..64298278f0 --- /dev/null +++ b/docs/en/framework/ui/react/localization.md @@ -0,0 +1,158 @@ +```json +//[doc-seo] +{ + "Description": "Learn how localization works in ABP React UI applications with i18next and ABP application configuration." +} +``` + +# Localization + +ABP React UI templates use [i18next](https://www.i18next.com/) with [react-i18next](https://react.i18next.com/). The generated app includes local JSON resources and integrates with ABP application configuration through the `@volo/abp-app-config` packages. + +## Localization Files + +The main React app stores client-side translations under `src/locales/`. + +```text +src/ +├── locales/ +│ └── en.json +└── lib/ + └── i18n/ + └── i18n.ts +``` + +The default `i18n.ts` imports the English resource and registers it: + +```ts +import i18n from 'i18next' +import { initReactI18next } from 'react-i18next' +import en from '@/locales/en.json' + +i18n.use(initReactI18next).init({ + resources: { + en: { translation: en }, + }, + lng: 'en', + fallbackLng: 'en', + keySeparator: false, + nsSeparator: false, + interpolation: { + escapeValue: false, + }, +}) +``` + +`keySeparator` and `nsSeparator` are disabled so ABP-style keys such as `AbpIdentity::Users` and `Menu:Home` can be used directly. + +## Using Localized Text + +Use `useTranslation()` from `react-i18next` in components: + +```tsx +import { useTranslation } from 'react-i18next' + +export function BooksTitle() { + const { t } = useTranslation() + + return

{t('Menu:Books')}

+} +``` + +ABP localization keys commonly use the `ResourceName::Key` format: + +```tsx +{t('AbpIdentity::Users')} +{t('AbpAccount::Login')} +{t('AbpUi::SavedSuccessfully')} +``` + +Application-specific menu keys may use names like `Menu:Home` or `Menu:Books`. + +## Adding a Translation + +Add the key to `src/locales/en.json`: + +```json +{ + "Menu:Reports": "Reports", + "Reports": "Reports" +} +``` + +Then use it from a component: + +```tsx +const { t } = useTranslation() + +return

{t('Reports')}

+``` + +## Adding a Language + +Create a new JSON file, for example `src/locales/tr.json`: + +```json +{ + "Menu:Reports": "Raporlar", + "Reports": "Raporlar" +} +``` + +Register it in `src/lib/i18n/i18n.ts`: + +```ts +import en from '@/locales/en.json' +import tr from '@/locales/tr.json' + +i18n.use(initReactI18next).init({ + resources: { + en: { translation: en }, + tr: { translation: tr }, + }, + lng: 'en', + fallbackLng: 'en', +}) +``` + +If you add a language selector, call `i18n.changeLanguage('tr')` when the user chooses Turkish. + +## Server-Side ABP Localization + +ABP's backend localization system is still the source of truth for server-defined resources, validation messages, exception messages, and module texts. The React app uses ABP application configuration through `@volo/abp-app-config` / `@volo/abp-react-app-config` for auth and configuration data, and these packages can include localization resources when configured to do so. + +The main template currently creates the app configuration client with: + +```ts +export const appConfig = createAbpReactAppConfig({ + baseUrl: () => getApiUrl(), + includeLocalizationResources: false, +}) +``` + +Because `includeLocalizationResources` is disabled in the main React template, UI text is normally loaded from `src/locales/*.json`. If you enable server-provided localization resources, make sure your UI initialization merges them into i18next before rendering localized components. + +## Request Culture + +The shared Axios client sends the active i18next language with each request: + +```ts +if (i18n?.language) { + config.headers['Accept-Language'] = + config.headers['Accept-Language'] ?? i18n.language +} +``` + +This lets backend responses, validation messages, and exception messages use the selected culture when the server supports it. + +## Admin Console Localization + +The Admin Console has its own React app and localization setup. In layered and single-layer templates, it is served from the `Volo.Abp.AdminConsole` package. In microservice templates, it is generated as `apps/react-admin-console/`. + +The Admin Console host can expose available languages through `AdminConsole:LocalizationLanguages`, and `/admin-console/api/config` returns the normalized language list. + +## See Also + +- [React UI](./index.md) +- [HTTP Requests](./http-requests.md) +- [Localization](../../../framework/fundamentals/localization.md) diff --git a/docs/en/framework/ui/react/permission-management.md b/docs/en/framework/ui/react/permission-management.md new file mode 100644 index 0000000000..fc009ce5a2 --- /dev/null +++ b/docs/en/framework/ui/react/permission-management.md @@ -0,0 +1,171 @@ +```json +//[doc-seo] +{ + "Description": "Learn how permissions are fetched, stored, checked, and applied in ABP React UI applications." +} +``` + +# Permission Management + +ABP permissions are defined on the server side and are exposed to the React app through ABP application configuration. The React template uses those permissions to protect routes, hide sidebar items, and conditionally render UI actions. + +For the server-side permission system, see [Authorization](../../../framework/fundamentals/authorization/index.md). + +## Packages + +The React template uses: + +| Package | Purpose | +| --- | --- | +| `@volo/abp-app-config` | Framework-agnostic ABP application configuration client. | +| `@volo/abp-react-app-config` | React hooks and adapters for application configuration. | + +The template creates a shared app configuration client in `src/lib/auth/permissions.ts`: + +```ts +export const appConfig = createAbpReactAppConfig({ + baseUrl: () => getApiUrl(), + includeLocalizationResources: false, +}) +``` + +## Fetching Permissions + +After the user logs in, `AuthProvider` fetches application configuration with the current access token: + +```ts +const user = await authClient.getUserManager().getUser() +if (user && !user.expired) { + await fetchAppConfig(user.access_token ?? null) +} +``` + +`fetchAppConfig` also sends the current tenant ID when one is selected: + +```ts +export async function fetchAppConfig(token: string | null): Promise { + const headers: Record = {} + const tenantId = sessionStorage.getItem('abp_tenant_id') + if (tenantId) headers.__tenant = tenantId + await appConfig.fetchConfig(token, { headers }) +} +``` + +The response includes the current user's granted policies. These are stored by the app configuration client and exposed to React components. + +## Checking Permissions in Components + +Use `usePermissions()` from `src/lib/auth/permissions.ts`: + +```tsx +import { usePermissions } from '@/lib/auth/permissions' + +export function BookActions() { + const { isGranted } = usePermissions() + + return ( + <> + {isGranted('MyProjectName.Books.Edit') && } + {isGranted('MyProjectName.Books.Delete') && } + + ) +} +``` + +The Books page uses this pattern for edit and delete actions: + +```ts +const { isGranted } = usePermissions() +const canEdit = isGranted('MyProjectName.Books.Edit') +const canDelete = isGranted('MyProjectName.Books.Delete') +``` + +## Route Guards + +Routes can require a permission by using `createPermissionGuard`: + +```ts +const booksRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/books', + component: BooksPage, + beforeLoad: createPermissionGuard('MyProjectName.Books'), +}) +``` + +`createPermissionGuard` runs the authentication guard first, fetches app configuration if needed, and redirects to `/403` when the required policy is not granted. + +```ts +export function createPermissionGuard(requiredPolicy: string) { + return async (context: GuardContext) => { + await authGuard(context) + + if (!appConfig.getSnapshot()?.initialized) { + const user = await userManager.getUser() + await fetchAppConfig(user?.access_token ?? null) + } + + if (!isPolicyGranted(requiredPolicy)) throw redirect({ to: '/403' }) + } +} +``` + +## Sidebar Visibility + +The sidebar reads `routeConfig` and hides items that require missing permissions: + +```ts +export const routeConfig: RouteConfigItem[] = [ + { + path: '/identity/users', + nameKey: 'AbpIdentity::Users', + requiredPolicy: 'AbpIdentity.Users', + }, +] +``` + +The sidebar checks each item: + +```ts +if (item.requiresAuth && !isAuthenticated) return false +if (!item.requiredPolicy) return true +if (!isAuthenticated) return false +return isGranted(item.requiredPolicy) +``` + +Use `requiresAuth` for menu items that only require login. Use `requiredPolicy` when the item should only be visible to users with a specific permission. + +## Compound Policies + +The template's `isPolicyGranted` helper supports simple compound expressions: + +- `PermissionA || PermissionB` +- `PermissionA && PermissionB` + +This is useful for menu entries that should be visible when the user has one of several related module permissions. + +## Where Permissions Are Applied + +The generated React app uses permissions in these places: + +- **Users page**: the `/identity/users` route and sidebar entry require `AbpIdentity.Users`. The page links to the Admin Console for full user and role management. +- **Books page**: the route requires `MyProjectName.Books`; edit and delete actions check `MyProjectName.Books.Edit` and `MyProjectName.Books.Delete`. +- **Admin Console link**: the sidebar entry uses `requiresAuth` because the Admin Console performs its own module and route permission checks. + +The Admin Console applies module-specific permissions for pages such as: + +- Identity users and roles: `AbpIdentity.*`. +- OpenIddict applications and scopes: `OpenIddictPro.Application` and `OpenIddictPro.Scope`. +- Audit Logging UI: `AuditLogging.AuditLogs`. +- Text Template Management: `TextTemplateManagement.*`. +- AI Management: `AIManagement.*`. + +## Multi-Tenancy + +When a tenant is selected, the template stores the tenant ID in `sessionStorage` as `abp_tenant_id`. Permission and API requests send it with the `__tenant` header. This ensures the backend returns permissions and data for the selected tenant context. + +## See Also + +- [Authorization](./authorization.md) +- [HTTP Requests](./http-requests.md) +- [Authorization](../../../framework/fundamentals/authorization/index.md) From 4bf5ae6e4edf6b9fdbc843710f15a24c716df247 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 17:55:42 +0300 Subject: [PATCH 05/10] docs: add React admin and customization guides Co-authored-by: Cursor --- docs/en/framework/ui/react/admin-console.md | 133 +++++++++++ .../en/framework/ui/react/components/index.md | 184 ++++++++++++++++ docs/en/framework/ui/react/customization.md | 208 ++++++++++++++++++ 3 files changed, 525 insertions(+) create mode 100644 docs/en/framework/ui/react/admin-console.md create mode 100644 docs/en/framework/ui/react/components/index.md create mode 100644 docs/en/framework/ui/react/customization.md diff --git a/docs/en/framework/ui/react/admin-console.md b/docs/en/framework/ui/react/admin-console.md new file mode 100644 index 0000000000..41e22a9fd5 --- /dev/null +++ b/docs/en/framework/ui/react/admin-console.md @@ -0,0 +1,133 @@ +```json +//[doc-seo] +{ + "Description": "Learn how the ABP Admin Console works with React UI applications and how it is hosted under /admin-console." +} +``` + +# Admin Console + +The **ABP Admin Console** is the React-based administration UI for ABP applications. It provides management pages for ABP modules and is available in React UI solutions created with ABP Studio v3.0+ or `abp new --modern --ui-framework react`. + +The Admin Console is delivered as the `Volo.Abp.AdminConsole` NuGet package for layered and single-layer solutions. In microservice solutions, the template also includes a standalone `apps/react-admin-console/` React app. + +## What It Provides + +The Admin Console contains administration pages for the ABP modules included in the host application. Module pages are activated based on the backend services available in the host, so a solution only shows pages for modules it actually has. + +The built-in module areas include: + +| Module | Notes | +| --- | --- | +| Identity Pro | User, role, claim, and organization unit management when Identity services are available. | +| Account Pro | Account management pages and account-related flows. | +| OpenIddict | Application and scope management when OpenIddict services are available. | +| Audit Logging UI | Optional. Visible when Audit Logging services are available. | +| AI Management | Optional. Visible when AI Management services are available. | +| Text Template Management | Optional. Visible when Text Template Management services are available. | + +Other module pages, such as Setting Management, SaaS, GDPR, or customization pages, can also be available depending on the solution and installed modules. + +## Hosting Model + +The Admin Console is served under: + +```text +/admin-console/* +``` + +API endpoints used by the Admin Console are served under: + +```text +/admin-console/api/* +``` + +The `Volo.Abp.AdminConsole` package embeds the built React SPA under `wwwroot/admin-console/` and registers it with ABP's Virtual File System. `AdminConsoleSpaMiddleware` then serves static assets and falls back to `index.html` for client-side routes. + +The middleware deliberately lets `/admin-console/api/*` requests pass through to MVC controllers. + +## Layered and Single-Layer Templates + +For layered and single-layer modern templates: + +- The developer-owned React app is in the `react/` folder. +- The Admin Console UI is embedded in the backend through the `Volo.Abp.AdminConsole` NuGet package. +- There is no separate `react-admin-console/` source folder in the generated solution. +- The backend host serves Admin Console pages under `/admin-console/*`. + +Example URL: + +```text +https://localhost:44300/admin-console/ +``` + +The main React app links to the Admin Console through `getAdminConsoleUrl()`. + +## Microservice Template + +For the microservice modern template: + +- The main React app is in `apps/react/`. +- The Admin Console app is in `apps/react-admin-console/`. +- Both are served through the Web Gateway. +- The Admin Console has its own OpenIddict client, normally `_AdminConsole`. + +The main React app uses `adminConsoleUrl` from `dynamic-env.json` to open the Admin Console origin and `/admin-console` base path. + +## Module Discovery + +The Admin Console calls: + +```text +GET /admin-console/api/modules +``` + +The backend checks for module application service contracts and returns which module areas are available. The discovery keys include: + +| Key | Backend service check | +| --- | --- | +| `identity` | `Volo.Abp.Identity.IIdentityUserAppService` | +| `saas` | `Volo.Saas.Host.ITenantAppService` | +| `auditLogging` | `Volo.Abp.AuditLogging.IAuditLogsAppService` | +| `gdpr` | `Volo.Abp.Gdpr.IGdprRequestAppService` | +| `openIddict` | `Volo.Abp.OpenIddict.Applications.IApplicationAppService` | +| `textTemplateManagement` | `Volo.Abp.TextTemplateManagement.TextTemplates.ITemplateDefinitionAppService` | +| `aiManagement` | AI Management service contracts, with a legacy AI engine fallback. | + +`settingManagement` is always returned as available by the discovery endpoint, while access to pages is still controlled by permissions. + +## Configuration Endpoint + +The Admin Console also uses: + +```text +GET /admin-console/api/config +``` + +This endpoint provides Admin Console runtime settings such as authority, client ID, scopes, application name, customization options, and localization language configuration. + +Host applications can configure Admin Console options from the `AdminConsole` configuration section. + +## Permissions + +Admin Console routes still require permissions. For example: + +- Identity pages use `AbpIdentity.*` permissions. +- OpenIddict pages use `OpenIddictPro.Application` and `OpenIddictPro.Scope`. +- Audit Logging uses `AuditLogging.AuditLogs`. +- Text Template Management uses `TextTemplateManagement.*`. +- AI Management uses `AIManagement.*`. + +The main React app's Admin Console menu item only requires authentication. The Admin Console performs detailed permission checks for its own pages. + +## Customization + +The developer-owned React app is intended for application-specific pages. The Admin Console is an ABP-managed administration surface and should normally be updated by updating ABP packages. + +For layered and single-layer hosts, the package supports host-side options such as application name, localization languages, and theme override CSS path. For larger UI changes, prefer building your own pages in the main React app or extending the backend modules through supported ABP extension points. + +## See Also + +- [React UI](./index.md) +- [Environment Variables](./environment-variables.md) +- [Permission Management](./permission-management.md) diff --git a/docs/en/framework/ui/react/components/index.md b/docs/en/framework/ui/react/components/index.md new file mode 100644 index 0000000000..856759acd5 --- /dev/null +++ b/docs/en/framework/ui/react/components/index.md @@ -0,0 +1,184 @@ +```json +//[doc-seo] +{ + "Description": "Learn about the component architecture and UI libraries used by ABP React UI applications." +} +``` + +# Components + +ABP React UI templates use a source-owned component architecture. The generated app includes shadcn/ui-style primitives, layout components, feature components, route pages, and shared infrastructure under `src/lib/`. + +The goal is to give you a working React application that you can customize without replacing framework-owned black boxes. + +## Component Structure + +The main React app is organized like this: + +```text +src/ +├── components/ +│ ├── layout/ +│ ├── ui/ +│ └── identity/ +├── lib/ +│ ├── api/ +│ ├── auth/ +│ ├── i18n/ +│ ├── routing/ +│ └── theme/ +├── locales/ +├── pages/ +└── routes/ +``` + +The exact folders can vary by selected template options and modules. + +## UI Stack + +The React template uses: + +| Library | Purpose | +| --- | --- | +| React | UI rendering. | +| Vite | Build tool and development server. | +| TanStack Router | Client-side routing. | +| TanStack Query | Server state, queries, mutations, and cache invalidation. | +| shadcn/ui-style components | Source-owned UI primitives built on Radix UI and Tailwind CSS. | +| Radix UI | Accessible low-level UI primitives. | +| Tailwind CSS | Utility-first styling and design tokens. | +| React Hook Form | Form state management. | +| Zod | Form and DTO validation schemas. | +| Axios | HTTP client. | +| i18next / react-i18next | Localization. | +| Zustand | Lightweight client state when needed. | +| Sonner | Toast notifications. | +| Lucide React | Icons. | + +## `components/ui` + +`src/components/ui/` contains reusable UI primitives. These components are copied into your project and can be edited directly. + +Common components include: + +- `Button` +- `Input` +- `Label` +- `Table` +- `Dialog` +- `DropdownMenu` +- `Select` +- `Card` +- `Tabs` +- `Badge` +- `DatePicker` +- `ConfirmDialog` + +Use these primitives to build application pages and feature components. + +```tsx +import { Button } from '@/components/ui/button' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' + +export function ReportCard() { + return ( + + + Reports + + + + + + ) +} +``` + +## Layout Components + +Layout components are under `src/components/layout/`. + +Important components include: + +- `RootLayout`: root shell used by TanStack Router. +- `Header`: top bar, login button, theme toggle, and user menu. +- `Sidebar`: route-config-driven navigation menu. +- `UserMenu`: account-related dropdown menu. + +The sidebar reads `src/lib/routing/route-config.ts`, checks authentication and permissions, and renders internal or external links. + +## Feature Components + +Feature-specific components should live near the feature that owns them. For example, Identity-specific layout components live under `src/components/identity/`, while Books-specific UI is implemented in `src/pages/books/BooksPage.tsx` in the sample template. + +As a rule: + +- Put generic, reusable primitives in `components/ui`. +- Put application layout in `components/layout`. +- Put feature-specific components under `components/` or next to the page when they are only used by one page. + +## Pages + +Route pages live under `src/pages/`. A page usually combines: + +- UI primitives from `components/ui`. +- API functions from `src/lib/api`. +- Server state from TanStack Query. +- Form state from React Hook Form. +- Validation schemas from Zod. +- Permissions from `usePermissions()`. +- Localized strings from `useTranslation()`. + +The Books page is the best full CRUD reference when the sample CRUD option is selected. + +## Forms + +Forms use React Hook Form and Zod: + +```tsx +const productSchema = z.object({ + name: z.string().min(1, 'Required'), + price: z.number().min(0), +}) + +type ProductFormData = z.infer + +const form = useForm({ + resolver: zodResolver(productSchema), + defaultValues: { + name: '', + price: 0, + }, +}) +``` + +This keeps runtime validation and TypeScript types close to each other. + +## Routing Components + +Routes are configured in `src/routes/router.tsx` with TanStack Router. Use: + +- `authGuard` for authenticated pages. +- `createPermissionGuard('Permission.Name')` for permission-protected pages. +- `RootLayout` and nested layouts for shared page structure. + +Menu entries are configured separately in `src/lib/routing/route-config.ts`, so route registration and navigation display can evolve independently. + +## API Components and Hooks + +API functions live under `src/lib/api/` and use the shared `api` Axios instance. Components normally consume these functions through TanStack Query: + +```tsx +const usersQuery = useQuery({ + queryKey: ['app', 'users', queryParams], + queryFn: () => getAppUsers(queryParams), +}) +``` + +This keeps HTTP details out of rendering components and gives you caching, loading states, refetching, and mutation invalidation. + +## See Also + +- [Customization](../customization.md) +- [HTTP Requests](../http-requests.md) +- [Unit Testing](../unit-testing.md) diff --git a/docs/en/framework/ui/react/customization.md b/docs/en/framework/ui/react/customization.md new file mode 100644 index 0000000000..3e64018dab --- /dev/null +++ b/docs/en/framework/ui/react/customization.md @@ -0,0 +1,208 @@ +```json +//[doc-seo] +{ + "Description": "Learn how to customize ABP React UI applications, including pages, themes, sidebar navigation, and the user menu." +} +``` + +# Customization + +The React app generated by ABP is fully owned by your solution. All source code is available, so you can change pages, components, routes, themes, menus, API calls, and layout behavior just like in any other React application. + +This page focuses on the main developer-owned React app. The same general approach applies to the public-web React app if your solution includes one. The Admin Console is an ABP-managed administration surface; see [Admin Console](./admin-console.md) for details. + +## General Customization + +Application pages live under `src/pages/`. The template includes practical references: + +- **Users page**: a simple page that lists users and links to the Admin Console for full user and role management. +- **Books page**: a full CRUD sample when the sample CRUD option is selected during solution creation. It demonstrates TanStack Query, forms, Zod validation, dialogs, tables, permissions, and toast notifications. + +Shared UI and infrastructure live under: + +```text +src/ +├── components/ +│ ├── layout/ +│ └── ui/ +├── lib/ +│ ├── api/ +│ ├── auth/ +│ ├── i18n/ +│ ├── routing/ +│ └── theme/ +└── pages/ +``` + +## Adding a Page + +Create a page under `src/pages/`: + +```tsx +export function ReportsPage() { + return ( +
+

Reports

+
+ ) +} +``` + +Register it with TanStack Router in `src/routes/router.tsx`: + +```tsx +const reportsRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/reports', + component: ReportsPage, + beforeLoad: createPermissionGuard('MyProjectName.Reports'), +}) + +const routeTree = rootRoute.addChildren([ + indexRoute, + reportsRoute, +]) +``` + +Use `authGuard` for pages that only require authentication and `createPermissionGuard` for pages that require a permission. + +## Theming + +The React template uses **shadcn/ui**-style components, Radix UI primitives, Tailwind CSS, and CSS variables. + +Theme tokens are defined in `src/styles/globals.css`: + +```css +:root { + --background: oklch(0.978 0.003 264); + --foreground: oklch(0.205 0.008 264); + --primary: oklch(0.48 0.10 278); + --radius: 0.5rem; +} + +.dark { + --background: oklch(0.16 0.004 264); + --foreground: oklch(0.92 0.005 264); + --primary: oklch(0.62 0.12 278); +} +``` + +ABP Studio's modern wizard can generate different shadcn theme color presets and light/dark/system theme behavior. + +## Changing Theme Colors + +To make a quick theme change, edit the CSS variables in `src/styles/globals.css`: + +```css +:root { + --primary: oklch(0.623 0.188 259.6); + --primary-foreground: oklch(1 0 0); +} +``` + +Because the generated shadcn/ui components consume these variables through Tailwind tokens, the change applies across buttons, links, active sidebar entries, focus rings, and other components that use the primary color. + +## Theme Mode Switcher + +Theme mode is handled by `src/lib/theme/ThemeProvider.tsx`. It supports: + +- `light` +- `dark` +- `system` + +The header cycles through the allowed modes: + +```tsx +const THEME_CYCLE: Theme[] = ['light', 'dark', 'system'] + +function ThemeToggle() { + const { theme, resolvedTheme, setTheme } = useTheme() + + function cycleTheme() { + const currentIndex = THEME_CYCLE.indexOf(theme) + const nextIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % THEME_CYCLE.length + setTheme(THEME_CYCLE[nextIndex]) + } + + return +} +``` + +To remove the switcher or replace it with a dropdown, edit `src/components/layout/Header.tsx`. + +## Modifying the Sidebar Menu + +Sidebar navigation is defined in `src/lib/routing/route-config.ts`. + +Add a menu item: + +```ts +import { BarChart3 } from 'lucide-react' + +export const routeConfig: RouteConfigItem[] = [ + { + path: '/reports', + nameKey: 'Menu:Reports', + icon: BarChart3, + order: 10, + requiredPolicy: 'MyProjectName.Reports', + }, +] +``` + +Then add the localization key to `src/locales/en.json`: + +```json +{ + "Menu:Reports": "Reports" +} +``` + +Use these properties depending on the menu item: + +| Property | Use | +| --- | --- | +| `path` | Internal route path or logical path for an external item. | +| `nameKey` | Localization key shown in the sidebar. | +| `icon` | Optional Lucide icon. | +| `order` | Sorting order. | +| `requiredPolicy` | Hide the item unless the permission is granted. | +| `requiresAuth` | Hide the item unless the user is authenticated. | +| `externalHref` | Open an external URL or another app, such as the Admin Console. | +| `children` | Add nested sidebar items. | + +## Sidebar vs User Menu + +Use the **sidebar navigation** for application pages and module entry points. + +Use the **user menu** for account-specific actions, profile links, sessions, security logs, linked accounts, and logout. The user menu is implemented in `src/components/layout/UserMenu.tsx`. + +Example user menu item: + +```tsx + + + + {t('MyAccount::Preferences')} + + +``` + +## Customizing UI Components + +shadcn/ui components are copied into your project under `src/components/ui/`. They are not black-box components from a package. You can edit them directly. + +For example: + +- Change button variants in `src/components/ui/button.tsx`. +- Change dialog structure in `src/components/ui/dialog.tsx`. +- Add a new reusable component under `src/components/ui/`. +- Add feature-specific components under `src/components//`. + +Keep generic primitives in `components/ui` and business-specific components close to the feature or page that owns them. + +## See Also + +- [Components](./components/index.md) +- [Permission Management](./permission-management.md) +- [Admin Console](./admin-console.md) From 9f043e0e26afd6b7f18cabb88fb484feee1ee165 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 17:56:44 +0300 Subject: [PATCH 06/10] docs: update React UI overview navigation Co-authored-by: Cursor --- docs/en/docs-nav.json | 52 ++++ docs/en/framework/ui/react/index.md | 451 +++++----------------------- 2 files changed, 129 insertions(+), 374 deletions(-) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 8d2fcc6e10..56079eb813 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -1873,6 +1873,58 @@ "text": "Overview", "path": "framework/ui/react/index.md", "isIndex": true + }, + { + "text": "Configuration and Development", + "items": [ + { + "text": "Environment Variables", + "path": "framework/ui/react/environment-variables.md" + }, + { + "text": "Unit Testing", + "path": "framework/ui/react/unit-testing.md" + } + ] + }, + { + "text": "Core Features", + "items": [ + { + "text": "Authorization", + "path": "framework/ui/react/authorization.md" + }, + { + "text": "Localization", + "path": "framework/ui/react/localization.md" + }, + { + "text": "Permission Management", + "path": "framework/ui/react/permission-management.md" + }, + { + "text": "HTTP Requests", + "path": "framework/ui/react/http-requests.md" + } + ] + }, + { + "text": "Customization and Components", + "items": [ + { + "text": "Customization", + "path": "framework/ui/react/customization.md" + }, + { + "text": "Components", + "path": "framework/ui/react/components/index.md", + "isIndex": true + } + ] + }, + { + "text": "Admin Console", + "path": "framework/ui/react/admin-console.md" } ] }, diff --git a/docs/en/framework/ui/react/index.md b/docs/en/framework/ui/react/index.md index e5fd471543..4483e7c84f 100644 --- a/docs/en/framework/ui/react/index.md +++ b/docs/en/framework/ui/react/index.md @@ -1,439 +1,142 @@ ```json //[doc-seo] { - "Description": "Learn how to build modern web applications with ABP using React UI — a React-first approach with a dedicated Admin Console, built on Vite, shadcn/ui, Zod, and Axios." + "Description": "Learn how to build modern web applications with ABP React UI, including runtime configuration, authentication, Admin Console, shadcn/ui components, and testing." } ``` # React UI -## Introduction +ABP provides a **React UI** option for building modern, client-side web applications. React UI is part of the **modern template system** and is available with **ABP Studio v3.0+** through the Modern Wizard or with `abp new --modern` using [ABP CLI](../../../cli/index.md). -ABP provides a **React UI** option for building modern, client-side web applications. The React UI is part of the **modern template system** and is available when you create a solution through the **Modern Wizard** in [ABP Studio](../../../studio/index.md) or with `abp new --modern` using [ABP CLI](../../../cli/index.md). +React UI is not available in classic, non-modern templates. Use ABP Studio's modern template flow or `Volo.Abp.Studio.Cli` to create a React-based solution. -> React UI is **not** available in the classic (non-modern) templates. Use `Volo.Abp.Studio.Cli` or ABP Studio's modern template flow to create a React-based solution. The classic CLI path (`--old`) does not create modern React solutions. +## Technology Stack -The React UI is built on a modern, industry-standard stack: +The React UI template is built with: | Technology | Purpose | -|---|---| -| [Vite](https://vitejs.dev/) | Build tool and dev server | +| --- | --- | +| [Vite](https://vite.dev/) | Build tool and dev server | | [React](https://react.dev/) | UI framework | -| [shadcn/ui](https://ui.shadcn.com/) | Component library (built on Radix UI + Tailwind CSS) | +| [TanStack Router](https://tanstack.com/router) | Client-side routing | +| [TanStack Query](https://tanstack.com/query) | Server state and API request orchestration | +| [shadcn/ui](https://ui.shadcn.com/) | Source-owned component library built on Radix UI and Tailwind CSS | | [Zod](https://zod.dev/) | Schema validation | +| [React Hook Form](https://react-hook-form.com/) | Form state management | | [Axios](https://axios-http.com/) | HTTP client | | [Vitest](https://vitest.dev/) | Unit testing | -| [React Router](https://reactrouter.com/) | Client-side routing | -| [OpenID Connect / OIDC](https://openid.net/connect/) | Authentication (via the ABP Auth Server) | +| [OpenID Connect / OIDC](https://openid.net/connect/) | Authentication against the ABP Auth Server | -## React App and Admin Console - -When you create a modern solution with React UI, it contains two UI surfaces: **your React application** and the **ABP Admin Console**. - -### React App (Your Application) - -This is **your application** — the user-facing SPA that you own and customize freely. It comes with: - -- A sample **Books CRUD page** when the template is generated with sample CRUD support, demonstrating how to build a full create/read/update/delete page with the ABP backend -- A plain **Users page** as a minimal reference -- Pre-configured authentication via OIDC against the ABP Auth Server -- Pre-configured HTTP client (Axios) with ABP API integration - -This is where you build your business-specific pages and features. - -The location of the React app differs by template type: - -- **Layered (`app --modern`) and Single-layer (`app-nolayers --modern`)**: the React app lives in the `react/` folder at the solution root. -- **Microservice (`microservice --modern`)**: the React app lives at `apps/react/`. - -### React Admin Console (`Volo.Abp.AdminConsole`) - -The **ABP Admin Console** is a pre-built React application that provides all standard ABP module management pages. It is delivered via the `Volo.Abp.AdminConsole` NuGet package and requires no modification on your part — it is updated automatically when you update your ABP packages. - -The Admin Console includes pages for: - -- Users & Roles management -- Organization Units -- Settings -- Audit Logs -- OpenIddict (Application, Scope management) -- Language Management *(if included)* -- Text Template Management *(if included)* -- GDPR *(if included)* -- SaaS / Tenant Management *(if included)* -- And all other optional module pages based on your solution configuration - -How the Admin Console is hosted also differs by template type: - -- **Layered and Single-layer templates**: The `Volo.Abp.AdminConsole` package is added directly to your `*.HttpApi.Host` project. It serves the Admin Console React app at the `/admin-console/*` path of your backend (e.g., `https://localhost:44300/admin-console/`). There is no separate `apps/react-admin-console/` folder — the Admin Console UI is embedded in and served by the backend. -- **Microservice template**: The Admin Console runs as a standalone React app at `apps/react-admin-console/`, served through the Web Gateway (YARP) alongside the main React app. +The template also includes ABP-specific NPM packages: -In both cases the Admin Console is accessible from the main React app via a navigation link. +- [`@volo/abp-app-config`](https://github.com/volosoft/volo/tree/dev/abp/npm/packs/abp-app-config) +- [`@volo/abp-oidc-auth`](https://github.com/volosoft/volo/tree/dev/abp/npm/packs/abp-oidc-auth) +- [`@volo/abp-react-app-config`](https://github.com/volosoft/volo/tree/dev/abp/npm/packs/abp-react-app-config) +- [`@volo/abp-react-oidc-auth`](https://github.com/volosoft/volo/tree/dev/abp/npm/packs/abp-react-oidc-auth) -## Creating a Solution - -### Using ABP CLI - -Install or update `Volo.Abp.Studio.Cli`, then pass the `--modern` flag to `abp new`: - -````bash -# Layered app with React UI (default when --modern is used) -abp new Acme.BookStore --template app --modern - -# Single-layer app with React UI -abp new Acme.BookStore --template app-nolayers --modern - -# Microservice solution with React UI + React Admin Console -abp new Acme.BookStore --template microservice --modern -```` - -The `react` UI framework is the default when `--modern` is specified. You can also pass it explicitly: - -````bash -abp new Acme.BookStore --template app --modern --ui-framework react -```` - -To create a solution without any UI (API-only backend): +## React App and Admin Console -````bash -abp new Acme.BookStore --template app --modern --ui-framework no-ui -```` +A modern React solution contains two UI surfaces: -See the [ABP CLI documentation](../../../cli/index.md#modern-templates) for the full list of modern templates, supported UI/mobile combinations, and modern-only options like `--shadcn-theme`, `--admin-password`, `--modular`, and `--services`. +- **Your React application**: the developer-owned SPA where you build application-specific pages and features. +- **ABP Admin Console**: the React-based administration UI for ABP modules. -### Using ABP Studio +The Admin Console is provided by the `Volo.Abp.AdminConsole` NuGet package in layered and single-layer templates. In microservice templates, it is also generated as a separate `apps/react-admin-console/` app and served through the Web Gateway. -Open ABP Studio and use the **New Solution** wizard. Choose the modern template flow, select the solution type you want to create, and use **React** as the UI framework. The wizard shows the options supported by the selected modern template and generates the solution with the same modern template system used by `abp new --modern`. +See [Admin Console](./admin-console.md) for hosting, module discovery, and permission details. ## Solution Structure -The layout of the React-related files depends on the template type. +The React app location depends on the modern template type: -### Layered and Single-layer Templates +- **Layered (`app --modern`) and single-layer (`app-nolayers --modern`)**: the React app lives in the `react/` folder at the solution root. +- **Microservice (`microservice --modern`)**: the React app lives at `apps/react/`. -For `app --modern` and `app-nolayers --modern`, the React app lives in the `react/` folder at the solution root. The Admin Console is embedded in the backend via the `Volo.Abp.AdminConsole` NuGet package; there is no separate React Admin Console folder. +Typical structure: -``` -Acme.BookStore/ -├── react/ # Your React application -│ ├── src/ -│ │ ├── pages/ # Your page components -│ │ │ ├── books/ # Sample Books CRUD page -│ │ │ └── users/ # Sample Users page -│ │ ├── components/ # Shared UI components -│ │ ├── lib/ # Utilities, API clients -│ │ ├── hooks/ # Custom React hooks -│ │ └── main.tsx # Entry point -│ ├── public/ -│ │ └── dynamic-env.json # Runtime configuration -│ ├── package.json -│ └── vite.config.ts +```text +react/ +├── dynamic-env.json +├── public/ ├── src/ -│ ├── Acme.BookStore.Application/ -│ ├── Acme.BookStore.Domain/ -│ ├── Acme.BookStore.EntityFrameworkCore/ -│ └── Acme.BookStore.HttpApi.Host/ # Hosts Admin Console at /admin-console/* -└── ... -``` - -### Microservice Template - -For `microservice --modern`, both the React app and the React Admin Console are standalone apps under the `apps/` directory, each served through the Web Gateway (YARP). - -``` -Acme.BookStore/ -├── apps/ -│ ├── react/ # Your React application -│ │ ├── src/ -│ │ │ ├── pages/ -│ │ │ ├── components/ -│ │ │ ├── lib/ -│ │ │ ├── hooks/ -│ │ │ └── main.tsx -│ │ ├── public/ -│ │ │ └── dynamic-env.json # Runtime configuration -│ │ ├── package.json -│ │ └── vite.config.ts -│ ├── react-admin-console/ # ABP Admin Console (managed by ABP) -│ │ ├── public/ -│ │ │ └── dynamic-env.json -│ │ └── ... -│ └── auth-server/ # OpenIddict Auth Server -├── gateways/ -│ └── web/ # YARP reverse proxy for React apps -├── services/ -│ ├── identity/ -│ ├── administration/ -│ └── ... -└── ... -``` - -## Configuration - -### Runtime Configuration (`dynamic-env.json`) - -The React app reads its runtime configuration from `public/dynamic-env.json`. This file is loaded at startup and allows you to change settings without rebuilding the application, which is useful for different environments like development, staging, and production. - -```json -{ - "oAuthConfig": { - "issuer": "https://localhost:44301/", - "clientId": "Acme.BookStore_App", - "scope": "openid profile email offline_access BookStore" - }, - "apis": { - "default": { - "url": "https://localhost:44300", - "rootNamespace": "Acme.BookStore" - } - } -} -``` - -| Key | Description | -|---|---| -| `oAuthConfig.issuer` | URL of the OpenIddict Auth Server | -| `oAuthConfig.clientId` | The OpenIddict client ID registered for this app | -| `oAuthConfig.scope` | OAuth scopes to request | -| `apis.default.url` | Base URL of the backend API | -| `apis.default.rootNamespace` | Root namespace used for API proxy generation | - -For the **microservice** modern template, the `apis.default.url` points to the **Web Gateway** (YARP reverse proxy) instead of a single backend host. - -### Admin Console Configuration - -For the **microservice** template, the Admin Console has its own `dynamic-env.json` (at `apps/react-admin-console/public/dynamic-env.json`) and uses a separate OpenIddict client (`_AdminConsole`). - -For **layered and single-layer** templates, the Admin Console is embedded in the backend via the `Volo.Abp.AdminConsole` package and does not have a separate configuration file — it inherits its settings from the backend host. - -## Authentication - -Both the React app and the Admin Console authenticate using **OpenID Connect (OIDC)** against the ABP Auth Server (OpenIddict). The auth flow is handled transparently — when a user visits a protected page, they are redirected to the Auth Server login page and returned to the app after successful authentication. All clients use the **Authorization Code flow with PKCE**, which is the recommended flow for SPAs. - -The number of seeded OpenIddict clients depends on the template: - -- **Layered and Single-layer templates**: one client is seeded — `_App` for the React SPA. The Admin Console is embedded in the backend and shares the same authentication context. -- **Microservice template**: two clients are seeded — `_App` for the main React SPA and `_AdminConsole` for the standalone React Admin Console app. - -## Making API Calls - -The React app uses **Axios** as the HTTP client, pre-configured with: - -- The base URL from `dynamic-env.json` -- Automatic Bearer token injection from the OIDC session -- ABP-compatible error handling (reads `error.data` from ABP error responses) - -**Example: Fetching a list of books** - -```typescript -import { useQuery } from '@tanstack/react-query'; -import { apiClient } from '@/lib/api-client'; - -interface BookDto { - id: string; - name: string; - type: number; - publishDate: string; - price: number; -} - -interface PagedResult { - items: T[]; - totalCount: number; -} - -export function useBooks() { - return useQuery({ - queryKey: ['books'], - queryFn: () => - apiClient - .get>('/api/app/book') - .then((res) => res.data), - }); -} -``` - -## Localization - -The React app integrates with ABP's [localization system](../../../framework/fundamentals/localization.md). Localization resources are fetched from the backend at startup via the `/api/abp/application-configuration` endpoint and made available throughout the app. - -**Example: Using localization in a component** - -```typescript -import { useLocalization } from '@/hooks/use-localization'; - -export function MyComponent() { - const { l } = useLocalization('BookStore'); - - return

{l('Books')}

; -} -``` - -The `l(key)` function looks up the key in the loaded localization resources for the given resource name (`'BookStore'` in this example). - -## Authorization - -Permission checks are available via a hook that reads the current user's granted permissions from the ABP application configuration: - -```typescript -import { usePermissions } from '@/hooks/use-permissions'; - -export function BooksPage() { - const { isGranted } = usePermissions(); - - return ( -
- {isGranted('BookStore.Books.Create') && ( - - )} -
- ); -} +│ ├── components/ +│ ├── lib/ +│ ├── locales/ +│ ├── pages/ +│ ├── routes/ +│ └── main.tsx +├── package.json +├── vite.config.ts +└── vitest.config.ts ``` -Permissions are defined on the server side using ABP's [permission system](../../../framework/fundamentals/authorization/index.md) and are automatically available in the React app. - -## Tech Stack Details - -### shadcn/ui Components - -The React app uses [shadcn/ui](https://ui.shadcn.com/) as the component library. shadcn/ui is not a traditional npm package — components are copied directly into your project under `src/components/ui/`, giving you full ownership and the ability to customize them freely. - -Common components available out of the box include: `Button`, `Input`, `Table`, `Dialog`, `Form`, `Select`, `Tabs`, `Card`, `Badge`, `Dropdown Menu`, and more. - -### Form Validation with Zod - -Forms use [Zod](https://zod.dev/) schemas for validation, integrated with [React Hook Form](https://react-hook-form.com/): - -```typescript -import { z } from 'zod'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; +## Creating a Solution -const createBookSchema = z.object({ - name: z.string().min(1).max(128), - price: z.number().min(0), - publishDate: z.string(), -}); +Install or update `Volo.Abp.Studio.Cli`, then create a modern solution: -type CreateBookInput = z.infer; +```bash +# Layered app with React UI +abp new Acme.BookStore --template app --modern --ui-framework react -export function CreateBookForm() { - const form = useForm({ - resolver: zodResolver(createBookSchema), - }); +# Single-layer app with React UI +abp new Acme.BookStore --template app-nolayers --modern --ui-framework react - // ... -} +# Microservice solution with React UI +abp new Acme.BookStore --template microservice --modern --ui-framework react ``` -### Testing with Vitest - -The React app is pre-configured with [Vitest](https://vitest.dev/) for unit testing: - -```bash -# Run tests -npm run test - -# Run tests with coverage -npm run test:coverage -``` +You can also use ABP Studio v3.0+ and select the modern template flow in the New Solution wizard. The wizard preconfigures local ports, runtime configuration, OIDC clients, theme options, and React/Admin Console wiring based on the selected template and modules. ## Running the Application -### Development - -1. Start the backend (from ABP Studio or `dotnet run` in the `*.HttpApi.Host` project). -2. Navigate to the React app directory and start the dev server. +Start the backend from ABP Studio or by running the backend host projects, then start the React development server. -For **layered and single-layer** templates, the React app is in the `react/` folder at the solution root: +For layered and single-layer templates: -````bash +```bash cd react npm install npm run dev -```` +``` -For the **microservice** template, the React app is under `apps/`: +For microservice templates: -````bash +```bash cd apps/react npm install npm run dev -```` - -The app will be available at `https://localhost:3000` (or the port configured in `vite.config.ts`). - -3. Access the Admin Console: - - **Layered / Single-layer**: navigate to the backend URL + `/admin-console/` (e.g., `https://localhost:44300/admin-console/`). - - **Microservice**: navigate to the Web Gateway URL + `/admin-console/`. - -### Production Build - -````bash -# Layered / Single-layer -cd react && npm run build - -# Microservice -cd apps/react && npm run build -```` - -The output is placed in `dist/` and can be served by any static file host or CDN. - -## Accessing the Admin Console - -The Admin Console is accessible from within the main React app. After logging in, you will find a link to the Admin Console in the navigation. In layered and single-layer solutions it is served by the backend at `/admin-console/*`; in microservice solutions it is served as a standalone React app through the Web Gateway. - -The Admin Console provides full management capabilities for: - -- **Identity**: Users, Roles, Claims, Organization Units -- **OpenIddict**: Applications, Scopes -- **Settings**: Application-wide and tenant-level settings -- **Audit Logs**: View and filter audit log entries -- **Language Management** *(optional)* -- **Text Template Management** *(optional)* -- **GDPR** *(optional)* -- **SaaS / Tenant Management** *(optional)* -- **And more**, depending on the modules included in your solution - -## Customization - -### Adding New Pages - -Create a new file under `src/pages/` and register the route in the router configuration: +``` -```typescript -// src/router.tsx (or similar) -import { BooksPage } from './pages/books/books-page'; -import { MyNewPage } from './pages/my-feature/my-new-page'; +Run tests with: -const routes = [ - { path: '/books', element: }, - { path: '/my-feature', element: }, - // ... -]; +```bash +npm run test ``` -### Adding Menu Items +Build for production with: -Add entries to the navigation configuration to include your new pages in the sidebar or top navigation: - -```typescript -// src/config/navigation.ts (or similar) -export const navigationItems = [ - { label: 'Books', path: '/books', icon: BookIcon }, - { label: 'My Feature', path: '/my-feature', icon: StarIcon }, -]; +```bash +npm run build ``` -### Customizing shadcn/ui Components +## Documentation Map + +Use these pages to learn each part of the React UI: -Since shadcn/ui components live in `src/components/ui/`, you can modify them directly. For example, to change the default button variant or add a new variant, edit `src/components/ui/button.tsx`. +- [Environment Variables](./environment-variables.md): runtime configuration, `dynamic-env.json`, Vite variables, and Studio-generated defaults. +- [Authorization](./authorization.md): OIDC, Authorization Code flow with PKCE, auth provider, hooks, and route guards. +- [Localization](./localization.md): i18next, local JSON resources, ABP localization keys, and request culture. +- [Permission Management](./permission-management.md): fetching granted policies, `usePermissions()`, route protection, and conditional UI. +- [HTTP Requests](./http-requests.md): Axios setup, interceptors, typed API modules, and TanStack Query usage. +- [Customization](./customization.md): changing pages, themes, sidebar items, user menu entries, and shadcn/ui components. +- [Components](./components/index.md): component architecture, UI primitives, layout components, forms, and routing. +- [Unit Testing](./unit-testing.md): Vitest, React Testing Library, examples, and test workflow. +- [Admin Console](./admin-console.md): the `Volo.Abp.AdminConsole` package, `/admin-console/*` hosting, module discovery, and optional modules. ## See Also -- [ABP CLI — Modern Templates](../../../cli/index.md#modern-templates) - [ABP Studio](../../../studio/index.md) +- [ABP CLI](../../../cli/index.md) +- [Authorization](../../../framework/fundamentals/authorization/index.md) - [Localization](../../../framework/fundamentals/localization.md) -- [Authorization / Permissions](../../../framework/fundamentals/authorization/index.md) -- [Auto API Controllers](../../../framework/api-development/auto-controllers.md) From 84863a0e9eea332ddbec8b52caab5079dbd767ae Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 18:21:11 +0300 Subject: [PATCH 07/10] docs: document React admin console settings Co-authored-by: Cursor --- docs/en/framework/ui/react/admin-console.md | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/en/framework/ui/react/admin-console.md b/docs/en/framework/ui/react/admin-console.md index 41e22a9fd5..adbe4056c3 100644 --- a/docs/en/framework/ui/react/admin-console.md +++ b/docs/en/framework/ui/react/admin-console.md @@ -108,6 +108,44 @@ This endpoint provides Admin Console runtime settings such as authority, client Host applications can configure Admin Console options from the `AdminConsole` configuration section. +## `appsettings.json` Customization + +In layered and single-layer modern React templates, the embedded Admin Console is configured from the backend host application's `appsettings.json` file. The generated template includes an `AdminConsole` section similar to the following: + +```json +{ + "AdminConsole": { + "IsEnabled": true, + "RedirectRootToAdminConsole": true, + "Authority": "https://localhost:44300", + "ClientId": "Acme_BookStore_AdminConsole", + "Scope": "openid profile email offline_access Acme_BookStore", + "LocalizationLanguages": [ "en", "tr" ], + "ThemeOverrideCssPath": "/theme-override.css", + "InitialTheme": "system", + "CustomizationPermissionName": "AdminConsole.Customization" + } +} +``` + +The most commonly changed options are: + +| Option | Description | +| --- | --- | +| `IsEnabled` | Enables or disables the embedded Admin Console SPA middleware. | +| `RedirectRootToAdminConsole` | Redirects the backend root path (`/`) to `/admin-console`. | +| `Authority` | OpenID Connect authority URL. If it is `null`, the host origin is used. | +| `ClientId` | OpenIddict client ID used by the Admin Console SPA. | +| `Scope` | Space-separated OAuth scopes requested by the Admin Console. | +| `LocalizationLanguages` | UI language codes exposed to the Admin Console. If empty, the frontend falls back to `en`. | +| `ThemeOverrideCssPath` | Optional CSS path or absolute URL injected into the Admin Console HTML. | +| `InitialTheme` | Initial theme behavior: `light`, `dark`, `system`, or `both`. | +| `CustomizationPermissionName` | Permission required to show and use the Admin Console customization page. If not set, customization is disabled. | + +The `ApplicationName`, `LogoUrl`, `InitialTheme`, and `ThemeOverrideCssPath` values can also be changed from the Admin Console customization UI when `CustomizationPermissionName` is configured and the current user has that permission. Values saved from the customization UI are stored as settings and override the defaults from configuration. + +In microservice solutions, the Admin Console is a separate React app under `apps/react-admin-console/`. It still uses its own OpenIddict client (`_AdminConsole`) and runtime configuration, while the backend exposes the same `/admin-console/api/config` and `/admin-console/api/modules` endpoints. + ## Permissions Admin Console routes still require permissions. For example: From 5f2aca20ce070d441a435c4256898b568d30cb7c Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 18:24:26 +0300 Subject: [PATCH 08/10] docs: add React to UI framework docs Co-authored-by: Cursor --- docs/en/get-started/layered-web-application.md | 15 ++++++++++++--- docs/en/get-started/microservice.md | 4 +++- .../get-started/single-layer-web-application.md | 12 +++++++++--- docs/en/modules/identity.md | 2 +- .../layered-web-application/overview.md | 1 + .../layered-web-application/web-applications.md | 13 +++++++++++++ .../solution-templates/microservice/overview.md | 3 ++- .../microservice/web-applications.md | 5 +++++ .../single-layer-web-application/overview.md | 1 + .../web-applications.md | 13 +++++++++++++ 10 files changed, 60 insertions(+), 9 deletions(-) diff --git a/docs/en/get-started/layered-web-application.md b/docs/en/get-started/layered-web-application.md index f4a383ff0b..cfbe1ebc40 100644 --- a/docs/en/get-started/layered-web-application.md +++ b/docs/en/get-started/layered-web-application.md @@ -10,7 +10,7 @@ ````json //[doc-params] { - "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG"], + "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG", "React"], "DB": ["EF", "Mongo"], "Tiered": ["Yes", "No"] } @@ -62,6 +62,8 @@ Once your configuration is done, click the *Next* button to navigate to the *UI ![abp-studio-new-solution-dialog-ui-framework-blazor-webapp](images/abp-studio-new-solution-dialog-ui-framework-blazor-webapp_dark.png) {{ else if UI == "NG" }} ![abp-studio-new-solution-dialog-ui-framework-ng](images/abp-studio-new-solution-dialog-ui-framework-ng_dark.png) +{{ else if UI == "React" }} +React UI is available in the modern template flow with ABP Studio v3.0+. Select **React** in the UI Framework list to create the React app and Admin Console integration. {{ end }} Here, you see all the possible UI options supported by that startup solution template. Pick the **{{ UI_Value }}**. @@ -192,6 +194,9 @@ You can start the following application(s): {{ if UI == "NG" }} {{ if Tiered == "No" }}- `Acme.BookStore.HttpApi.Host`{{ end }} - `Acme.BookStore.Angular` +{{ else if UI == "React" }} +{{ if Tiered == "No" }}- `Acme.BookStore.HttpApi.Host`{{ end }} +- `react` {{ else if UI == "Blazor" }} {{ if Tiered == "No" }}- `Acme.BookStore.HttpApi.Host`{{ end }} - `Acme.BookStore.Blazor` @@ -207,7 +212,7 @@ You can start the following application(s): > Notice that the services running in docker-compose are exposed to your localhost. If any service in your localhost is already using the same port(s), you will get an error. In that case, stop your local services first. {{ end }} -Once the `Acme.BookStore.{{ if UI == "NG" }}Angular{{ else if UI == "BlazorServer" || UI == "Blazor" || UI == "BlazorWebApp" }}Blazor{{ else }}Web{{ end }}` application started, you can right-click it and select the *Browse* command: +Once the {{ if UI == "React" }}`react`{{ else }}`Acme.BookStore.{{ if UI == "NG" }}Angular{{ else if UI == "BlazorServer" || UI == "Blazor" || UI == "BlazorWebApp" }}Blazor{{ else }}Web{{ end }}`{{ end }} application started, you can right-click it and select the *Browse* command: ![abp-studio-quick-start-browse-command](images/abp-studio-quick-start-browse-command_dark.png) @@ -239,7 +244,11 @@ Once the solution is opened in Visual Studio, you should see a screen like shown ![visual-studio-bookstore-application](images/visual-studio-bookstore-application_dark.png) +{{ if UI == "React" }} +Right-click the `Acme.BookStore.HttpApi.Host` project and select the *Set as Startup Project* command. You can then hit *F5* or *Ctrl + F5* to run the backend host application. Start the React application from the `react` folder with `npm run dev`, then browse the React UI. +{{ else }} Right-click the `Acme.BookStore.{{ if UI == "NG" || UI == "Blazor" }}HttpApi.Host{{ else if UI == "BlazorServer" || UI == "BlazorWebApp" }}Blazor{{ else }}Web{{ end }}` project and select the *Set as Startup Project* command. You can then hit *F5* or *Ctrl + F5* to run the web application. It will run and open the application UI in your default browser: +{{ end }} ![bookstore-browser-users-page](images/bookstore-browser-users-page_dark.png) @@ -257,7 +266,7 @@ You can start the following application(s): - `Docker-Dependencies` - `Acme.BookStore.AuthServer` - `Acme.BookStore.HttpApi.Host` -{{ else if UI == "NG" || UI == "Blazor" }} +{{ else if UI == "NG" || UI == "Blazor" || UI == "React" }} - `Acme.BookStore.HttpApi.Host` {{ else if UI == "BlazorServer" }} - `Acme.BookStore.Blazor` diff --git a/docs/en/get-started/microservice.md b/docs/en/get-started/microservice.md index d30e3926fc..5fb5aa927c 100644 --- a/docs/en/get-started/microservice.md +++ b/docs/en/get-started/microservice.md @@ -64,6 +64,8 @@ On that screen, you can enable multi-tenancy for your solution. After selecting Here, you see all the possible UI options supported by that startup solution template. You can pick your favorite one and click the *Next* button for the *Mobile Framework* selection screen: +If you select **React**, the solution includes the main React application and the React Admin Console surface. The Admin Console uses its own OpenIddict client and is served through the Web Gateway with the rest of the solution. + ![abp-studio-new-solution-dialog-mobile-framework](images/abp-studio-new-solution-dialog-mobile-framework-microservice.png) Here, you see all the mobile applications available in that startup solution template. These mobile applications are well-integrated into your solution and can use the same backend with your web application. They are simple (do not have pre-built features as much as the web application) but a very good starting point to build your mobile application. @@ -200,7 +202,7 @@ You can click the *Play* button on the root item in *Solution Runner* to start a > > Some applications/services may fail on the first run. That may be because of service and database dependencies were not satisfied and an error occurs on the application startup. ABP Studio automatically restarts failing services until it is successfully started. Being completely ready for such a distributed solution may take a while, but it will be eventually started. -Once all the applications are ready, you can right-click the `Web` application and select the *Browse* command: +Once all the applications are ready, you can right-click the main web application and select the *Browse* command. For React UI solutions, this is the `react` application. ![abp-studio-microservice-solution-runner-browse](images/abp-studio-microservice-solution-runner-browse.png) diff --git a/docs/en/get-started/single-layer-web-application.md b/docs/en/get-started/single-layer-web-application.md index ef657722b0..7c25202f04 100644 --- a/docs/en/get-started/single-layer-web-application.md +++ b/docs/en/get-started/single-layer-web-application.md @@ -10,7 +10,7 @@ ````json //[doc-params] { - "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG"], + "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG", "React"], "DB": ["EF", "Mongo"] } ```` @@ -62,6 +62,8 @@ Once your configuration is done, click the *Next* button to navigate to the *UI ![abp-studio-new-solution-dialog-ui-framework-blazor-webapp](images/abp-studio-no-layers-new-solution-dialog-ui-framework-blazor-webapp_dark.png) {{ else if UI == "NG" }} ![abp-studio-new-solution-dialog-ui-framework-ng](images/abp-studio-no-layers-new-solution-dialog-ui-framework-ng_dark.png) +{{ else if UI == "React" }} +React UI is available in the modern template flow with ABP Studio v3.0+. Select **React** in the UI Framework list to create the React app and Admin Console integration. {{ end }} Here, you see all the possible UI options supported by that startup solution template. Pick the **{{ UI_Value }}**. @@ -146,9 +148,9 @@ In the Solution Runner section (on the left side) you can see all the runnable a To start an application, either click the *Play* icon near to the application or right-click and select the *Run* -> *Start* context menu item. -You can start the `Acme.BookStore`{{ if UI == "NG" }} and `Acme.BookStore.Angular`{{ end }}. +You can start the `Acme.BookStore`{{ if UI == "NG" }} and `Acme.BookStore.Angular`{{ else if UI == "React" }} and `react`{{ end }}. -Once the `Acme.BookStore{{ if UI == "NG" }}.Angular{{ end }}` application started, you can right-click it and select the *Browse* command: +Once the {{ if UI == "React" }}`react`{{ else }}`Acme.BookStore{{ if UI == "NG" }}.Angular{{ end }}`{{ end }} application started, you can right-click it and select the *Browse* command: ![abp-studio-quick-start-browse-command](images/abp-studio-no-layers-quick-start-browse-command_dark.png) @@ -180,7 +182,11 @@ Once the solution is opened in Visual Studio, you should see a screen like shown ![visual-studio-bookstore-application](images/no-layers-visual-studio-bookstore-application_dark.png) +{{ if UI == "React" }} +You can then hit *F5* or *Ctrl + F5* to run the backend host application. Start the React application from the `react` folder with `npm run dev`, then browse the React UI. +{{ else }} You can then hit *F5* or *Ctrl + F5* to run the web application. It will run and open the application UI in your default browser: +{{ end }} ![bookstore-browser-users-page](images/no-layers-bookstore-browser-users-page_dark.png) diff --git a/docs/en/modules/identity.md b/docs/en/modules/identity.md index d92f4b7b8e..b7f13a9c8b 100644 --- a/docs/en/modules/identity.md +++ b/docs/en/modules/identity.md @@ -19,7 +19,7 @@ The source code of this module can be accessed [here](https://github.com/abpfram ## User Interface -This module provides [Blazor](../framework/ui/blazor/overall.md), [Angular](../framework/ui/angular/quick-start.md) and [MVC / Razor Pages](../framework/ui/mvc-razor-pages/overall.md) UI options. +This module provides [Blazor](../framework/ui/blazor/overall.md), [Angular](../framework/ui/angular/quick-start.md), [React](../framework/ui/react/index.md) and [MVC / Razor Pages](../framework/ui/mvc-razor-pages/overall.md) UI options. ### Menu Items diff --git a/docs/en/solution-templates/layered-web-application/overview.md b/docs/en/solution-templates/layered-web-application/overview.md index 1a091649cc..a75698fd79 100644 --- a/docs/en/solution-templates/layered-web-application/overview.md +++ b/docs/en/solution-templates/layered-web-application/overview.md @@ -96,6 +96,7 @@ The solution comes with a main web application with the following UI Framework o * **Blazor WebAssembly** * **Blazor Server** * **Blazor WebApp** +* **[React UI](../../framework/ui/react/index.md)** * **MAUI with Blazor (Hybrid)** **\*** ### The Mobile Application diff --git a/docs/en/solution-templates/layered-web-application/web-applications.md b/docs/en/solution-templates/layered-web-application/web-applications.md index 8400a6dfbe..38d35772e1 100644 --- a/docs/en/solution-templates/layered-web-application/web-applications.md +++ b/docs/en/solution-templates/layered-web-application/web-applications.md @@ -27,6 +27,7 @@ The web applications are the main user interfaces of the solution. They are the - **MVC / Razor Pages**: This is an ASP.NET Core MVC application. It is a traditional web application that serves HTML pages to users and is suitable for building web applications with server-side rendering. - **Angular**: This is an Angular application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and is ideal for building modern web applications with rich user interfaces. +- **React UI**: This is a React application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and includes the React-based ABP Admin Console integration. - **Blazor UI**: A flexible framework for building web applications with .NET. It supports various hosting models: - **Blazor WebAssembly**: This is a client-side SPA that runs entirely in the user's browser. It communicates with the server using HTTP requests and is suitable for modern web applications with rich interactivity and offline capabilities. - **Blazor Server**: This is a server-side SPA that runs on the server and communicates with the client in real time using SignalR. It is ideal for applications requiring constant connectivity and rapid server updates. @@ -130,6 +131,18 @@ See the [testing document](https://angular.dev/guide/testing). * [Chart.js](https://www.chartjs.org/) is used to create widgets. * [ngx-validate](https://github.com/ng-turkey/ngx-validate) is used for dynamic validation of reactive forms. +## React UI + +React UI is a modern SPA option built with React, Vite, TanStack Router, TanStack Query, shadcn/ui-style components, Axios, and Vitest. + +When you select the React option in the Layered Solution Template, it generates: + +- A React application located under the solution's root folder, typically named `react`. +- An ASP.NET Core application, named `*.HttpApi.Host`, where the server-side HTTP APIs run. +- An embedded React Admin Console hosted by the backend through the `Volo.Abp.AdminConsole` package. + +The React application communicates with the server by sending HTTP requests to the `*.HttpApi.Host` application. See the [React UI documentation](../../framework/ui/react/index.md) for details. + ## Blazor UI Blazor is a flexible framework for building web applications with .NET. It supports various hosting models, including Blazor WebAssembly, Blazor Server, Blazor WebApp, and Maui Blazor (Hybrid). diff --git a/docs/en/solution-templates/microservice/overview.md b/docs/en/solution-templates/microservice/overview.md index fc322565c3..6edc7c3c67 100644 --- a/docs/en/solution-templates/microservice/overview.md +++ b/docs/en/solution-templates/microservice/overview.md @@ -47,7 +47,7 @@ The following features are built and pre-configured for you in the solution. * **Authentication** is fully configured based on best practices; * **JWT Bearer Authentication** for microservices and applications. * **OpenId Connect Authentication**, if you have selected the MVC UI. - * **Authorization code flow** is implemented, if you have selected a SPA UI (Angular or Blazor WASM). + * **Authorization code flow** is implemented, if you have selected a SPA UI (Angular, Blazor WASM or React). * Other flows (resource owner password, client credentials...) are easy to use when you need them. * **[Permission](../../framework/fundamentals/authorization/index.md)** (authorization), **[setting](../../framework/infrastructure/settings.md)**, **[feature](../../framework/infrastructure/features.md)** and the **[localization](../../framework/fundamentals/localization.md)** management systems are pre-configured and ready to use. * **[Background job system](../../framework/infrastructure/background-jobs/index.md)** with [RabbitMQ integrated](../../framework/infrastructure/background-jobs/rabbitmq.md). @@ -105,6 +105,7 @@ The solution comes with a main web application with the following UI Framework o * **MVC / Razor Pages UI** * **Blazor WebAssembly** * **Blazor Server** +* **[React UI](../../framework/ui/react/index.md)** * **MAUI with Blazor (Hybrid)** ### The Mobile Application diff --git a/docs/en/solution-templates/microservice/web-applications.md b/docs/en/solution-templates/microservice/web-applications.md index 6c50a7801a..ffe7d37509 100644 --- a/docs/en/solution-templates/microservice/web-applications.md +++ b/docs/en/solution-templates/microservice/web-applications.md @@ -57,6 +57,7 @@ The following options are provided while [creating the solution](../../get-start * Angular * Blazor WebAssembly * Blazor Server +* React UI * MAUI Blazor (Hybrid) The following sections explain each of these UI types. @@ -77,6 +78,10 @@ If you've selected the Blazor WebAssembly UI while creating your solution, `Acme If you've selected the Blazor Server UI while creating your solution, `Acme.CloudCrm.Blazor` project is included in the `apps` folder of the solution. That folder contains the main web application of the solution that is implemented using Blazor Server. +### React Web Application + +If you've selected the React UI while creating your solution, the `react` application is included in the `apps` folder of the solution. The template also includes the React Admin Console surface. Both are served through the Web Gateway and authenticate with the AuthServer using OpenID Connect. + ### MAUI Blazor (Hybrid) Web Application If you've selected the MAUI Blazor (Hybrid) UI while creating your solution, `Acme.CloudCrm.MauiBlazor` project is included in the `apps` folder of the solution. That folder contains the main desktop application of the solution that is implemented using MAUI Blazor (Hybrid) that uses existing Blazor UI Implementation. diff --git a/docs/en/solution-templates/single-layer-web-application/overview.md b/docs/en/solution-templates/single-layer-web-application/overview.md index c7e16090a7..568fa4294a 100644 --- a/docs/en/solution-templates/single-layer-web-application/overview.md +++ b/docs/en/solution-templates/single-layer-web-application/overview.md @@ -92,6 +92,7 @@ The solution comes with a main web application with the following UI Framework o * **MVC / Razor Pages UI** * **Blazor WebAssembly** * **Blazor Server** +* **[React UI](../../framework/ui/react/index.md)** ### Multi-Tenancy & SaaS Module **\*** diff --git a/docs/en/solution-templates/single-layer-web-application/web-applications.md b/docs/en/solution-templates/single-layer-web-application/web-applications.md index f454b3630e..5681c296c9 100644 --- a/docs/en/solution-templates/single-layer-web-application/web-applications.md +++ b/docs/en/solution-templates/single-layer-web-application/web-applications.md @@ -25,6 +25,7 @@ The single-layer solution template includes a web application project that acts - **MVC / Razor Pages**: This is an ASP.NET Core MVC application. It is a traditional web application that serves HTML pages to users and is suitable for building web applications with server-side rendering. - **Angular**: This is an Angular application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and is ideal for building modern web applications with rich user interfaces. +- **React UI**: This is a React application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and includes the React-based ABP Admin Console integration. - **Blazor UI**: A flexible framework for building web applications with .NET. It supports various hosting models: - **Blazor WebAssembly**: This is a client-side SPA that runs entirely in the user's browser. It communicates with the server using HTTP requests and is suitable for modern web applications with rich interactivity and offline capabilities. - **Blazor Server**: This is a server-side SPA that runs on the server and communicates with the client in real time using SignalR. It is ideal for applications requiring constant connectivity and rapid server updates. @@ -50,6 +51,18 @@ When you select the Angular option in the single-layer solution template, it gen The Angular application runs as a client-side SPA in the user's browser and communicates with the server by sending HTTP requests to the ASP.NET Core host application. +## React UI + +React UI is a modern SPA option built with React, Vite, TanStack Router, TanStack Query, shadcn/ui-style components, Axios, and Vitest. + +When you select the React option in the single-layer solution template, it generates: + +- A React application located under the solution's root folder, typically named `react`. +- The ASP.NET Core host application, usually named something like `Acme.BookStore`. +- An embedded React Admin Console hosted by the backend through the `Volo.Abp.AdminConsole` package. + +The React application runs as a client-side SPA in the user's browser and communicates with the server by sending HTTP requests to the ASP.NET Core host application. See the [React UI documentation](../../framework/ui/react/index.md) for details. + ## Blazor UI Blazor is a flexible framework for building web applications with .NET. It supports various hosting models, including Blazor WebAssembly, Blazor Server, Blazor WebApp, and Maui Blazor (Hybrid). From 7e6614869085b9ac13bdfe604de985b463faa3b7 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 18:26:11 +0300 Subject: [PATCH 09/10] docs: refine React admin console configuration Co-authored-by: Cursor --- docs/en/framework/ui/react/admin-console.md | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/en/framework/ui/react/admin-console.md b/docs/en/framework/ui/react/admin-console.md index adbe4056c3..47bc355b76 100644 --- a/docs/en/framework/ui/react/admin-console.md +++ b/docs/en/framework/ui/react/admin-console.md @@ -106,9 +106,9 @@ GET /admin-console/api/config This endpoint provides Admin Console runtime settings such as authority, client ID, scopes, application name, customization options, and localization language configuration. -Host applications can configure Admin Console options from the `AdminConsole` configuration section. +Host applications can configure Admin Console options from the `AdminConsole` configuration section or by configuring `AbpAdminConsoleOptions`. -## `appsettings.json` Customization +## Configuring the Admin Console In layered and single-layer modern React templates, the embedded Admin Console is configured from the backend host application's `appsettings.json` file. The generated template includes an `AdminConsole` section similar to the following: @@ -128,6 +128,26 @@ In layered and single-layer modern React templates, the embedded Admin Console i } ``` +You can also configure the same values in the module class with `AbpAdminConsoleOptions`: + +```csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + Configure(options => + { + options.IsEnabled = true; + options.RedirectRootToAdminConsole = true; + options.Authority = "https://localhost:44300"; + options.ClientId = "Acme_BookStore_AdminConsole"; + options.Scope = "openid profile email offline_access Acme_BookStore"; + options.LocalizationLanguages = new[] { "en", "tr" }; + options.ThemeOverrideCssPath = "/theme-override.css"; + options.InitialTheme = "system"; + options.CustomizationPermissionName = "AdminConsole.Customization"; + }); +} +``` + The most commonly changed options are: | Option | Description | From c95bd045e2bcc55db350dd77259f68d3dcaddba0 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Wed, 6 May 2026 18:26:58 +0300 Subject: [PATCH 10/10] Revert "docs: add React to UI framework docs" This reverts commit 5f2aca20ce070d441a435c4256898b568d30cb7c. --- docs/en/get-started/layered-web-application.md | 15 +++------------ docs/en/get-started/microservice.md | 4 +--- .../get-started/single-layer-web-application.md | 12 +++--------- docs/en/modules/identity.md | 2 +- .../layered-web-application/overview.md | 1 - .../layered-web-application/web-applications.md | 13 ------------- .../solution-templates/microservice/overview.md | 3 +-- .../microservice/web-applications.md | 5 ----- .../single-layer-web-application/overview.md | 1 - .../web-applications.md | 13 ------------- 10 files changed, 9 insertions(+), 60 deletions(-) diff --git a/docs/en/get-started/layered-web-application.md b/docs/en/get-started/layered-web-application.md index cfbe1ebc40..f4a383ff0b 100644 --- a/docs/en/get-started/layered-web-application.md +++ b/docs/en/get-started/layered-web-application.md @@ -10,7 +10,7 @@ ````json //[doc-params] { - "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG", "React"], + "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG"], "DB": ["EF", "Mongo"], "Tiered": ["Yes", "No"] } @@ -62,8 +62,6 @@ Once your configuration is done, click the *Next* button to navigate to the *UI ![abp-studio-new-solution-dialog-ui-framework-blazor-webapp](images/abp-studio-new-solution-dialog-ui-framework-blazor-webapp_dark.png) {{ else if UI == "NG" }} ![abp-studio-new-solution-dialog-ui-framework-ng](images/abp-studio-new-solution-dialog-ui-framework-ng_dark.png) -{{ else if UI == "React" }} -React UI is available in the modern template flow with ABP Studio v3.0+. Select **React** in the UI Framework list to create the React app and Admin Console integration. {{ end }} Here, you see all the possible UI options supported by that startup solution template. Pick the **{{ UI_Value }}**. @@ -194,9 +192,6 @@ You can start the following application(s): {{ if UI == "NG" }} {{ if Tiered == "No" }}- `Acme.BookStore.HttpApi.Host`{{ end }} - `Acme.BookStore.Angular` -{{ else if UI == "React" }} -{{ if Tiered == "No" }}- `Acme.BookStore.HttpApi.Host`{{ end }} -- `react` {{ else if UI == "Blazor" }} {{ if Tiered == "No" }}- `Acme.BookStore.HttpApi.Host`{{ end }} - `Acme.BookStore.Blazor` @@ -212,7 +207,7 @@ You can start the following application(s): > Notice that the services running in docker-compose are exposed to your localhost. If any service in your localhost is already using the same port(s), you will get an error. In that case, stop your local services first. {{ end }} -Once the {{ if UI == "React" }}`react`{{ else }}`Acme.BookStore.{{ if UI == "NG" }}Angular{{ else if UI == "BlazorServer" || UI == "Blazor" || UI == "BlazorWebApp" }}Blazor{{ else }}Web{{ end }}`{{ end }} application started, you can right-click it and select the *Browse* command: +Once the `Acme.BookStore.{{ if UI == "NG" }}Angular{{ else if UI == "BlazorServer" || UI == "Blazor" || UI == "BlazorWebApp" }}Blazor{{ else }}Web{{ end }}` application started, you can right-click it and select the *Browse* command: ![abp-studio-quick-start-browse-command](images/abp-studio-quick-start-browse-command_dark.png) @@ -244,11 +239,7 @@ Once the solution is opened in Visual Studio, you should see a screen like shown ![visual-studio-bookstore-application](images/visual-studio-bookstore-application_dark.png) -{{ if UI == "React" }} -Right-click the `Acme.BookStore.HttpApi.Host` project and select the *Set as Startup Project* command. You can then hit *F5* or *Ctrl + F5* to run the backend host application. Start the React application from the `react` folder with `npm run dev`, then browse the React UI. -{{ else }} Right-click the `Acme.BookStore.{{ if UI == "NG" || UI == "Blazor" }}HttpApi.Host{{ else if UI == "BlazorServer" || UI == "BlazorWebApp" }}Blazor{{ else }}Web{{ end }}` project and select the *Set as Startup Project* command. You can then hit *F5* or *Ctrl + F5* to run the web application. It will run and open the application UI in your default browser: -{{ end }} ![bookstore-browser-users-page](images/bookstore-browser-users-page_dark.png) @@ -266,7 +257,7 @@ You can start the following application(s): - `Docker-Dependencies` - `Acme.BookStore.AuthServer` - `Acme.BookStore.HttpApi.Host` -{{ else if UI == "NG" || UI == "Blazor" || UI == "React" }} +{{ else if UI == "NG" || UI == "Blazor" }} - `Acme.BookStore.HttpApi.Host` {{ else if UI == "BlazorServer" }} - `Acme.BookStore.Blazor` diff --git a/docs/en/get-started/microservice.md b/docs/en/get-started/microservice.md index 5fb5aa927c..d30e3926fc 100644 --- a/docs/en/get-started/microservice.md +++ b/docs/en/get-started/microservice.md @@ -64,8 +64,6 @@ On that screen, you can enable multi-tenancy for your solution. After selecting Here, you see all the possible UI options supported by that startup solution template. You can pick your favorite one and click the *Next* button for the *Mobile Framework* selection screen: -If you select **React**, the solution includes the main React application and the React Admin Console surface. The Admin Console uses its own OpenIddict client and is served through the Web Gateway with the rest of the solution. - ![abp-studio-new-solution-dialog-mobile-framework](images/abp-studio-new-solution-dialog-mobile-framework-microservice.png) Here, you see all the mobile applications available in that startup solution template. These mobile applications are well-integrated into your solution and can use the same backend with your web application. They are simple (do not have pre-built features as much as the web application) but a very good starting point to build your mobile application. @@ -202,7 +200,7 @@ You can click the *Play* button on the root item in *Solution Runner* to start a > > Some applications/services may fail on the first run. That may be because of service and database dependencies were not satisfied and an error occurs on the application startup. ABP Studio automatically restarts failing services until it is successfully started. Being completely ready for such a distributed solution may take a while, but it will be eventually started. -Once all the applications are ready, you can right-click the main web application and select the *Browse* command. For React UI solutions, this is the `react` application. +Once all the applications are ready, you can right-click the `Web` application and select the *Browse* command: ![abp-studio-microservice-solution-runner-browse](images/abp-studio-microservice-solution-runner-browse.png) diff --git a/docs/en/get-started/single-layer-web-application.md b/docs/en/get-started/single-layer-web-application.md index 7c25202f04..ef657722b0 100644 --- a/docs/en/get-started/single-layer-web-application.md +++ b/docs/en/get-started/single-layer-web-application.md @@ -10,7 +10,7 @@ ````json //[doc-params] { - "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG", "React"], + "UI": ["MVC", "Blazor", "BlazorServer", "BlazorWebApp", "NG"], "DB": ["EF", "Mongo"] } ```` @@ -62,8 +62,6 @@ Once your configuration is done, click the *Next* button to navigate to the *UI ![abp-studio-new-solution-dialog-ui-framework-blazor-webapp](images/abp-studio-no-layers-new-solution-dialog-ui-framework-blazor-webapp_dark.png) {{ else if UI == "NG" }} ![abp-studio-new-solution-dialog-ui-framework-ng](images/abp-studio-no-layers-new-solution-dialog-ui-framework-ng_dark.png) -{{ else if UI == "React" }} -React UI is available in the modern template flow with ABP Studio v3.0+. Select **React** in the UI Framework list to create the React app and Admin Console integration. {{ end }} Here, you see all the possible UI options supported by that startup solution template. Pick the **{{ UI_Value }}**. @@ -148,9 +146,9 @@ In the Solution Runner section (on the left side) you can see all the runnable a To start an application, either click the *Play* icon near to the application or right-click and select the *Run* -> *Start* context menu item. -You can start the `Acme.BookStore`{{ if UI == "NG" }} and `Acme.BookStore.Angular`{{ else if UI == "React" }} and `react`{{ end }}. +You can start the `Acme.BookStore`{{ if UI == "NG" }} and `Acme.BookStore.Angular`{{ end }}. -Once the {{ if UI == "React" }}`react`{{ else }}`Acme.BookStore{{ if UI == "NG" }}.Angular{{ end }}`{{ end }} application started, you can right-click it and select the *Browse* command: +Once the `Acme.BookStore{{ if UI == "NG" }}.Angular{{ end }}` application started, you can right-click it and select the *Browse* command: ![abp-studio-quick-start-browse-command](images/abp-studio-no-layers-quick-start-browse-command_dark.png) @@ -182,11 +180,7 @@ Once the solution is opened in Visual Studio, you should see a screen like shown ![visual-studio-bookstore-application](images/no-layers-visual-studio-bookstore-application_dark.png) -{{ if UI == "React" }} -You can then hit *F5* or *Ctrl + F5* to run the backend host application. Start the React application from the `react` folder with `npm run dev`, then browse the React UI. -{{ else }} You can then hit *F5* or *Ctrl + F5* to run the web application. It will run and open the application UI in your default browser: -{{ end }} ![bookstore-browser-users-page](images/no-layers-bookstore-browser-users-page_dark.png) diff --git a/docs/en/modules/identity.md b/docs/en/modules/identity.md index b7f13a9c8b..d92f4b7b8e 100644 --- a/docs/en/modules/identity.md +++ b/docs/en/modules/identity.md @@ -19,7 +19,7 @@ The source code of this module can be accessed [here](https://github.com/abpfram ## User Interface -This module provides [Blazor](../framework/ui/blazor/overall.md), [Angular](../framework/ui/angular/quick-start.md), [React](../framework/ui/react/index.md) and [MVC / Razor Pages](../framework/ui/mvc-razor-pages/overall.md) UI options. +This module provides [Blazor](../framework/ui/blazor/overall.md), [Angular](../framework/ui/angular/quick-start.md) and [MVC / Razor Pages](../framework/ui/mvc-razor-pages/overall.md) UI options. ### Menu Items diff --git a/docs/en/solution-templates/layered-web-application/overview.md b/docs/en/solution-templates/layered-web-application/overview.md index a75698fd79..1a091649cc 100644 --- a/docs/en/solution-templates/layered-web-application/overview.md +++ b/docs/en/solution-templates/layered-web-application/overview.md @@ -96,7 +96,6 @@ The solution comes with a main web application with the following UI Framework o * **Blazor WebAssembly** * **Blazor Server** * **Blazor WebApp** -* **[React UI](../../framework/ui/react/index.md)** * **MAUI with Blazor (Hybrid)** **\*** ### The Mobile Application diff --git a/docs/en/solution-templates/layered-web-application/web-applications.md b/docs/en/solution-templates/layered-web-application/web-applications.md index 38d35772e1..8400a6dfbe 100644 --- a/docs/en/solution-templates/layered-web-application/web-applications.md +++ b/docs/en/solution-templates/layered-web-application/web-applications.md @@ -27,7 +27,6 @@ The web applications are the main user interfaces of the solution. They are the - **MVC / Razor Pages**: This is an ASP.NET Core MVC application. It is a traditional web application that serves HTML pages to users and is suitable for building web applications with server-side rendering. - **Angular**: This is an Angular application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and is ideal for building modern web applications with rich user interfaces. -- **React UI**: This is a React application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and includes the React-based ABP Admin Console integration. - **Blazor UI**: A flexible framework for building web applications with .NET. It supports various hosting models: - **Blazor WebAssembly**: This is a client-side SPA that runs entirely in the user's browser. It communicates with the server using HTTP requests and is suitable for modern web applications with rich interactivity and offline capabilities. - **Blazor Server**: This is a server-side SPA that runs on the server and communicates with the client in real time using SignalR. It is ideal for applications requiring constant connectivity and rapid server updates. @@ -131,18 +130,6 @@ See the [testing document](https://angular.dev/guide/testing). * [Chart.js](https://www.chartjs.org/) is used to create widgets. * [ngx-validate](https://github.com/ng-turkey/ngx-validate) is used for dynamic validation of reactive forms. -## React UI - -React UI is a modern SPA option built with React, Vite, TanStack Router, TanStack Query, shadcn/ui-style components, Axios, and Vitest. - -When you select the React option in the Layered Solution Template, it generates: - -- A React application located under the solution's root folder, typically named `react`. -- An ASP.NET Core application, named `*.HttpApi.Host`, where the server-side HTTP APIs run. -- An embedded React Admin Console hosted by the backend through the `Volo.Abp.AdminConsole` package. - -The React application communicates with the server by sending HTTP requests to the `*.HttpApi.Host` application. See the [React UI documentation](../../framework/ui/react/index.md) for details. - ## Blazor UI Blazor is a flexible framework for building web applications with .NET. It supports various hosting models, including Blazor WebAssembly, Blazor Server, Blazor WebApp, and Maui Blazor (Hybrid). diff --git a/docs/en/solution-templates/microservice/overview.md b/docs/en/solution-templates/microservice/overview.md index 6edc7c3c67..fc322565c3 100644 --- a/docs/en/solution-templates/microservice/overview.md +++ b/docs/en/solution-templates/microservice/overview.md @@ -47,7 +47,7 @@ The following features are built and pre-configured for you in the solution. * **Authentication** is fully configured based on best practices; * **JWT Bearer Authentication** for microservices and applications. * **OpenId Connect Authentication**, if you have selected the MVC UI. - * **Authorization code flow** is implemented, if you have selected a SPA UI (Angular, Blazor WASM or React). + * **Authorization code flow** is implemented, if you have selected a SPA UI (Angular or Blazor WASM). * Other flows (resource owner password, client credentials...) are easy to use when you need them. * **[Permission](../../framework/fundamentals/authorization/index.md)** (authorization), **[setting](../../framework/infrastructure/settings.md)**, **[feature](../../framework/infrastructure/features.md)** and the **[localization](../../framework/fundamentals/localization.md)** management systems are pre-configured and ready to use. * **[Background job system](../../framework/infrastructure/background-jobs/index.md)** with [RabbitMQ integrated](../../framework/infrastructure/background-jobs/rabbitmq.md). @@ -105,7 +105,6 @@ The solution comes with a main web application with the following UI Framework o * **MVC / Razor Pages UI** * **Blazor WebAssembly** * **Blazor Server** -* **[React UI](../../framework/ui/react/index.md)** * **MAUI with Blazor (Hybrid)** ### The Mobile Application diff --git a/docs/en/solution-templates/microservice/web-applications.md b/docs/en/solution-templates/microservice/web-applications.md index ffe7d37509..6c50a7801a 100644 --- a/docs/en/solution-templates/microservice/web-applications.md +++ b/docs/en/solution-templates/microservice/web-applications.md @@ -57,7 +57,6 @@ The following options are provided while [creating the solution](../../get-start * Angular * Blazor WebAssembly * Blazor Server -* React UI * MAUI Blazor (Hybrid) The following sections explain each of these UI types. @@ -78,10 +77,6 @@ If you've selected the Blazor WebAssembly UI while creating your solution, `Acme If you've selected the Blazor Server UI while creating your solution, `Acme.CloudCrm.Blazor` project is included in the `apps` folder of the solution. That folder contains the main web application of the solution that is implemented using Blazor Server. -### React Web Application - -If you've selected the React UI while creating your solution, the `react` application is included in the `apps` folder of the solution. The template also includes the React Admin Console surface. Both are served through the Web Gateway and authenticate with the AuthServer using OpenID Connect. - ### MAUI Blazor (Hybrid) Web Application If you've selected the MAUI Blazor (Hybrid) UI while creating your solution, `Acme.CloudCrm.MauiBlazor` project is included in the `apps` folder of the solution. That folder contains the main desktop application of the solution that is implemented using MAUI Blazor (Hybrid) that uses existing Blazor UI Implementation. diff --git a/docs/en/solution-templates/single-layer-web-application/overview.md b/docs/en/solution-templates/single-layer-web-application/overview.md index 568fa4294a..c7e16090a7 100644 --- a/docs/en/solution-templates/single-layer-web-application/overview.md +++ b/docs/en/solution-templates/single-layer-web-application/overview.md @@ -92,7 +92,6 @@ The solution comes with a main web application with the following UI Framework o * **MVC / Razor Pages UI** * **Blazor WebAssembly** * **Blazor Server** -* **[React UI](../../framework/ui/react/index.md)** ### Multi-Tenancy & SaaS Module **\*** diff --git a/docs/en/solution-templates/single-layer-web-application/web-applications.md b/docs/en/solution-templates/single-layer-web-application/web-applications.md index 5681c296c9..f454b3630e 100644 --- a/docs/en/solution-templates/single-layer-web-application/web-applications.md +++ b/docs/en/solution-templates/single-layer-web-application/web-applications.md @@ -25,7 +25,6 @@ The single-layer solution template includes a web application project that acts - **MVC / Razor Pages**: This is an ASP.NET Core MVC application. It is a traditional web application that serves HTML pages to users and is suitable for building web applications with server-side rendering. - **Angular**: This is an Angular application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and is ideal for building modern web applications with rich user interfaces. -- **React UI**: This is a React application, a single-page application (SPA) that runs on the client side. It communicates with the server using HTTP requests and includes the React-based ABP Admin Console integration. - **Blazor UI**: A flexible framework for building web applications with .NET. It supports various hosting models: - **Blazor WebAssembly**: This is a client-side SPA that runs entirely in the user's browser. It communicates with the server using HTTP requests and is suitable for modern web applications with rich interactivity and offline capabilities. - **Blazor Server**: This is a server-side SPA that runs on the server and communicates with the client in real time using SignalR. It is ideal for applications requiring constant connectivity and rapid server updates. @@ -51,18 +50,6 @@ When you select the Angular option in the single-layer solution template, it gen The Angular application runs as a client-side SPA in the user's browser and communicates with the server by sending HTTP requests to the ASP.NET Core host application. -## React UI - -React UI is a modern SPA option built with React, Vite, TanStack Router, TanStack Query, shadcn/ui-style components, Axios, and Vitest. - -When you select the React option in the single-layer solution template, it generates: - -- A React application located under the solution's root folder, typically named `react`. -- The ASP.NET Core host application, usually named something like `Acme.BookStore`. -- An embedded React Admin Console hosted by the backend through the `Volo.Abp.AdminConsole` package. - -The React application runs as a client-side SPA in the user's browser and communicates with the server by sending HTTP requests to the ASP.NET Core host application. See the [React UI documentation](../../framework/ui/react/index.md) for details. - ## Blazor UI Blazor is a flexible framework for building web applications with .NET. It supports various hosting models, including Blazor WebAssembly, Blazor Server, Blazor WebApp, and Maui Blazor (Hybrid).