Skip to content

Migration Guide — Shell v2 to v3

Shell v3 upgrades the underlying Angular framework from Angular 19 to Angular 21 and introduces a new library, @yuuvis/client-components, that consolidates generic, backend-independent UI components. This guide walks through the complete migration process for an existing client project.

Areav2v3
Angular1921
Client CLI1921
TypeScript5.7.35.9.3
Shell libraries5 packages6 packages (new: @yuuvis/client-components)

New library — @yuuvis/client-components

Generic, backend-independent UI components (layout primitives, form controls, directives) that previously lived in @yuuvis/client-framework have been extracted into a dedicated library. In v3 the original exports in @yuuvis/client-framework remain available but are marked deprecated and will be removed in v4.

See Deprecated Entry Points in @yuuvis/client-framework for the full list of affected entry points and their replacements.

Angular upgrade in two hops

Angular does not support skipping major versions. The migration therefore follows two sequential steps: Angular 19 → 20, then Angular 20 → 21.

  • Back up your project. Commit all pending changes and push to a remote branch before starting.
  • Node.js: Use the version required by Angular 21 (Node.js 20 or 22 LTS recommended).
  • yuuvis Client CLI: After completing the Angular upgrade you will update the CLI. Keep the current version installed until the upgrade is complete.
  • Verify the project builds cleanly on v2 before migrating:
    Terminal window
    npm run build

  1. Run the Angular update schematics

    The ng update command updates the Angular CLI, framework packages, and automatically applies Angular’s own migration schematics for breaking changes between versions.

    Terminal window
    npx ng update @angular/cli@20 @angular/core@20

    Angular 20 ships with a schematic that migrates components to the reactive Signals API. This migration is required before upgrading to Angular 21 — run it now while still on Angular 20:

    Terminal window
    npx ng generate @angular/core:signals
  2. Update yuuvis shell packages to Angular-20-compatible versions

    Set the yuuvis shell libraries to the latest v3 release that targets Angular 20. Edit package.json directly — do not use npm run update:shell at this stage because the existing update script does not yet include @yuuvis/client-components.

    package.json
    ...
    {
    "dependencies": {
    ...
    "@yuuvis/client-core": "3.0.0-beta.20.2",
    "@yuuvis/client-shell-core": "3.0.0-beta.20.2",
    "@yuuvis/client-framework": "3.0.0-beta.20.2",
    "@yuuvis/client-shell": "3.0.0-beta.20.2",
    "@yuuvis/material": "3.0.0-beta.20.2",
    "@yuuvis/media-viewer": "3.0.0-beta.20.0"
    }
    ...
    }
  3. Perform a clean install and verify

    Delete the installed packages and lock file to avoid stale dependency resolutions, then reinstall from scratch:

    Terminal window
    rm -rf node_modules package-lock.json
    npm install

    Run the build to confirm the project compiles without errors:

    Terminal window
    npm run build
  4. Commit the intermediate state

    Commit all changes before proceeding to the next phase. This makes it easy to identify which phase introduced a problem if something goes wrong later.

    Terminal window
    git add .
    git commit -m "chore: upgrade Angular 19 → 20 and shell packages"

  1. Run the Angular update schematics

    Terminal window
    npx ng update @angular/cli@21 @angular/core@21
  2. Add @yuuvis/client-components and update all shell packages

    Shell v3 targeting Angular 21 introduces @yuuvis/client-components as a new required dependency. Add it alongside all other shell packages:

    package.json
    {
    ...
    "dependencies": {
    ...
    "@yuuvis/client-core": "^3.0.0",
    "@yuuvis/client-shell-core": "^3.0.0",
    "@yuuvis/client-components": "^3.0.0",
    "@yuuvis/client-framework": "^3.0.0",
    "@yuuvis/client-shell": "^3.0.0",
    "@yuuvis/material": "^3.0.0",
    "@yuuvis/media-viewer": "^3.0.0"
    }
    ...
    }
  3. Update TypeScript

    The Angular update schematics update tsconfig settings but do not update the typescript package version in devDependencies. Set it manually — this change takes effect in the next step when you reinstall:

    package.json
    {
    "devDependencies": {
    ...
    "@colsen1991/ngx-translate-extract-marker": "^3.0.1",
    "@vendure/ngx-translate-extract": "^10.1.3",
    "typescript": "5.9.3"
    }
    }
  4. Perform a clean install and verify

    Terminal window
    rm -rf node_modules package-lock.json
    npm install
    npm run build

Before applying the CLI patches, install the Angular-21-compatible version of the yuuvis Client CLI globally:

Terminal window
npm install -g @yuuvis/client-cli@^21.0.0

Verify the installed version:

Terminal window
yuv --version

The yuuvis Client CLI ships three patches that fix Angular-21-specific issues in existing projects. Apply them in order:

Terminal window
yuv patch apply p0006
yuv patch apply p0007
yuv patch apply p0008

What it fixes: Angular 21 generates new projects with Zone.js disabled by default (zoneless: true). The shell’s bootstrapShellApplication function requires Zone.js. Without the correct setup Angular throws:

NG0908: In this configuration Angular requires Zone.js

What it changes:

  • src/app/app.config.ts — adds provideZoneChangeDetection({ eventCoalescing: true }) as the first entry in the providers array.
  • angular.json — ensures "zone.js" is present in the polyfills array of the build target.

The patch is applied only when at least one of these two changes is missing from the project.

p0007 — Replace TranslateModule with TranslatePipe

Section titled “p0007 — Replace TranslateModule with TranslatePipe”

What it fixes: Angular 21 introduced a new internal StandaloneService (providedIn: 'environment'). When a standalone component imports a classic NgModule — specifically TranslateModule from @ngx-translate/core — Angular creates a new Environment Injector during route activation and triggers a circular injection error at runtime (the build succeeds, but the app breaks when navigating to the affected route):

NG0203: The EnvironmentInjector token injection failed. inject() must be called from an injection context.

What it changes: Replaces TranslateModule with the standalone TranslatePipe in all CLI-generated app component files matching projects/*/src/lib/*.component.ts:

// before
import { TranslateModule } from '@yuuvis/client-core';
@Component({ imports: [TranslateModule] })
// after
import { TranslatePipe } from '@yuuvis/client-core';
@Component({ imports: [TranslatePipe] })

p0008 — Add @yuuvis/client-components to the update script

Section titled “p0008 — Add @yuuvis/client-components to the update script”

What it fixes: The scripts/update-shell.js script in projects created before Angular 21 does not include @yuuvis/client-components. Running npm run update:shell would therefore leave that library at its old version.

What it changes: Adds @yuuvis/client-components to the pkgs array in scripts/update-shell.js:

const pkgs = [
'@yuuvis/client-core',
'@yuuvis/client-shell-core',
'@yuuvis/client-components', // added by patch
'@yuuvis/client-framework',
'@yuuvis/client-shell',
'@yuuvis/material'
];

After this patch, npm run update:shell -- <version> will keep all six shell libraries in sync.


Phase 4 — ngx-translate Migration (v15 → v17)

Section titled “Phase 4 — ngx-translate Migration (v15 → v17)”

Patch p0007 (applied in Phase 3) fixes the injection error caused by TranslateModule. Separately, @ngx-translate/core released a new major version (v17) with API changes that p0007 does not address. Review the official migration guide to cover those remaining changes:

ngx-translate Migration Guide

Common changes to review in your code:

  • TranslateService method signatures
  • TranslatePipe standalone import usage
  • Custom loader and handler configurations

After applying all patches and completing the ngx-translate review, perform a final clean build:

Terminal window
rm -rf node_modules package-lock.json
npm install
npm run build

Start the development server and verify the application runs as expected:

Terminal window
npm start