{"id":37020873,"url":"https://github.com/swaechter/angularj-universal","last_synced_at":"2026-01-14T02:26:31.523Z","repository":{"id":57715650,"uuid":"88739966","full_name":"swaechter/angularj-universal","owner":"swaechter","description":"This project provides an experimental server side render for Spring Boot and Angular 5 based on the J2V8 library","archived":true,"fork":false,"pushed_at":"2020-04-30T06:11:43.000Z","size":2046,"stargazers_count":136,"open_issues_count":5,"forks_count":14,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-07-07T09:03:55.965Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swaechter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-19T12:03:17.000Z","updated_at":"2025-04-03T13:04:05.000Z","dependencies_parsed_at":"2022-09-11T15:30:56.206Z","dependency_job_id":null,"html_url":"https://github.com/swaechter/angularj-universal","commit_stats":null,"previous_names":["swaechter/angularj-ssr"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/swaechter/angularj-universal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaechter%2Fangularj-universal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaechter%2Fangularj-universal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaechter%2Fangularj-universal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaechter%2Fangularj-universal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swaechter","download_url":"https://codeload.github.com/swaechter/angularj-universal/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaechter%2Fangularj-universal/sbom","scorecard":{"id":861470,"data":{"date":"2025-08-11","repo":{"name":"github.com/swaechter/angularj-universal","commit":"3b967f623047b3862c4c3eb49bb67231e76f6329"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/18 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"158 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-c75v-2vq8-878f","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-whgm-jr23-g3j9","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-vc8w-jr9v-vj7f","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-3wcq-x3mq-6r9p","Warn: Project is vulnerable to: GHSA-vh7m-p724-62c2","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-j4f2-536g-r55m","Warn: Project is vulnerable to: GHSA-r7qp-cfhv-p84w","Warn: Project is vulnerable to: GHSA-6h5x-7c5m-7cr7","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q","Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-xf7w-r453-m56c","Warn: Project is vulnerable to: GHSA-vvj3-85vf-fgmw","Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-6x33-pw7p-hmpq","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-pc5p-h8pf-mvwp","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-jg8v-48h5-wgxg","Warn: Project is vulnerable to: GHSA-36fh-84j7-cv5h","Warn: Project is vulnerable to: GHSA-7x7c-qm48-pq9c","Warn: Project is vulnerable to: GHSA-rc3x-jf5g-xvc5","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-779f-wgxg-qr8f","Warn: Project is vulnerable to: GHSA-82v2-mx6x-wq7q","Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-92xj-mqp7-vmcj","Warn: Project is vulnerable to: GHSA-wxgw-qj99-44c2","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-9v62-24cr-58cx","Warn: Project is vulnerable to: GHSA-r8f7-9pfq-mjmv","Warn: Project is vulnerable to: GHSA-jmqm-f2gx-4fjv","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-6fx8-h7jm-663j","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-7mwh-4pqv-wmr8","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-h9rv-jmmf-4pgx","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-fxwf-4rqh-v8g3","Warn: Project is vulnerable to: GHSA-25hc-qcg6-38wj","Warn: Project is vulnerable to: GHSA-xfhh-g9f5-x4m4","Warn: Project is vulnerable to: GHSA-qm95-pgcg-qqfq","Warn: Project is vulnerable to: GHSA-cqmj-92xf-r6r9","Warn: Project is vulnerable to: GHSA-c9g6-9335-x697","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-884p-74jh-xrg2","Warn: Project is vulnerable to: GHSA-j7fq-p9q7-5wfv","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-46c4-8wrp-j99v","Warn: Project is vulnerable to: GHSA-9m6j-fcg5-2442","Warn: Project is vulnerable to: GHSA-hh27-ffr2-f2jc","Warn: Project is vulnerable to: GHSA-rqff-837h-mm52","Warn: Project is vulnerable to: GHSA-8v38-pw62-9cw2","Warn: Project is vulnerable to: GHSA-hgjh-723h-mx2j","Warn: Project is vulnerable to: GHSA-jf5r-8hm2-f872","Warn: Project is vulnerable to: GHSA-mgfv-m47x-4wqp","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-cf66-xwfp-gvc4","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-4fc4-chg7-h8gh","Warn: Project is vulnerable to: GHSA-g78m-2chm-r7qv","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-776f-qx25-q3cc","Warn: Project is vulnerable to: GHSA-72mh-269x-7mh5","Warn: Project is vulnerable to: GHSA-h4j5-c7cj-74xg","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T01:25:42.713Z","repository_id":57715650,"created_at":"2025-08-24T01:25:42.713Z","updated_at":"2025-08-24T01:25:42.713Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-01-14T02:26:27.853Z","updated_at":"2026-01-14T02:26:31.516Z","avatar_url":"https://github.com/swaechter.png","language":"Java","funding_links":[],"categories":["开发框架"],"sub_categories":["Web框架"],"readme":"# Angular Universal for Java [![Build Status](https://travis-ci.org/swaechter/angularj-universal.svg?branch=master)](https://travis-ci.org/swaechter/angularj-universal)\n\n## Background\n\nWith the introduction of Angular Universal, a solution for dynamically prerendering Angular applications on the server side (SSR) and sending the content directly to the browser as 'already-bootstrapped' application, Angular became more interesting for many developers that were using a Node.js environment. It solved the problems of SEO optimization, empty page previews from Facebooks \u0026 others and resource management (For more information see https://scotch.io/tutorials/server-side-rendering-in-angular-2-with-angular-universal).\n\nFor traditional web developers in the Java enterprise environment with technologies like Spring Boot or Java EE, these technologies required the use of a separate Node.js runtime in combination with a web framework like Express.js or even worse, inter process communication between two servers.\n\nThis project provides a Java API to a local running Node.js instance that is responsible for server side rendering the Angular application. For this, a regular TCP connection (gRPC is planned in the future) is used to exchange the render requests and to receive the rendered pages.\n\nAfter the initial request and response, the browser takes over and the single page application is fully running in the browser (No further server side rendering requests are required until the next F5 page refresh):\n\n[![High Level Overview](https://github.com/swaechter/angularj-universal/blob/master/doc/AngularJ_Universal_HighLevelOverview.png?raw=true)](https://github.com/swaechter/angularj-universal/blob/master/doc/AngularJ_Universal_HighLevelOverview.png?raw=true)\n\n## Overview\n\nThis repository is divided into several modules that all share the same Angular application\n\n| Module name                                   | Content and responsibility                                                                                                                                                                                                                                 |\n| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| angularj-universal-application                | Contains the main Angular application with several pages |\n| angularj-universal-renderer                   | Contains the main render SDK that provides the core functionality and allows a developer to implement an own render solution |\n| angularj-universal-renderer-tcp               | Contains a specific render solution that uses a Node.js instance via a TCP connection for rendering requests  |\n| angularj-universal-renderer-v8                | Contains a specific render solution that uses a Node.js instance via J2V8 language bindings for rendering requests (**Note: This module is obsolete and deprecated - no further development and support!**)  |\n| angularj-universal-example-spring-boot        | Contains a Spring Boot web application that serves the Angular application with the help of a custom written Spring Boot starter (See module bellow)  |\n| angularj-universal-example-spring-boot-simple | Contains a Spring Boot web application that serves the Angular application without the help of the Spring Boot starter. This leads to a more simple example, but a lot more boiler plated code is required. For simplicity, this module is used as example |\n| angularj-universal-example-servlet            | TODO: Provide a servlet example  |\n| angularj-universal-spring-boot-starter        | Custom Spring Boot starter that allows are better integration of a server side rendered application into the Spring Boot ecosystem |\n\n## Getting started\n\n### Phase -1: Foreword\n\nIt is really hard to cover all possible work flows and frameworks, so we are focusing on Spring Boot in this example, but other examples are provided as source code. Please don't hesitate to open a new issue and ask for help with a new framework. With your help we will be able to provide an example for your framework!\n\nIf you want to skip this tutorial, checkout the working example  https://github.com/swaechter/angularj-universal/tree/master/angularj-universal-example-spring-boot-simple\n\n### Phase 0: Overview\n\nThe whole getting started process can be divided into three phases:\n\n1. Create a new Java application with Spring Boot as framework and Maven as build system\n2. Create a new Angular application inside the Java project\n3. Integrate the Angular application into the Java project\n\nAs mentioned, you can adapt these steps for your framework. If you want to skip the tutorial, just take a look at the example in `angularj-universal-example-spring-boot-simple` and the Angular application `angularj-universal-application`.\n\n### Phase 1: Create a new Java project\n\nHead over to `http://start.spring.io/` and create a new Spring Boot project with Maven. It is important to select `Web` and `DevTools` as dependency:\n\n```bash\nhttp://start.spring.io/\n```\n\nDownload and import that Maven project in your favorite Java IDE. In addition, add the AngularJ Universal dependencies:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ech.swaechter\u003c/groupId\u003e\n    \u003cartifactId\u003eangularj-universal-renderer\u003c/artifactId\u003e\n    \u003cversion\u003e0.0.3\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ech.swaechter\u003c/groupId\u003e\n    \u003cartifactId\u003eangularj-universal-renderer-v8\u003c/artifactId\u003e\n    \u003cversion\u003e0.0.3\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nNow that we have a project layout and the required Java dependencies, we can continue with phase 2 and create a new Angular application inside the Java project.\n\n### Phase 2: Create a new Angular application\n\nTo make the integration with Java as smooth as possible, we will stick to the Maven default layout `https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html`. The Angular application will be located in `angularj-universal-example-spring-boot-simple/src/main/angular` and the build output in `angularj-universal-example-spring-boot-simple/src/main/resources`.\n\nInstall the Angular CLI and create a new Angular application:\n\n```bash\nsudo npm install -g @angular/cli\ncd angularj-universal-example-spring-boot-simple/src/main\nng new angular\n```\n\nGenerate the universal component and add all required third party libraries:\n\n```bash\ncd angular\nng generate universal --client-project angular\nnpm install --save @nguniversal/module-map-ngfactory-loader @nguniversal/socket-engine\nnpm install --save-dev webpack-cli ts-loader\nnpm update\n```\n\nThis will create a traditional single page application (SPA) that needs some adjustment and preparations. To enable lazy modules, change the file `src/app/app.server.module.ts` to this:\n\n```typescript\nimport {NgModule} from '@angular/core';\nimport {ServerModule} from '@angular/platform-server';\n\nimport {AppModule} from './app.module';\nimport {AppComponent} from './app.component';\nimport {ModuleMapLoaderModule} from \"@nguniversal/module-map-ngfactory-loader\";\n\n@NgModule({\n    imports: [\n        AppModule,\n        ServerModule,\n        // ModuleMapLoaderModule // Add this line // TODO: Check how to add this line - lazy loading is at the moment not supported!\n    ],\n    bootstrap: [AppComponent],\n})\nexport class AppServerModule {\n}\n```\n\nTo stick with the traditional Maven layout, change the output path of the application (Property `projects.angular.architect.build.options.outputPath`) in `angular.json`;\n\n```json\n\"outputPath\": \"../resources/public\"\n```\n\nAt the moment, the generated server bundle will not be relocatable (The required libraries from `ǹode_modules` are not packaged into the build artifact), hence we have to build a relocatable bundle with webpack. Create the file `webpack.config.js`:\n\n```js\nconst path = require('path');\nconst webpack = require('webpack');\n\nconst UglifyJsPlugin = require('uglifyjs-webpack-plugin');\n\nmodule.exports = {\n    mode: 'development',\n    entry: {server: './server.ts'},\n    resolve: {extensions: ['.js', '.ts']},\n    target: 'node',\n    externals: [/(node_modules|main\\..*\\.js)/],\n    output: {\n        path: path.join(__dirname, '../resources'),\n        filename: '[name].js'\n    },\n    module: {\n        rules: [\n            {test: /\\.ts$/, loader: 'ts-loader'}\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            /(.+)?express(\\\\|\\/)(.+)?/,\n            path.join(__dirname, 'src'),\n            {}\n        ),\n        new UglifyJsPlugin({\n            uglifyOptions: {\n                ecma: 6,\n                compress: false,\n                mangle: false,\n                comments: false\n            }\n        })\n    ]\n};\n```\n\nNow we need to create the Node.js script that allows us to establish a TCP connection between the Java webserver and the Node.js rednering process. For this, create a script called `server.ts` that provides the communication mechanism::\n\n```typescript\nrequire('zone.js/dist/zone-node');\n\nconst socketEngine = require('@nguniversal/socket-engine');\nconst {AppServerModuleNgFactory} = require('./dist/angular-server/main');\n\nconst port: Number = parseInt(process.env.NODEPORT) || 9090;\n\nconsole.log('Going to start the server on port: ' + port);\nsocketEngine.startSocketEngine(AppServerModuleNgFactory, [], 'localhost', port);\n```\n\nThis script will provide a rendering service on port `9090` which we can use from the Java render engine (**Note: Ensure, that this port is local-link only accessible! Not from another system!**).\n\nNow let's update our Node scripts to all three applications at once (Snipped from `package.json`):\n\n```json\n\"scripts\": {\n    \"start\": \"npm run build\",\n    \"build\": \"ng build --prod \u0026\u0026 ng run angular:server \u0026\u0026 webpack --config webpack.config.js\"\n},\n```\n\nNow run `npm start` or `npm run build` and the traditional client side SPA application will land in `angularj-universal-example-spring-boot-simple/src/main/resources/public`, the publicly accessible part of our web server. In addition, the relocatable server side bundle that will be loaded by the Java JVM can be found in `angularj-universal-example-spring-boot-simple/src/main/resources/server.js`, the not publicly accessible part of our web server (Only the subdirectory `public` is).\n\nWe can continue with the third phase and integrate the Angular application into the Java application and automate the NPM build (Because In cause you don't execute it, your application will fail).\n\n### Phase 3: Integrate the Angular application into the Java project\n\nNow we switch back to the Java part and create a web application with a controller and a service that is going to render our application.\n\nCreate a new Java class file `angularj-universal-example-spring-boot-simple/src/main/java/ch/swaechter/angularjuniversal/example/springboot/simple/DemoApplication.java` with the following content bellow:\n\n__Note 1:__ In this example we only provide the `/` route, but the example in `angularj-universal-application` has several pages and hence routes (Home, keywords, about etc.). For every Angular route you have to define an own route in Spring Boot\n\n__Note 2:__ To avoid such manual and duplicated routes, check out the Spring Boot starter example in `angularj-universal-example-spring-boot`. In the starter example, you can define all routes via the `application.properties` and don't have to define any `ModelAndView` at all.\n\n\n```java\npackage ch.swaechter.angularjuniversal.example.springboot.simple;\n\nimport ch.swaechter.angularjuniversal.renderer.Renderer;\nimport ch.swaechter.angularjuniversal.renderer.configuration.RenderConfiguration;\nimport ch.swaechter.angularjuniversal.renderer.engine.RenderEngineFactory;\nimport ch.swaechter.angularjuniversal.renderer.utils.RenderUtils;\nimport ch.swaechter.angularjuniversal.v8renderer.V8RenderEngineFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.stereotype.Service;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.ResponseBody;\nimport org.springframework.web.bind.annotation.RestController;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.concurrent.Future;\n\n@SpringBootApplication\npublic class WebApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(WebApplication.class, args);\n    }\n\n    @RestController\n    public class ContentController {\n\n        private final RenderService renderservice;\n\n        @Autowired\n        public ContentController(RenderService renderservice) {\n            this.renderservice = renderservice;\n        }\n\n        @ResponseBody\n        @GetMapping(\"/\")\n        public String showIndex() throws Exception {\n            return renderservice.renderPage(\"/\").get();\n        }\n\n        // Note: For every Angular route you have to provide a Java Spring Boot route - or just provide a wildcard route\n    }\n\n    @Service\n    public class RenderService {\n\n        private final Renderer renderer;\n\n        public RenderService() throws IOException {\n            // Load the template and create a temporary server bundle file from the resource (This file will of course never change until manually edited)\n            InputStream templateInputStream = getClass().getResourceAsStream(\"/public/index.html\");\n            InputStream serverBundleInputStream = getClass().getResourceAsStream(\"/server.js\");\n            String templateContent = RenderUtils.getStringFromInputStream(templateInputStream, StandardCharsets.UTF_8);\n            File serverBundleFile = RenderUtils.createTemporaryFileFromInputStream(\"serverbundle\", \"tmp\", serverBundleInputStream);\n            // File serverBundleFile = new File(\"\u003cLocal server bundle on the file system\u003e\"); --\u003e Also enable auto reload in the configuration\n\n            // Create the configuration. For real live reloading, don't use a temporary file but the real generated on from the file system\n            // The string \"node\" is the path or executable name of the Node.js process and has to match/be found\n            RenderConfiguration renderConfiguration = new RenderConfiguration.RenderConfigurationBuilder(\"node\", 9090, serverBundleFile, templateContent).liveReload(false).build();\n\n            // Create the TCP render engine factory for spawning render engines\n            RenderEngineFactory renderEngineFactory = new TcpRenderEngineFactory();\n\n            // Create and start the renderer\n            this.renderer = new Renderer(renderConfiguration, renderEngineFactory);\n            this.renderer.startRenderer();\n        }\n\n        Future\u003cString\u003e renderPage(String uri) {\n            // Render a request and return a resolvable future\n            return renderer.addRenderRequest(uri);\n        }\n    }\n}\n```\n\nNow start the Spring Boot application and head to the URL:\n\n```bash\nhttp://localhost:8080\n```\n\nYou can test if the server side rendering is working if:\n\n* You see the page in general\n* You disable JavaScript temporary, reload and still see the page\n* You inspect the source code of the current page and see the rendered page (Not only the content of the index.html file)\n\n### Final notes\n\nBe aware of these information:\n\n* You have to build the Angular application with `npm run build`, otherwise the AngularJ Universal won't find the index template and relocatable server bundle and will fail. In case you want to integrate this into your regular Maven build, take a look at the Maven NPM/Node plugin `eirslett/frontend-maven-plugin` or just take a look at the usage in `angularj-universal-application/pom.xml`\n* If you rebuild your Angular application you have to restart/reload the web application by default. You can avoid this problem if you use the the server bundle from the file system in the `RenderConfiguration` and enable the reload flag\n* All examples use the Angular application in `angularj-universal-application` to avoid duplication of Angular applications. Just be aware of these fact in case you are reading the source code and asking yourself where the application is. In case you want to use the examples for your own project, just copy away the example and integrate the `angularj-universal-application` content and adjust the `pom.xml`\n\n## Issues and Questions\n\nIf you encounter a problem/bug or something isn't documented well enough, feel free to create an issue in the issue tracker (https://github.com/swaechter/angularj-universal/issues) or send me a mail (waechter.simon@gmail.com)\n\n## Credits\n\nThis project was heavily influenced by many other projects (A huge thank you to the authors):\n\n* https://github.com/bennylut/hello-angular2-universal-j2v8 for providing an Angular 2 example that shows how the J2V8 library and Node.js can be used to render pages\n* https://github.com/blacksonic/angular2-aot-cli-webpack-plugin for providing an example of a relocatable webpack bundle\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaechter%2Fangularj-universal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswaechter%2Fangularj-universal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaechter%2Fangularj-universal/lists"}