Related Github Documents
Document Properties
Kbid
2945B3
Last Modified
27-Oct-2021
Added to KB
18-Jun-2020
Public Access
Everyone
Status
Online
Doc Type
Guidelines, Concepts & Cookbooks
Product
Intershop Progressive Web App

Guide - Intershop Progressive Web App - Customization Guide

Customization Guide

When customizing the PWA, always keep in mind that you probably want to upgrade from time to time and will have to merge incoming changes into your codebase.
We therefore suggest that you do not edit existing files all too much and keep them as intact as possible.
In this document we provide a couple of rules that you should follow.
Generally speaking:

Keep modifications on existing files as minimal as possible!

It can be tempting to always modify existing templates, component and style files inline when doing customization.
However, when merging incoming upgrades the number of merge conflicts can possibly be large.
So if you want to upgrade to new PWA versions later, stick to the following recommendations.

Setup an Intershop PWA-based Project

When initially setting up an Intershop PWA-based project it is not advisable to clone the complete GitHub repository of the Intershop PWA.
All that is initially needed is the master branch that includes the released versions of the PWA.
This can be achieved with the following Git command.

git clone --single-branch --branch master --origin intershop https://github.com/intershop/intershop-pwa.git project-pwa

This command clones only the master branch from the GitHub repository of the Intershop PWA with the remote name intershop (not origin that will be needed later on for the projects own remote Git repository) into a folder project-pwa (instead of intershop-pwa).

Based on this initial version of the Intershop PWA (the latest release), any project customizations can be started.

Start Customization

To start customizing, set a theme for your customization with the script node schematics/customization/add --default <prefix>.
This will:

  • Add an Angular theme configuration, that is used to configure your individual brand. (see Guide - Multiple Themes)
  • Add style files for customization under src/styles/themes/<prefix>
  • Add the theme as an active theme in package.json. (It will replace all active themes if --default is used.)
  • Add a prefix custom for new Angular artifacts.
  • Customize TSLint to support your new theme files.

After that we recommend to additionally use the prefix custom in every component to further help identifying customized components.

$ node schematics/customization/add brand

$ ng g c shared/components/basket/custom-basket-display
CREATE src/app/shared/components/basket/custom-basket-display/custom-basket-display.component.ts (275 bytes)
...

Specific Concerns

Components

When adding new functionality, it is better to encapsulate it in new components that handle every aspect of the customization and just use them in existing templates.
That way the modifications on existing code are most often kept to a single line change only.

When heavily customizing existing components it is better to copy components and change all references.
If 20 % of the component has to be changed, it is already a good idea to duplicate it.
That way incoming changes will not affect your customizations.
Typical hot-spots where copying is a good idea are header-related or product-detail-page related customizations.

Theme Specific Overrides

The customized webpack build supports replacing any file with an environment suffix in front of the file extension.
If you for example want to customize the template product-detail.component.html, put your customized content in the parallel file product-detail.component.brand.html and run a build with --configuration=brand.
Then this overridden component template will be swapped in.

This also works for multiple configurations: product-detail.component.foo.bar.baz.html will be active for configurations foo, bar and baz, but not for foobar.

There is also a virtual theme all that can be used to always override a specific file.
However, the all theme cannot be used in combination with other themes.
If a theme specific override is available next to an override for all, the specific override will be chosen.

As an example, imagine the following files/overrides exist:

  my.component.html
  my.component.all.html
  my.component.foo.html
  my.component.bar.baz.html
  • In a build for theme foo, the file my.component.foo.html will be swapped in.
  • In a build for theme bar, the file my.component.bar.baz.html will be swapped in.
  • In a build for theme foobar, the file my.component.all.html will be swapped in.
  • The file my.component.html won't be used for any builds.
Schematic Support

You can use the override schematic to introduce custom theme overrides:

override

Deep Copies with Replacements (DEPRECATED)

We supply a schematic customized-copy for copying components and replacing all usages.
This schematic should only be used in rare cases.
Prefer using theme overrides

$ node schematics/customization/add brand
$ ng g customized-copy shared/components/product/product-price
CREATE src/app/shared/components/product/brand-product-price/brand-product-price.component.html (1591 bytes)
CREATE src/app/shared/components/product/brand-product-price/brand-product-price.component.spec.ts (7632 bytes)
CREATE src/app/shared/components/product/brand-product-price/brand-product-price.component.ts (1370 bytes)
UPDATE src/app/shared/shared.module.ts (12676 bytes)
UPDATE src/app/shared/components/product/product-row/product-row.component.html (4110 bytes)
UPDATE src/app/shared/components/product/product-row/product-row.component.spec.ts (5038 bytes)
UPDATE src/app/shared/components/product/product-tile/product-tile.component.html (2140 bytes)
UPDATE src/app/shared/components/product/product-tile/product-tile.component.spec.ts (4223 bytes)
...

Existing Features

When you want to disable code provided by Intershop, it is better to comment it out instead of deleting it.
This allows Git to merge changes more predictably since original and incoming passages are still similar to each other.
Commenting out should be done in the form of block comments starting a line above and ending in an additional line below the code.
Use <!-- and --> for HTML and /* and */ for SCSS and TypeScript.

Some of the provided components supply configuration parameters which can be used to handle customization in an easy way (i.e. disabling features or switching between them).

New Features

When adding new independent features to the PWA, it might be a good idea to add an extension first.
Use the provided schematics ng g extension <name> to scaffold the extension.
Adding all related pages, components, models and services here is less intrusive than adding them to the existing folder structure.
Add additional artifacts to extensions by supplying the --extension flag to schematics calls.

Data

When adding new fields to PWA data models, add them to interfaces and map them as early as possible in mapper classes to model classes.
That way the data can be readily used on templates.
Improving and parsing improper data too late could lead to more modifications on components and templates which will be harder to upgrade later on.

NgRx

Adding new data to the state should always almost exclusively be done by adding new stores in store groups.
Add one with ng g store-group <group> and then add consecutive stores with ng g store --feature <group> <store>.
Keep modifications to the existing store as little as possible.
As NgRx is loosely coupled by nature, you can deactivate effects by simply commenting out the @Effect decorator.

Testing

When modifying components it is most likely that related test cases will fail.
If possible, use the Jest update feature update snapshots when adapting test cases.
When you upgrade the PWA to a new version, those snapshots will most likely have merge conflicts in them.
Here you can just accept either modification and update the test snapshots.

Styling

Changing the styling of existing components should be done by adding overrides in the custom theme folder under src/styles/themes.
For this you could copy only the *.scss files you need to adapt and fit the reference in your themes style.scss.
Or you can start your styling changes by copying the complete set of standard styles to your themes folder right from the start and do all the changes there.
Or you can come up with your own preferred way for styling adaptions.
Just putting a brand override file next to the original file in the src/styles folder will not lead to the expected results.
You should not change relevant information in the global style files under src/styles.

When styling is done on component level, all styling is encapsulated to exactly this component (default behavior).
You can re-use variables from the global styling on component level by importing only the styling file that defines the theme variables, e.g.

@import 'variables';

Be aware that Visual Studio Code will not resolve the import reference correctly but it works in the build PWA version anyways.

Dependencies

When updating dependencies and resolving conflicts inside of package-lock.json, always accept Intershop's changes first.
After that run npm install to regenerate the file.

Cypress Tests

We currently do not support specific adaptions for customizing Cypress tests in projects.
In theory the customized PWA project can re-use our Page Objects without much adaptions if the customized PWA also uses the same selectors for CSS classes and data-testing-ids.

Specs should be copied and adapted for the project to use correct demo data.
When executing tests, the test itself requires an appropriate demo server to be launched before the run.
We currently use patterns in the test name to determine the channel for which the test can be run.
E.g. login-user.b2b.b2c.e2e-spec.ts can be run on with the inSPIRED B2C and B2B channels.
The same system can be adopted for customization projects.

Import Changes from New PWA Release (Migration)

Importing changes of new releases is done with Git tooling.
If you stick to the guidelines in this chapter, the process of updating should run without major problems.
Also remember to use npm install after importing a change that modified the package.json and package-lock.json and run tests and linting in the process.

Reading through the migrations.md and the CHANGELOG.md - here especially the 'Breaking Changes' section - should be the first step before any migration.

The first step for any migration is to add the Intershop PWA GitHub repository as an additional remote if this is not already the case.

git remote add intershop https://github.com/intershop/intershop-pwa.git

For importing changes from the current release, you can use different approaches:

1. Range Cherry Pick of New Release Commits

For the range git cherry-pick approach one needs to create a new branch based on the current project's main development branch, naming it, for example, migration_to_1.1.

git checkout -b migration_to_1.1

Now the Git commits of the new Intershop PWA release will be cherry picked into this migration branch.
For this, one needs to provide the wanted commit range which should be possible by using the Intershop PWA version tags, e.g. 1.0.0 to 1.1.0.
If there are any problems with the tags, using the specific commit SHAs should always work.

git cherry-pick 1.0.0..1.1.0

Now each commit of the new Intershop PWA release is applied to the custom project context.
Thus, if any merge conflicts arise, this will be within the specific Intershop PWA commit context and should be mergeable with the information and diff provided for this commit in the GitHub repository.

After successfully going through the range cherry pick (with git commit and git cherry-pick --continue after each resolved merge conflict), an npm install will probably be required and one needs to check whether the project code still works as expected.
Starting the server or npm run check are good basic tests for that.

2. Rebase Commits of New Release

For the git rebase --onto approach one needs to create a new branch based on the release tag of the Intershop PWA one wants to migrate to, naming it, for example, migration_to_1.1.

git checkout -b migration_to_1.1 1.1.0

Now the branch with the Git commits of the new Intershop PWA release will be rebased onto the current project's main development branch.
For this, one needs to provide the branch name of the target branch to rebase onto.
In addition, a commit is needed where the current migration branch should be "cut off".
This is usually the current version tag of the Intershop PWA used currently in the custom project, e.g. 1.0.0.
If there are any problems with the tag, using the specific commit SHAs should always work.

git rebase --onto develop 1.0.0

Now each commit of the new Intershop PWA release is applied to the custom project context.
Thus, if any merge conflicts arise, this will be within the specific Intershop PWA commit context and should be mergeable with the information and diff provided for this commit in the GitHub repository.

After successfully going through the rebase onto (with git rebase --continue after each resolved merge conflict), an npm install will probably be required and one needs to check whether the project code still works as expected.
Starting the server or npm run check are good basic tests for that.

3. Merge the New Release in its Entirety

This is also a possible way to migrate your custom project to the latest version of the Intershop PWA, but you will have to resolve all potentially appearing conflicts at once and without the specific commit context.

Just add the Intershop PWA GitHub repository as a second remote in your project and git merge the release branch.

Prior to 0.16.1 the entire git history changed completely.
Please see Merging 0.16.1 as 2nd upstream repository: "refusing to merge unrelated histories for suggestions on importing the new history.

Hints

  • The Intershop PWA project is configured to follow consistent formatting rules.
    For a better overview of relevant changes and less merge efforts it is advised to adhere to these rules during project development as well.
    For this, one needs to configure one's IDE accordingly.
    The fitting Visual Studio Code configuration is part of the project.
  • The Intershop PWA project configures and contains a set of linting rules that also aim to ensure a consistent code style and are intended to prevent any coding patterns that are considered problematic.
    It is advised to follow these rules in customer projects as well.
    If some rules are actually unwanted in a project, it is best to disable these configurations but to keep all other checks intact and to address any violations.
  • Keep the unit tests running and write new ones.
    This will also help ensuring not to break any existing functionality after a migration.
  • npm run check should run through successfully on local development environments after a feature or bugfix or migration has finished.
    This check can be left to a CI pipeline as well but the task should be configured in a way that fits the requirements of the project.

Further References

Disclaimer

The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.

Customer Support
Knowledge Base
Product Resources
Tickets