Skip to main contentCarbon Design System

1. Installing Carbon

Starting with the Carbon Angular, there are two ways to begin working with Carbon components. By the end, these two methods will produce the same result.

Preview

A preview of what you will build:

Prerequisites

Fork, clone and branch

This tutorial has an accompanying GitHub repository called carbon-tutorial-angular that we’ll use as a starting point for each step.

Fork

To begin, fork carbon-tutorial-angular using your GitHub account.

Clone

Go to your forked repository, copy the SSH or HTTPS URL and in your terminal run the two commands to get the repository in your local file system and enter that directory.

git clone [your fork SSH/HTTPS]
cd carbon-tutorial-angular

Add upstream remote

Add a remote called upstream so we can eventually submit a pull request once you have completed this tutorial step.

SSH:
git remote add upstream git@github.com:carbon-design-system/carbon-tutorial-angular.git

Or, if you prefer to use HTTPS instead of SSH with your remotes:

HTTPS:
git remote add upstream https://github.com/carbon-design-system/carbon-tutorial-angular.git

Verify that your forked repository remotes are correct:

git remote -v

Your terminal should output something like this:

origin [your forked repo] (fetch)
origin [your forked repo] (push)
upstream git@github.com:carbon-design-system/carbon-tutorial-angular.git (fetch)
upstream git@github.com:carbon-design-system/carbon-tutorial-angular.git (push)

Branch

Now that we have our repository set up, let’s check out the branch for this tutorial step’s starting point. Run the two commands:

git fetch upstream
git checkout -b angular-step-1 upstream/angular-step-1

Use starter app (recommended)

Add starter remote

Add a temporary remote called starter so we can clone the carbon-angular-starter.

SSH:
git remote add starter git@github.com:carbon-design-system/carbon-angular-starter.git

Or, if you prefer to use HTTPS instead of SSH with your remotes:

HTTPS:
git remote add starter https://github.com/carbon-design-system/carbon-angular-starter.git

Pull starter code

Now that we a have starter remote, we can rebase our branch to match whatever is in the starter app. Run the two commands:

git fetch starter
git reset --hard starter/master

Remove starter remote

Remove the temporary remote called starter since we have no use for it anymore.

git remote remove starter

Build and start

We have the repository forked to your GitHub account, cloned down to your machine, and the starting branch checked out. Next, install the Carbon app’s dependencies with:

npm install

After the dependencies are installed, you can start the app with:

npm start

Your app should now be running with the message: ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

That’s it! Your browser should now resemble our starter-app.

Update UI Shell

Let’s update the UI Shell so it has a link to the repos page that we will create shortly. In header.component.html replace the code with:

src/app/header/header.component.html
<ibm-header [route]="['/']" name="Carbon Tutorial Angular">
<ibm-header-navigation ariaLabel="Carbon Tutorial Angular">
<ibm-header-item [route]="'[/repos']">Repositories</ibm-header-item>
</ibm-header-navigation>
<ibm-header-global>
<ibm-header-action title="action">
<svg icon ibmIconNotification20></svg>
</ibm-header-action>
<ibm-header-action title="action">

Before we continue on to the next step, we want to begin developing with a clean app. So let’s delete the src/app/starter-home folder and update the routing in app-routing.module.ts by removing the below block:

src/app/app-routing.module.ts
{
path: '',
loadChildren: () => import('./starter-home/starter-home.module').then(m => m.StarterHomeModule)
},

Now you can skip most of Start from scratch and jump straight to Create pages.

Start from scratch

Install Angular CLI

Since we are starting from scratch, we need to first install Angular CLI.

npm install -g @angular/cli

Create an Angular App

Now that we have our environment set up, starting a new Angular app is easy! If you haven’t set up the environment yet, please do so using the steps provided in Prerequisites (above). We will be using the Angular CLI to create and generate our components. It can also generate services, router, components, and directives.

To create a new Angular project with Angular CLI, just run:

ng new carbon-angular-tutorial --directory ./

This will create the new project within the current directory. Make sure you do this within the cloned fork of the project. When you get prompted, enter the following.

? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS

This command will install the Angular app with all the configurations needed. Within the project folder carbon-angular-tutorial, the src directory should have the following structure:

carbon-angular-tutorial
...
├── src
├── app
│   ├── app-routing.module.ts
│   ├── app.component.html
│   ├── app.component.scss
│   ├── app.component.spec.ts
│   ├── app.component.ts

Install Carbon

Even though we installed some dependencies while creating the new app, we’ve yet to install the Carbon packages.

  • carbon-components - component styles
  • carbon-components-angular - Angular components
  • @carbon/icons-angular - Angular icons
npm install carbon-components carbon-components-angular @carbon/icons-angular

Import carbon-component styles

In src/styles.scss, import the Carbon styles by adding the following to the top of the file:

src/styles.scss
@import '~carbon-components/scss/globals/scss/styles';

Code style

Next, we will edit the code style to match Carbon Angular recommendations. Through the conventions listed in our tslint.js, the app will look clean and easier to read and maintain. So replace your code in tslint.json with the code below.

tslint.json
{
"rulesDirectory": [
"node_modules/codelyzer"
],
"rules": {
"callable-types": true,
"class-name": true,
"comment-format": [
true,

Now that our guidelines are defined, we need to apply them to our app.

ng lint --fix

All files should now pass linting. Finally, to help the editor indent lines properly in our project and to keep code styles consistent, we need to edit .editorconfig.

.editorconfig
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = tab
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

Progressive web app

Before we start adding components, let’s explore progressive web app, or PWA. PWA is a web application that has a set of capabilities (similar to native apps) which provide an app-like experience to users. Some other capabilities include full responsiveness and browser compatibility, connectivity independence and self-updates. In the src directory create a file called sw.js and paste the code below.

For more information on PWAs, check out the developer’s documentation.

src/sw.js
let log = console.log.bind(console);
let err = console.error.bind(console);
let version = '1';
let cacheName = 'pwa-client-v' + version;
let dataCacheName = 'pwa-client-data-v' + version;
let appShellFilesToCache = [
'./',
'./index.html',

Now we need to register our service worker and use it to cache files locally. In index.html add the below code in a script block using <script></script> under the app-root tag.

src/index.html
<script>
// Uncomment the following lines to activate the service worker
// if (navigator.serviceWorker) {
// navigator.serviceWorker.register("sw.js").then(() => {
// console.log("Service worker installed");
// }, err => {
// console.error("Service worker error:", err);
// });
// }

Next, we need to add the web app manifest. The manifest is a file in json format that provides the name, description, icon locations and other information required for an app to be considered a PWA. It lets users install the web app on the home screen just like native apps without going through an app store. Create a manifest.json in the src directory the paste the following code.

src/manifest.json
{
"name": "Carbon Angular Starter",
"short_name": "Starter",
"icons": [
{
"src": "/assets/icons/favicon-32x32.png",
"sizes": "32x32",
"type": "image/png"
},

We will also need to add sw.js and manifest.json into our asset entities (build & test) in angular.json and reference the manifest.json and theme-color in the index.html <head> tags. The theme color tells the browser with what color to tint UI elements such as the address bar.

angular.json
"assets": [
"src/favicon.ico",
"src/assets",
"src/sw.js",
"src/manifest.json"
],
src/index.html
<link rel="manifest" href="manifest.json" />
<meta name="theme-color" content="#ffff00" />

Finally, let’s download the different sizes of icons to the src/assests/icons directory by running the following commands:

mkdir src/assets/icons
curl -o src/assets/icons/android-chrome-192x192.png https://raw.githubusercontent.com/carbon-design-system/carbon-angular-starter/master/src/assets/icons/android-chrome-192x192.png
curl -o src/assets/icons/icon-144x144.png https://raw.githubusercontent.com/carbon-design-system/carbon-angular-starter/master/src/assets/icons/icon-144x144.png
curl -o src/assets/icons/icon-192x192.png https://raw.githubusercontent.com/carbon-design-system/carbon-angular-starter/master/src/assets/icons/icon-192x192.png
curl -o src/assets/icons/icon-256x256.png https://raw.githubusercontent.com/carbon-design-system/carbon-angular-starter/master/src/assets/icons/icon-256x256.png
curl -o src/assets/icons/icon-384x384.png https://raw.githubusercontent.com/carbon-design-system/carbon-angular-starter/master/src/assets/icons/icon-384x384.png
curl -o src/assets/icons/icon-512x512.png https://raw.githubusercontent.com/carbon-design-system/carbon-angular-starter/master/src/assets/icons/icon-512x512.png

Run the app

Now we can run our app for a quick preview inside the browser.

npm start

Your app should now be running with the message: ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

Before we start adding components we want to start with an empty project, so delete everything in app.component.html except for the router-outler. We will also have to delete the test that was associated with this code. So in app.component.spec.ts, delete the should render title and should have as title 'carbon-angular-tutorial' test.

Add UI Shell

Next, we’re going to create an Angular component called Header to use with the UI Shell Carbon component. Using Angular CLI we will create this component inside the src/app directory.

ng g component header --lint-fix
Folder structure
src/app/header
├── header.component.html
├── header.component.scss
├── header.component.spec.ts
└── header.component.ts

Import UI Shell

Next we’ll import our Carbon UI Shell components into app.module.ts, app.component.spec.ts and header.component.spec.ts. Set up the file like so:

src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
// carbon-components-angular default imports
import { UIShellModule } from 'carbon-components-angular';
src/app/app.component.spec.ts,src/app/header/header.component.spec.ts
import { UIShellModule } from 'carbon-components-angular/ui-shell/ui-shell.module';
src/app/app.component.spec.ts,src/app/header/header.component.spec.ts
TestBed.configureTestingModule({
declarations: [HeaderComponent],
imports: [UIShellModule]
});

Import icons

Now let’s import the icons from our @carbon/icons-angular package. In app.module.ts, app.component.spec.ts and header.component.spec.ts, we need to import each individual icon we will use.

src/app/app.module.ts,src/app/app.component.spec.ts,src/app/header/header.component.spec.ts
import { Notification20Module } from '@carbon/icons-angular/lib/notification/20';
import { UserAvatar20Module } from '@carbon/icons-angular/lib/user--avatar/20';
import { AppSwitcher20Module } from '@carbon/icons-angular/lib/app-switcher/20';
src/app/app.module.ts,src/app/app.component.spec.ts,src/app/header/header.component.spec.ts
imports: [Notification20Module, UserAvatar20Module, AppSwitcher20Module];

Then we need to add the template code. Populate header.component.html with:

src/app/header/header.component.html
<ibm-header name="Carbon Tutorial Angular">
<ibm-header-navigation ariaLabel="Carbon Tutorial Angular">
<ibm-header-item href="/repos">Repositories</ibm-header-item>
</ibm-header-navigation>
<ibm-header-global>
<ibm-header-action title="action">
<svg icon ibmIconNotification20></svg>
</ibm-header-action>
<ibm-header-action title="action">

Next import the header compoenent in app.component.spec.ts and add the component in app.component.html

src/app/app.component.spec.ts
import { HeaderComponent } from './header/header.component';
src/app/app.component.spec.ts
declarations: [HeaderComponent];
src/app/app.component.html
<app-header></app-header>
<main class="bx--content">
<router-outlet></router-outlet>
</main>

Let’s add some padding to the top of the document, so the content is below the header. We are going to do this by using the bx--header class provided by carbon. So in header.component.ts lets hostbind that class.

import { Component, HostBinding } from '@angular/core';
...
@HostBinding('class.bx--header') headerClass = true;

Create pages

Next thing we need to do is create the files for our content. These files will be located in the app folder inside of src. It should be a sibling of header.

Our app will have two pages. First, we need a landing page. Go ahead and stop your development server (with CTRL-C) and then:

ng g module home --routing --lint-fix
ng g component home/landing-page --lint-fix
Folder structure
src/app/home
├── home
│   ├── landing-page.component.html
│   ├── landing-page.component.scss
│   ├── landing-page.component.spec.ts
│   └── landing-page.component.ts
├── home-routing.module.ts
└── home-page.module.ts

And a repo page:

ng g module repositories --routing --lint-fix
ng g component repositories/repo-page --lint-fix
Folder structure
src/app/repositories
├── repositories
│   ├── repo-page.component.html
│   ├── repo-page.component.scss
│   ├── repo-page.component.spec.ts
│   └── repo-page.component.ts
├── repositories-routing.module.ts
└── repositories.module.ts

Now you can restart your server with npm start.

Add routing

We need to update routing functionality to enable the loading of repositories. Inside app-routing.module.ts we’ll add the following code in the routes array:

src/app-routing.module.ts
const routes: Routes = [
{
path: '',
loadChildren: () => import('./home/home.module').then(m => m.HomeModule),
},
{
path: 'repos',
loadChildren: () =>
import('./repositories/repositories.module').then(

And modify the NgModule declaration to use the hash router:

src/app-routing.module.ts
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})
export class AppRoutingModule {}

And add routes for the landing and repo pages:

src/app/home/home-routing.module.ts
import { LandingPageComponent } from './landing-page/landing-page.component';
const routes: Routes = [
{
path: '',
component: LandingPageComponent,
},
];
src/app/repositories/repositories-routing.module.ts
import { RepoPageComponent } from './repo-page/repo-page.component';
const routes: Routes = [
{
path: '',
component: RepoPageComponent
}
];

After that we need to do a couple quick fixes to the UI Shell to have it route to the repo page.

src/app/header/header.component.html
<ibm-header-item [route]="['/repos']">Repositories</ibm-header-item>

You should now have a working header that routes to the repos pages without full page reload!

Submit pull request

We’re going to submit a pull request to verify completion of this tutorial step and demonstrate a couple related concepts.

Continuous integration (CI) check

We have lint and test scripts defined in package.json that verify file formatting for files that have been touched since the last Git commit. You’d typically also have that script run your test suite as part of your CI build. Go ahead and make sure everything looks good with:

ng lint --fix
npm run lint && npm test

Git commit and push

Before we can create a pull request, we need to stage and commit all of our changes:

git add --all && git commit -m "feat(tutorial): complete step 1"

Then, push to your repository:

git push origin angular-step-1

Pull request (PR)

Finally, visit carbon-tutorial-angular to “Compare & pull request”. In doing so, make sure that you are comparing to angular-step-1 into base: angular-step-1. Take notice of the Netlify bot that deploys a preview of your PR every time that you push new commits. These previews can be shared and viewed by anybody to assist the PR review process.