{"id":15178756,"url":"https://github.com/hapinessjs/ng-universal-module","last_synced_at":"2025-10-01T19:31:12.882Z","repository":{"id":51931085,"uuid":"107660305","full_name":"hapinessjs/ng-universal-module","owner":"hapinessjs","description":"This is a Hapiness Engine for running Angular Apps on the server for server side rendering.","archived":true,"fork":false,"pushed_at":"2021-05-09T00:06:31.000Z","size":504,"stargazers_count":17,"open_issues_count":7,"forks_count":1,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-01-16T01:29:56.593Z","etag":null,"topics":["angular","angular-cli","hapiness","observable","rxjs6","server-side-rendering","universal"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hapinessjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-20T09:40:21.000Z","updated_at":"2024-04-26T23:26:03.000Z","dependencies_parsed_at":"2022-08-22T04:20:12.043Z","dependency_job_id":null,"html_url":"https://github.com/hapinessjs/ng-universal-module","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapinessjs%2Fng-universal-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapinessjs%2Fng-universal-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapinessjs%2Fng-universal-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapinessjs%2Fng-universal-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hapinessjs","download_url":"https://codeload.github.com/hapinessjs/ng-universal-module/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234892715,"owners_count":18902907,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","angular-cli","hapiness","observable","rxjs6","server-side-rendering","universal"],"created_at":"2024-09-27T15:22:57.674Z","updated_at":"2025-10-01T19:31:12.482Z","avatar_url":"https://github.com/hapinessjs.png","language":"TypeScript","readme":"\u003cimg src=\"http://bit.ly/2mxmKKI\" width=\"500\" alt=\"Hapiness\" /\u003e\n\n\u003cdiv style=\"margin-bottom:20px;\"\u003e\n\u003cdiv style=\"line-height:60px\"\u003e\n    \u003ca href=\"https://travis-ci.org/hapinessjs/ng-universal-module.svg?branch=master\"\u003e\n        \u003cimg src=\"https://travis-ci.org/hapinessjs/ng-universal-module.svg?branch=master\" alt=\"build\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://coveralls.io/github/hapinessjs/ng-universal-module?branch=master\"\u003e\n        \u003cimg src=\"https://coveralls.io/repos/github/hapinessjs/ng-universal-module/badge.svg?branch=master\" alt=\"coveralls\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://david-dm.org/hapinessjs/ng-universal-module\"\u003e\n        \u003cimg src=\"https://david-dm.org/hapinessjs/ng-universal-module.svg\" alt=\"dependencies\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://david-dm.org/hapinessjs/ng-universal-module?type=dev\"\u003e\n        \u003cimg src=\"https://david-dm.org/hapinessjs/ng-universal-module/dev-status.svg\" alt=\"devDependencies\" /\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n    \u003ca href=\"https://www.typescriptlang.org/docs/tutorial.html\"\u003e\n        \u003cimg src=\"https://cdn-images-1.medium.com/max/800/1*8lKzkDJVWuVbqumysxMRYw.png\"\n             align=\"right\" alt=\"Typescript logo\" width=\"50\" height=\"50\" style=\"border:none;\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://reactivex.io/rxjs\"\u003e\n        \u003cimg src=\"http://reactivex.io/assets/Rx_Logo_S.png\"\n             align=\"right\" alt=\"ReactiveX logo\" width=\"50\" height=\"50\" style=\"border:none;\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.fastify.io\"\u003e\n        \u003cimg src=\"https://www.fastify.io/images/fastify-logo-menu.d13f8da7a965c800.png\"\n             align=\"right\" alt=\"Fastify logo\" height=\"55\" style=\"border:none;\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.angular.io\"\u003e\n            \u003cimg src=\"https://angular.io/assets/images/logos/angular/angular.svg\"\n                 align=\"right\" alt=\"Angular logo\" width=\"75\" style=\"border:none; margin-top:-5px;\" /\u003e\n        \u003c/a\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n# NG-Universal\n\nThis is a [Hapiness](https://github.com/hapinessjs/hapiness) Engine for running [Angular](https://www.angular.io) Apps on the server for server side rendering.\n\n\u003chr /\u003e\n\n# Integrating NG-Universal into existing CLI Applications\n\nThis story will show you how to set up Universal bundling for an existing `@angular/cli`.\n\nWe support actually `@angular` `@8.1.0` and next so you must upgrade all packages inside your project.\n\nWe use `yarn` as package manager.\n\n## Table of contents\n\n- [Install Dependencies](#install-dependencies)\n- [Step 1: Prepare your App for Universal rendering](#step-1-prepare-your-app-for-universal-rendering)\n    - [src/app/app.module.ts](#srcappappmodulets)\n    - [src/app/app.server.module.ts](#srcappappservermodulets)\n    - [src/main.ts](#srcmaints)\n- [Step 2: Create a server \"main\" file and tsconfig to build it](#step-2-create-a-server-main-file-and-tsconfig-to-build-it)\n    - [src/main.server.ts](#srcmainserverts)\n    - [./tsconfig.server.json](#tsconfigserverjson)\n- [Step 3: Create a new target in angular.json](#step-3-create-a-new-target-in-angularjson)\n    - [angular.json](#angularjson)\n    - [Building the bundle](#building-the-bundle)\n- [Step 4: Setting up a Hapiness Application to run our Universal bundles](#step-4-setting-up-a-hapiness-application-to-run-our-universal-bundles)\n    - [./server.ts (root project level)](#serverts-root-project-level)\n    - [Extra Providers](#extra-providers)\n    - [Using the Request, Reply and Utils](#using-the-requestreply-and-utils)\n- [Step 5: Setup a webpack config to handle this Node server.ts file and serve your application!](#step-5-setup-a-webpack-config-to-handle-this-node-serverts-file-and-serve-your-application)\n    - [./webpack.server.config.js (root project level)](#webpackserverconfigjs-root-project-level)\n    - [Almost there](#almost-there)\n- [Contributing](#contributing)\n- [Change History](#change-history)\n- [Maintainers](#maintainers)\n- [License](#license)\n\n\u003chr /\u003e\n\n## Install Dependencies\n\nInstall `@angular/platform-server` into your project. Make sure you use the same version as the other `@angular` packages in your project.\n\nInstall [Hapiness](https://github.com/hapinessjs/hapiness) modules into your project: [`@hapiness/core`](https://github.com/hapinessjs/hapiness), [`@hapiness/ng-universal`](https://github.com/hapinessjs/ng-universal-module) and [`@hapiness/ng-universal-transfer-http`](https://github.com/hapinessjs/ng-universal-transfer-http).\n\n\u003e You also need :\n\u003e - `ts-loader` and `webpack`, `webpack-cli` for your webpack build we'll show later and it's only in `devDependencies`.\n\u003e - `@nguniversal/module-map-ngfactory-loader`, as it's used to handle lazy-loading in the context of a server-render. (by loading the chunks right away)\n\n\n```bash\n$ yarn add --dev ts-loader webpack webpack-cli\n$ yarn add @angular/platform-server @nguniversal/module-map-ngfactory-loader @hapiness/core @hapiness/ng-universal @hapiness/ng-universal-transfer-http\n```\n\n## Step 1: Prepare your App for Universal rendering\n\nThe first thing you need to do is make your `AppModule` compatible with Universal by adding `.withServerTransition()` and an application ID to your `BrowserModule` import.\n\n`TransferHttpCacheModule` installs a Http interceptor that avoids duplicate `HttpClient` requests on the client, for requests that were already made when the application was rendered on the server side.\n\nWhen the module is installed in the application `NgModule`, it will intercept `HttpClient` requests on the server and store the response in the `TransferState` key-value store. This is transferred to the client, which then uses it to respond to the same `HttpClient` requests on the client.\n\nTo use the `TransferHttpCacheModule` just install it as part of the top-level App module.\n\n### src/app/app.module.ts:\n\n```typescript\nimport { BrowserModule } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\nimport { TransferHttpCacheModule } from '@hapiness/ng-universal-transfer-http';\n\nimport { AppComponent } from './app.component';\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    // Add .withServerTransition() to support Universal rendering.\n    // The application ID can be any identifier which is unique on\n    // the page.\n    BrowserModule.withServerTransition({ appId: 'ng-universal-example' }),\n    // Add TransferHttpCacheModule to install a Http interceptor\n    TransferHttpCacheModule\n  ],\n  providers: [],\n  bootstrap: [AppComponent]\n})\nexport class AppModule {\n}\n```\n\nNext, create a module specifically for your application when running on the server. It's recommended to call this module `AppServerModule`.\n\nThis example places it alongside `app.module.ts` in a file named `app.server.module.ts`:\n\n### src/app/app.server.module.ts:\n\n```typescript\nimport { NgModule } from '@angular/core';\nimport { ServerModule, ServerTransferStateModule } from '@angular/platform-server';\nimport { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';\n\nimport { AppModule } from './app.module';\nimport { AppComponent } from './app.component';\n\n@NgModule({\n  imports: [\n    // The AppServerModule should import your AppModule followed\n    // by the ServerModule from @angular/platform-server.\n    AppModule,\n    ServerModule,\n    ModuleMapLoaderModule,\n    ServerTransferStateModule\n  ],\n  // Since the bootstrapped component is not inherited from your\n  // imported AppModule, it needs to be repeated here.\n  bootstrap: [AppComponent]\n})\nexport class AppServerModule {\n}\n```\n\nThen, you must set an event on `DOMContentLoaded` to be sure `TransferState` will be passed between `server` and `client`.\n\n### src/main.ts:\n\n```typescript\nimport { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n  enableProdMode();\n}\n\ndocument.addEventListener('DOMContentLoaded', () =\u003e {\n  platformBrowserDynamic().bootstrapModule(AppModule)\n    .catch(err =\u003e console.log(err));\n});\n```\n\n[back to top](#table-of-contents)\n\n\u003chr /\u003e\n\n## Step 2: Create a server \"main\" file and tsconfig to build it\n\nCreate a main file for your Universal bundle. This file only needs to export your `AppServerModule`. It can go in `src`. This example calls this file `main.server.ts`:\n\n### src/main.server.ts:\n\n```typescript\nimport { enableProdMode } from '@angular/core';\n\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n    enableProdMode();\n}\n\nexport { AppServerModule } from './app/app.server.module';\n\nexport { NgUniversalModule } from '@hapiness/ng-universal';\n```\n\nCopy `tsconfig.app.json` to `tsconfig.server.json` and change it to build with a `\"module\"` target of `\"commonjs\"`.\n\nAdd a section for `\"angularCompilerOptions\"` and set `\"entryModule\"` to your `AppServerModule`, specified as a path to the import with a hash (`#`) containing the symbol name. In this example, this would be `src/app/app.server.module#AppServerModule`.\n\n### src/tsconfig.server.json:\n\n```\n{\n    \"extends\": \"./tsconfig.json\",\n    \"compilerOptions\": {\n        \"outDir\": \"./out-tsc/app\",\n        \"baseUrl\": \"./\",\n        \"module\": \"commonjs\",\n        \"types\": []\n    },\n    \"include\": [\n        \"src/**/*.ts\"\n    ],\n    \"exclude\": [\n        \"test.ts\",\n        \"**/*.spec.ts\"\n    ],\n    \"angularCompilerOptions\": {\n        \"entryModule\": \"src/app/app.server.module#AppServerModule\"\n    }\n}\n```\n\n[back to top](#table-of-contents)\n\n\u003chr /\u003e\n\n## Step 3: Create a new target in `angular.json`\n\nIn `angular.json` locate the **architect** property inside your project, and add a new **server target**.\n\nIn **build target**, adapt `options.outputPath` to `dist/browser`.\n\n### angular.json:\n\n```\n{\n  ...\n  \"architect\": {\n    \"build\": {\n      \"builder\": \"@angular-devkit/build-angular:browser\",\n      \"options: {\n        \"outputPath\": \"dist/browser\",\n        ...\n      },\n      ...\n    }\n    \"server\": {\n        \"builder\": \"@angular-devkit/build-angular:server\",\n        \"options\": {\n            \"outputPath\": \"dist/server\",\n            \"main\": \"src/main.server.ts\",\n            \"tsConfig\": \"tsconfig.server.json\"\n        },\n        \"configurations\": {\n            \"production\": {\n                \"fileReplacements\": [\n                    {\n                        \"replace\": \"src/environments/environment.ts\",\n                        \"with\": \"src/environments/environment.prod.ts\"\n                    }\n                ]\n            }\n        }\n    }\n  }\n  ...\n}\n```\n\n### Building the bundle:\n\nWith these steps complete, you should be able to build a server bundle for your application:\n\n```bash\n# This builds the client application in dist/browser/\n$ ng build --prod\n...\n# This builds the server bundle in dist/server/\n$ ng run your-project-name:server\n\n# outputs:\nDate: 2017-10-21T21:54:49.240Z                                                       \nHash: 3034f2772435757f234a\nTime: 3689ms\nchunk {0} main.js (main) 9.2 kB [entry] [rendered]\nchunk {1} styles.css (styles) 0 bytes [entry] [rendered]\n```\n\n[back to top](#table-of-contents)\n\n\u003chr /\u003e\n\n## Step 4: Setting up a Hapiness Application to run our Universal bundles\n\nNow that we have everything set up to -make- the bundles, how we get everything running?\n\nWe'll use Hapiness application and `@hapiness/ng-universal` module.\n\nBelow we can see a TypeScript implementation of a -very- simple Hapiness application to fire everything up.\n\n\u003e **Note:**\n\u003e\n\u003e This is a very bare bones Hapiness application, and is just for demonstrations sake.\n\u003e\n\u003e In a real production environment, you'd want to make sure you have other authentication and security things setup here as well.\n\u003e\n\u003e This is just meant just to show the specific things needed that are relevant to Universal itself. The rest is up to you!\n\nAt the ROOT level of your project (where package.json / etc are), created a file named: `server.ts`\n\n### server.ts (root project level):\n\n```typescript\n// This is important and needed before anything else\nimport 'zone.js/dist/zone-node';\n\nimport { Hapiness, Module } from '@hapiness/core';\nimport { HttpServer, HttpServerConfig } from '@hapiness/core/httpserver';\nimport { join } from 'path';\n\nconst BROWSER_FOLDER = join(process.cwd(), 'dist', 'browser');\n\n// * NOTE :: leave this as require() since this file is built Dynamically from webpack\nconst { AppServerModuleNgFactory, LAZY_MODULE_MAP, NgUniversalModule} = require('./dist/server/main');\n\n// Create our Hapiness application\n@Module({\n    version: '1.0.0',\n    imports: [\n        NgUniversalModule.setConfig({\n            bootstrap: AppServerModuleNgFactory,\n            lazyModuleMap: LAZY_MODULE_MAP,\n            staticContent: {\n                indexFile: 'index.html',\n                rootPath: BROWSER_FOLDER\n            }\n        })\n    ]\n})\nclass HapinessApplication {\n    /**\n     * OnStart process\n     */\n    onStart(): void {\n        console.log(`SSR application is running`);\n    }\n\n    /**\n     * OnError process\n     */\n    onError(error: Error): void {\n        console.error(error);\n    }\n}\n\n\n// Boostrap Hapiness application\nHapiness.bootstrap(HapinessApplication, [\n    HttpServer.setConfig\u003cHttpServerConfig\u003e({\n        host: '0.0.0.0',\n        port: 4000\n    })\n]);\n```\n\n### Extra Providers:\n\nExtra Providers can be provided either on engine setup\n\n```typescript\nNgUniversalModule.setConfig({\n  bootstrap: AppServerModuleNgFactory,\n  lazyModuleMap: LAZY_MODULE_MAP,\n  staticContent: {\n    indexFile: 'index.html',\n    rootPath: BROWSER_FOLDER\n  },\n  providers: [\n      ServerService\n  ]\n})\n```\n\n### Using the Request, Reply and Utils:\n\nThe `Request`, `Reply` and `Utils` objects are injected into the app via injection tokens (`REQUEST`, `REPLY` and `UTILS`). You can access them by `@Inject`\n\n```typescript\nimport { Inject, Injectable } from '@angular/core';\nimport { HttpServerRequest, REQUEST } from '@hapiness/ng-universal';\n\n@Injectable()\nexport class RequestService {\n  constructor(@Inject(REQUEST) private _request: HttpServerRequest) {}\n}\n```\n\nIf your app runs on the `client` side too, you will have to provide your own versions of these in the client app.\n\n- `REQUEST` token will inject `HttpServerRequest` the current instance of [Fastify Request](https://www.fastify.io/docs/latest/Request/).\n- `REPLY` token will inject `HttpServerReply` current instance provides:\n    - `header(key: string, value: string): HttpServerReply` method to add `new header` in `SSR` response\n    - `redirect(url: string): HttpServerReply` method to `redirect` the response with a `302` to the given `URL`.\n- `UTILS` token will inject `HttpUtils` current instance provides:\n    - `parseCookie(str: string, options?: any)` method which is the same of original `cookie` [library](https://github.com/jshttp/cookie#cookieparsestr-options).\n    - `serializeCookie(name: string, value: string, options?: any)` method which is the same of original `cookie` [library](https://github.com/jshttp/cookie#cookieparsestr-options).\n\n[back to top](#table-of-contents)\n\n\u003chr /\u003e\n\n## Step 5: Setup a webpack config to handle this Node server.ts file and serve your application!\n\nNow that we have our Hapiness application setup, we need to pack it and serve it!\n\nCreate a file named `webpack.server.config.js` at the ROOT of your application.\n\n\u003e This file basically takes that `server.ts` file, and takes it and compiles it and every dependency it has into `dist/server.js`.\n\n### ./webpack.server.config.js (root project level):\n\n```javascript\nconst path = require('path');\nconst webpack = require('webpack');\n\nmodule.exports = {\n    mode: 'none',\n    entry: { server: './server.ts' },\n    target: 'node',\n    resolve: {\n        extensions: [ '.ts', '.js' ]\n    },\n    optimization: {\n        minimize: false\n    },\n    output: {\n        path: path.join(__dirname, 'dist'),\n        filename: '[name].js',\n        libraryTarget: \"commonjs\"\n    },\n    module: {\n        noParse: /polyfills-.*\\.js/,\n        rules: [\n            { test: /\\.ts$/, loader: 'ts-loader' },\n            {\n                // Mark files inside `@angular/core` as using SystemJS style dynamic imports.\n                // Removing this will cause deprecation warnings to appear.\n                test: /(\\\\|\\/)@angular(\\\\|\\/)core(\\\\|\\/).+\\.js$/,\n                parser: { system: true },\n            }\n        ]\n    },\n    plugins: [\n        // Temporary Fix for issue: https://github.com/angular/angular/issues/11580\n        // for \"WARNING Critical dependency: the request of a dependency is an expression\"\n        new webpack.ContextReplacementPlugin(\n            /(.+)?angular(\\\\|\\/)core(.+)?/,\n            path.join(__dirname, 'src'), // location of your src\n            {} // a map of your routes\n        ),\n        new webpack.ContextReplacementPlugin(\n            /(.+)?hapiness(\\\\|\\/)(.+)?/,\n            path.join(__dirname, 'src'),\n            {}\n        )\n    ],\n    stats: {\n        warnings: false\n    }\n};\n```\n\nYou can add this config if you want to use `@hapiness/config` to have server config in `./config/default.yml` instead of static data:\n\n```javascript\nexternals: [\n    {\n        // This is the only module you have to install with npm in your final packaging\n        // npm i config\n        config: {\n            commonjs: 'config',\n            root: 'config'\n        }\n    }\n]\n```\n\nAnd replace the `bootstrap` in *./server.ts*\n\n```typescript\nimport { Config } from '@hapiness/config';\n\n// Boostrap Hapiness application\nHapiness.bootstrap(HapinessApplication, [\n    HttpServer.setConfig\u003cHttpServerConfig\u003e(Config.get('server'))\n]);\n```\n\nNow, you can build your server file:\n\n```bash\n$ webpack --config webpack.server.config.js --progress --colors\n```\n\n#### Almost there:\n\nNow let's see what our resulting structure should look like, if we open up our `/dist/` folder we should see:\n\n```\n/dist/\n  /browser/\n  /server/\n  server.js\n```\n\nTo fire up the application, in your terminal enter\n\n```bash\n$ node dist/server.js\n```\n\nNow lets create a few handy scripts to help us do all of this in the future.\n\n```\n\"scripts\": {\n\n  // These will be your common scripts\n  \"build:dynamic\": \"yarn run build:client-and-server-bundles \u0026\u0026 yarn run webpack:server\",\n  \"serve:dynamic\": \"node dist/server.js\",\n\n  // Helpers for the above scripts\n  \"build:client-and-server-bundles\": \"ng build --prod \u0026\u0026 ng run your-project-name:server:production\",\n  \"webpack:server\": \"webpack --config webpack.server.config.js --progress --colors\"\n}\n```\n\nIn the future when you want to see a Production build of your app with Universal (locally), you can simply run:\n\n```bash\n$ yarn run build:dynamic \u0026\u0026 yarn run serve:dynamic\n```\n\nEnjoy!\n\nOnce again to see a working version of everything, check out the [universal-starter](https://github.com/hapinessjs/ng-universal-example).\n\n\n[back to top](#table-of-contents)\n\n\u003chr /\u003e\n\n## Contributing\n\nTo set up your development environment:\n\n1. clone the repo to your workspace,\n2. in the shell `cd` to the main folder,\n3. hit `npm or yarn install`,\n4. run `npm or yarn run test`.\n    * It will lint the code and execute all tests.\n    * The test coverage report can be viewed from `./coverage/lcov-report/index.html`.\n\n[Back to top](#table-of-contents)\n\n## Change History\n* v8.1.0 (2019-07-04)\n    * `Angular v8.1.0+`\n    * Documentation to allow dynamic import syntax directly to load lazy loaded chunks\n* v8.0.0 (2019-05-31)\n    * `Angular v8.0.0+`\n    * Migrate server to `Hapiness` v2 based on [Fastify](https://www.fastify.io/)\n    * Code refactoring\n    * Adapt tests\n    * Documentation\n* v7.0.0 (2018-10-31)\n    * `Angular v7.0.1+`\n    * Migrate tests to [jest](https://jestjs.io/en/) and [ts-jest](https://kulshekhar.github.io/ts-jest/)\n    * Code refactoring\n    * Documentation\n* v6.2.0 (2018-09-24)\n    * `Angular v6.1.8+`\n    * Latest packages' versions\n    * Install automatically `rxj-compat@6.2.2` to be compatible with all `Hapiness` extensions\n    * Update doc of [webpack.server.config.ts]((#webpackserverconfigjs-root-project-level)) to match with latest version of `Angular Universal` [story](https://github.com/angular/angular-cli/wiki/stories-universal-rendering#webpackserverconfigjs-root-project-level)\n    * Documentation\n* v6.1.0 (2018-07-26)\n    * `Angular v6.1.0+`\n    * Documentation\n* v6.0.1 (2018-05-25)\n    * `Angular v6.0.3+`\n    * `RxJS v6.2.0+`\n    * Documentation\n* v6.0.0 (2018-05-11)\n    * `Angular v6.0.1+`\n    * `RxJS v6.1.0+`\n    * Documentation\n\n[Back to top](#table-of-contents)\n\n## Maintainers\n\n\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd colspan=\"5\" align=\"center\"\u003e\u003ca href=\"https://www.tadaweb.com\"\u003e\u003cimg src=\"http://bit.ly/2xHQkTi\" width=\"117\" alt=\"tadaweb\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Juneil\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/6546204?v=3\u0026s=117\" width=\"117\"/\u003e\u003c/a\u003e\u003c/td\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/reptilbud\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/6841511?v=3\u0026s=117\" width=\"117\"/\u003e\u003c/a\u003e\u003c/td\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/njl07\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/1673977?v=3\u0026s=117\" width=\"117\"/\u003e\u003c/a\u003e\u003c/td\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/sopretty\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/6479712?s=117\u0026v=4\" width=\"117\"/\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Juneil\"\u003eJulien Fauville\u003c/a\u003e\u003c/td\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/reptilbud\"\u003eSébastien Ritz\u003c/a\u003e\u003c/td\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/njl07\"\u003eNicolas Jessel\u003c/a\u003e\u003c/td\u003e\n        \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/sopretty\"\u003eMathieu Jeanmougin\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n[Back to top](#table-of-contents)\n\n## License\n\nCopyright (c) 2018 **Hapiness** Licensed under the [MIT license](https://github.com/hapinessjs/hapiness/blob/master/LICENSE.md).\n\n[Back to top](#table-of-contents)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhapinessjs%2Fng-universal-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhapinessjs%2Fng-universal-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhapinessjs%2Fng-universal-module/lists"}