New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@norce/admin-angular-adapter

Package Overview
Dependencies
Maintainers
3
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@norce/admin-angular-adapter

Makes an Angular app mountable in the Norce admin shell: the mount lifecycle, the host providers, the API helpers and the standalone page.

latest
Source
npmnpm
Version
0.3.0
Version published
Maintainers
3
Created
Source

@norce/admin-angular-adapter

Makes an Angular app mountable in the Norce admin shell, so the app keeps only its pages.

npm install @norce/admin-angular-adapter @norce/admin-contract

It needs Angular ^21.2 (common, core, platform-browser and router) and RxJS ^7.8. It needs no UI library.

The entry

import { defineAngularApp } from '@norce/admin-angular-adapter';
import { providePrimeNG } from 'primeng/config';

import { routes } from './app/routes';
import { AppPreset } from './preset';

export const { contractVersion, mount } = defineAngularApp({
  name: 'users',
  title: 'Users',
  routes,
  styles: new URL('./styles.css', import.meta.url),
  providers: () => [providePrimeNG({ theme: { preset: AppPreset } })],
});

Each mount gets an application of its own with zoneless change detection, routing below ctx.basePath, and the title and breadcrumb handed to the shell. The breadcrumb is the page's route title, under title on every page but the landing one.

OptionMeaning
nameThe module key. It names the root element and Angular's APP_ID.
titleThe app's title, the first breadcrumb item below the landing page.
routesThe app's routes. A catch-all ** route is added after them, which the back button's URLs outside the base path land on.
routerFeaturesFeatures for provideRouter, such as withComponentInputBinding().
stylesThe app's stylesheet, resolved against the entry. It is added on mount and removed on unmount.
providersA function returning the app's own providers, such as its UI library's. It is called on every mount.
rootThe root component. Without one, the app renders its routes and nothing else.
onUnmountRuns after the application is destroyed, for anything the cleanup below does not cover.

Unmount

On unmount the adapter destroys the application and empties the container. It then puts back the children of head and the class and style attributes of html and body as they were before the mount. That removes theme styles, scroll locks and dark-mode classes that a UI library leaves behind, without knowing its selectors.

It does not cover anything else on the page, such as an element appended to body that the application does not destroy, a global listener, a timer or a socket. Remove those in the component that adds them, or in onUnmount.

The API

hostFetch(ctx, url, init) is fetch for the app's own API. It sends a same-origin /api/… URL to /api{basePath}/…, which the shell's backend proxies to the app's /api/…, so the app keeps the API paths of its standalone build. It adds the tenant header and retries once after ctx.onUnauthorized() when the call answers 401. hostInterceptor does the same for HttpClient, on same-origin calls only. HOST_CONTEXT injects the context the shell handed the mount.

provideHost(ctx, { name, title, routes }) gives the providers defineAngularApp uses, which is useful in TestBed. isWithinBasePath(basePath, pathname) tells whether a URL belongs to the app.

The hosted build

The shell imports the entry as a native ES module. An @angular/build:application target builds it without an index.html, with stable names for the entry and the stylesheet:

"build": {
  "builder": "@angular/build:application",
  "options": {
    "browser": "src/main.ts",
    "index": false,
    "styles": ["src/styles.css"],
    "outputHashing": "media"
  }
}

The standalone page

mountStandalone(mount, { basePath }) runs the app on a page of its own, with a stand-in tenant, user and locale. Any other HostContext field can be passed to override the stand-in.

// src/standalone/main.ts
import { mountStandalone } from '@norce/admin-angular-adapter';

import { mount } from '../main';

void mountStandalone(mount, { basePath: '/users' });

The package ships the page's index.html and a stylesheet that loads the shell's theme. The app's own stylesheet is emitted with inject: false, because mount adds it itself:

"standalone": {
  "builder": "@angular/build:application",
  "options": {
    "browser": "src/standalone/main.ts",
    "index": "node_modules/@norce/admin-angular-adapter/standalone/index.html",
    "styles": [
      { "input": "src/styles.css", "inject": false, "bundleName": "styles" },
      {
        "input": "node_modules/@norce/admin-angular-adapter/standalone/standalone.css",
        "bundleName": "standalone"
      }
    ],
    "outputHashing": "media"
  }
}

Point ng serve's buildTarget at this target to develop on the standalone page.

UI library themes

The adapter ships no UI-library theme. An app maps the --norce-admin-* properties from @norce/admin-contract into its library itself, for example a PrimeNG preset whose tokens are var(--norce-admin-…) values. The properties switch with light-dark(), so one set of tokens serves both colour schemes.

FAQs

Package last updated on 08 Nov 2026

Related posts