Extending the Admin UI
When creating a plugin, you may wish to extend the Admin UI in order to expose a graphical interface to the plugin’s functionality.
This is possible by defining AdminUiExtensions.
For a complete working example of a Vendure plugin that extends the Admin UI, see the real-world-vendure Reviews plugin
How It Works
A UI extension is an Angular module that gets compiled into the Admin UI application bundle by the compileUiExtensions
function exported by the @vendure/ui-devkit
package. Internally, the ui-devkit package makes use of the Angular CLI to compile an optimized set of JavaScript bundles containing your extensions.
Use Your Favourite Framework
The Vendure Admin UI is built with Angular, and writing UI extensions in Angular is seamless and powerful. But if you are not familiar with Angular, that’s no problem! You can write UI extensions using React, Vue, or any other web technology of choice!
Lazy vs Shared Modules
Angular uses the concept of modules (NgModules) for organizing related code. These modules can be lazily loaded, which means that the code is not loaded when the app starts, but only later once that code is required. This keeps the main bundle small and improves performance.
When creating your UI extensions, you can set your module to be either lazy
or shared
. Shared modules are loaded eagerly, i.e. their code is bundled up with the main app and loaded as soon as the app loads.
As a rule, modules defining new routes should be lazily loaded (so that the code is only loaded once that route is activated), and modules defining new navigations items and custom form input should be set to shared
.
Dev mode
When you are developing your Admin UI extension, you can set the devMode
option to true
which will compile the Admin UI app in development mode, and recompile and auto-refresh the browser on any changes to your extension source files.
// vendure-config.ts
plugins: [
AdminUiPlugin.init({
port: 3002,
app: compileUiExtensions({
outputPath: path.join(__dirname, '../admin-ui'),
extensions: [{
// ...
}],
devMode: true,
}),
}),
],
Compiling as a deployment step
Although the examples so far all use the compileUiExtensions
function in conjunction with the AdminUiPlugin, it is also possible to use it on its own:
// compile-admin-ui.ts
import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
import * as path from 'path';
compileUiExtensions({
outputPath: path.join(__dirname, '../admin-ui'),
extensions: [/* ... */],
}).compile?.().then(() => {
process.exit(0);
});
This can then be run from the command line:
yarn ts-node compile-admin-ui.ts
Once complete, the production-ready app bundle will be output to admin-ui/dist
. This method is suitable for a production setup, so that the Admin UI can be compiled ahead-of-time as part of your deployment process. This ensures that your Vendure server starts up as quickly as possible. In this case, you can pass the path of the compiled app to the AdminUiPlugin:
// project/vendure-config.ts
plugins: [
AdminUiPlugin.init({
port: 3002,
app: {
path: 'admin-ui/dist'
}
}),
],
Note: the TypeScript source files of your UI extensions must not be compiled by your regular TypeScript build task. This is because they will instead be compiled by the Angular compiler when you run compileUiExtensions()
. You can exclude them in your main tsconfig.json
by adding a line to the “exclude” array:
{
"exclude": [
"src/plugins/**/ui/*"
]
}
Also note: When you use compileUiExtensions to compile the Angular App, a new directory will be created to host the compiled Admin-UI app. The name and location of the app is specified by the “outputPath” which is set in the compileUiExtensions options object. Make sure to exlcude the admin-ui directory from typescript’s transpilation since code there is already transpiled.
{
"exclude": [
"node_modules",
"migration.ts",
"admin-ui" // <-- add this
],
}
To compile the angular app ahead of time (for production) and copy the dist folder to Vendure’s output dist folder, include the following commands in your packages.json scripts:
{
"scripts": {
"copy": "npx copyfiles -u 1 'src/__admin-ui/dist/**/*' dist",
"build": "tsc && yarn copy",
"build:admin": "rimraf admin-ui && npx ts-node src/compile-admin-ui.ts",
}
}
“build:admin” will remove the admin-ui folder and run the compileUiExtensions function to generate the admin-ui Angular app. Make sure to install copyfiles before running the “copy” command:
yarn install copyfiles