--- { title: "Package Font Files on NPM for Angular Usage", description: "", published: '2020-11-15T22:12:03.284Z', authors: ['crutchcorn'], tags: ['angular', 'javascript', 'npm'], attached: [], license: 'cc-by-4' } --- While working on my company's shared component system, I got a request from our design team. They wanted to keep our branding consistent with internal documents and other assets. As such, they requested we use a font called "Stirling Foundry". While we're prepping our shared component system for an open-source release to the public, we quickly acknowledged that we couldn't possibly ship this font with the package we intend for public publishing [due to it's licensing and cost](https://www.fonts.com/font/the-foundry/foundry-sterling). However, we have mutliple teams that rely on our shared component system and we don't want to have to copy+paste the relevant `@font-face` definition or font files. What was our solution? Ship a second `npm` package (in our internal `npm` registry) that contained all of our private assets - including font files. Let's walk through how we did that. # Setup Assets Package {#assets-package} As we're wanting to ship our packages seperately, we opted for two Git repositories for the component system and private assets. In a new repository, I have the following for the `package.json`: ```json { "name": "ecp-private-assets", "version": "1.0.0", "main": "index.js", "scripts": { "release": "standard-version" }, "devDependencies": { "@commitlint/cli": "^11.0.0", "@commitlint/config-angular": "^11.0.0", "husky": "^4.3.0", "standard-version": "^9.0.0" }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } }, "commitlint": { "extends": [ "@commitlint/config-angular" ] } } ``` While this package is not going to maintain code, I still believe it important to maintain a semver for the package. If a path of the package changes, the semver will communicate that with your package's consumers alongside the changeling. As such, this `package.json` utilizes [Conventional Commit and `commitlint` to auto-generate changelogs and maintain history version](/posts/setup-standard-version/). ## Add Font Files {#font-files} The "Foundry Stirling" font that I'm shipping is a combination of 7 `.otf` files. I start by creating a `fonts` directory. Inside that directory, I place the `.otf` files in the `fonts` directory. Once done, your project repo should look something like this: ``` . ├── CHANGELOG.md ├── README.md ├── fonts │ ├── foundry_sterling_bold.otf │ ├── foundry_sterling_book.otf │ ├── foundry_sterling_book_italic.otf │ ├── foundry_sterling_demi.otf │ ├── foundry_sterling_extra_bold.otf │ ├── foundry_sterling_light.otf │ └── foundry_sterling_medium.otf ├── index.js ├── package-lock.json └── package.json ``` ## `@font-face` CSS Definition {#css-declare} Now that we have the fonts in their place, we need to create a common `foundry_stirling.css` file to access those fonts from CSS. Because we're planning on using Angular CLI, we'll want to set the `src` property to be prefixed with `/assets/`, since that's where Angular sends it's assets. ```css /* foundry_stirling.css */ @font-face { font-family: 'Foundry Sterling'; font-style: normal; /* Light */ font-weight: 300; src: local('Foundry Sterling Light'), local('FoundrySterling-light'), url("/assets/foundry_sterling_light.otf") format('opentype') } /* ... */ @font-face { font-family: 'Foundry Sterling'; font-style: normal; /* Extra-Bold */ font-weight: 800; src: local('Foundry Sterling Extra Bold'), local('FoundrySterling-extra-bold'), url("/assets/foundry_sterling_extra_bold.otf") format('opentype') } ``` > While we're using CSS here, if you wanted to set the `src` to a different location for non-Angular projects, you could use a SCSS `@mixin` to define the `@font-face` declarations with a customizable `$base_path`. > > ```scss > @mixin foundry_sterling($base_path) { > @font-face { > font-family: 'Foundry Sterling'; > font-style: normal; > /* Extra-Bold */ > font-weight: 800; > src: url("#{$base_path}/foundry_sterling_extra_bold.otf") format('opentype') > } > > // ... Other @font-face declarations > } > ``` > > Then, when consuming the package in your client-side app, you'll want to use something like this: > > ```scss > @include foundry_sterling("/assets") > ``` ### Font Name Value Mapping {#font-val-mapping} Because our font had multiple files to declare the different CSS values weights, we had to declare the `@font-face` for each of the font files. This is the mapping we used: | Value | Common weight name | Related File | | ----- | ------------------------- | --------------------------------- | | 100 | Thin / Hairline | N/A | | 200 | Extra-Light / Ultra-Light | N/A | | 300 | Light | `foundry_sterling_light.otf` | | 400 | Normal / Regular | `foundry_sterling_book.otf` | | 500 | Medium | `foundry_sterling_medium.otf` | | 600 | Semi-Bold / Demi-Bold | `foundry_sterling_demi.otf` | | 700 | Bold | `foundry_sterling_bold.otf` | | 800 | Extra-Bold / Ultra-Bold | `foundry_sterling_extra_bold.otf` | | 900 | Black / Heavy | N/A | # Consume Assets Package in Angular CLI {#angular-cli}