{"id":2445,"date":"2017-03-07T11:28:02","date_gmt":"2017-03-07T10:28:02","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=2445"},"modified":"2017-03-07T11:28:02","modified_gmt":"2017-03-07T10:28:02","slug":"server-side-rendering-with-angular","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/","title":{"rendered":"Server Side Rendering With Angular"},"content":{"rendered":"<div class=\"article\">\n<blockquote><p>\n<strong>Big thanks<\/strong> to <a href=\"https:\/\/twitter.com\/robwormald\">Rob Wormald<\/a> who provided an <a href=\"https:\/\/github.com\/robwormald\/ng-universal-demo\/\">example that helped me to understand how server side rendering can be used in Angular<\/a>, answered some open questions and took the time to review the article. <strong>Further big thanks<\/strong> to my buddy <a href=\"https:\/\/twitter.com\/hpgrahsl?lang=de\">Hans-Peter Grahsl<\/a> who helped me to improve this article.\n<\/p><\/blockquote>\n<p>Especially for consumer apps, server side prerendering brings back the benefits of classical web sites without forgoing the advantages of modern JavaScript solutions. It leads to faster loading times which in turn may cause higher conversion rates. It also allows for social links with previews of a web site and it might even help with SEO as search engines are dealing with server side rendered content for more than two decades. That being said, search engines like Google are constantly improving when it comes to indexing JavaScript solutions.<\/p>\n<p>Since its first days, Angular is supporting this option. For Version 2 one could use the community project <a href=\"https:\/\/universal.angular.io\/\">Angular Universal<\/a>. As server side rendering is considered a strategic feature for Google's SPA-Flagship, the product team decided to include a refactored version directly into the framework. Beginning with Angular 4, this version is available.<\/p>\n<p>In this article I'm describing the necessary steps to extend an existing Angular 4 application with server side rendering. I'm using a <a href=\"https:\/\/github.com\/webpack\/webpack\">webpack<\/a> configuration which has been generated by means of the <a href=\"https:\/\/cli.angular.io\/\">Angular CLI<\/a>. The <a href=\"https:\/\/github.com\/manfredsteyer\/angular-ssr\">full example<\/a> can be found <a href=\"https:\/\/github.com\/manfredsteyer\/angular-ssr\">here<\/a>.<\/p>\n<blockquote><p>\nServer side rendering brings additional complexity to a solution. Therefore, I would recommend to only use it when in need of its advantages.\n<\/p><\/blockquote>\n<h2>Ejecting the Angular CLI<\/h2>\n<p>If you are using the Angular CLI you have to eject it, to get the possibility to adopt your build process by leveraging webpack:<\/p>\n<pre><code>ng eject\n<\/code><\/pre>\n<blockquote><p>\nMake sure to know about the <a href=\"https:\/\/github.com\/angular\/angular-cli\/wiki\/eject\">consequences<\/a> before ejecting the CLI.\n<\/p><\/blockquote>\n<p>The CLI version I've used for this article did not include the <code>Uglyfy<\/code>-Plugin which removes code webpack marks as unused. In addition to that, it sets the <code>AotPlugin<\/code>'s flag <code>skipCodeGeneration<\/code> to <code>true<\/code> which prevents AOT. In order to enable these options, I've modified the generated <code>webpack.config.js<\/code> as follows:<\/p>\n<pre><code>[...]\n\"plugins\": [\n    [...],\n    new AotPlugin({\n      \"mainPath\": \"src\/main.ts\",\n      \"hostReplacementPaths\": {\n        \"environments\\\\environment.ts\": \"environments\\\\environment.ts\"\n      },\n      \"exclude\": [],\n      \"tsConfigPath\": \"tsconfig.json\",\n\n      \/\/ Set flag to false to allow AOT\n      \"skipCodeGeneration\": false\n    }),\n\n    \/\/ Add UgilyJsPlugin\n    new webpack.optimize.UglifyJsPlugin()\n]\n[...]\n<\/code><\/pre>\n<p>While AOT is not necessary for server side rendering, combining them makes perfect sense since both options positively impact the application's loading time.<\/p>\n<h2>Necessary Packages<\/h2>\n<p>The solution presented here uses <a href=\"https:\/\/nodejs.org\/en\/\">Node.js<\/a> with <a href=\"http:\/\/expressjs.com\/\">Express<\/a> on the server side. Therefore I've downloaded the package <code>express<\/code> together with typings for it (<code>@types\/express<\/code>) as well as <code>@angular\/platform-server<\/code>:<\/p>\n<pre><code>npm i @angular\/platform-server@4.0.0-rc.2 --save\nnpm i express --save\nnpm i @types\/express --save-dev\n<\/code><\/pre>\n<p>One should make sure to get the version of <code>@angular\/platform-server<\/code> that fits to the other used Angular packages. In my case, it was the version <code>4.0.0-rc.2<\/code>.<\/p>\n<h2>Creating a Root Module for Server Side Rendering<\/h2>\n<p>To leverage server side rendering, one needs a root module that includes the new <code>ServerModule<\/code>. According to <a href=\"https:\/\/github.com\/robwormald\/ng-universal-demo\/\">Rob Wormald's example<\/a>, I also included the root module I'm using for rendering within the browser. This allows me to align with the DRY principle without the need to refactor the existing module structure:<\/p>\n<pre><code>\/\/ app.server.module.ts\n\nimport { NgModule } from '@angular\/core';\nimport { ServerModule } from '@angular\/platform-server';\nimport { AppModule } from '.\/app.module';\nimport { AppComponent } from '.\/app.component';\n\n@NgModule({\n  imports: [\n      ServerModule,\n      AppModule\n  ],\n  bootstrap: [\n      AppComponent\n  ],\n  providers: [ ]\n})\nexport class AppServerModule {}\n<\/code><\/pre>\n<p>Furthermore, the client side root module includes the <code>BrowserModule<\/code> by calling its static <code>withServerTransition<\/code> method. This method demands an id for the application in question:<\/p>\n<pre><code>\/\/ app.module.ts\n\n@NgModule({\n    imports: [\n        BrowserModule.withServerTransition({\n            appId: 'demo-app'\n        }),\n        HttpModule,\n        FormsModule,\n        [...]\n    ],\n    [...]\n})\nexport class AppModule {\n}\n<\/code><\/pre>\n<h2>AOT for the server side<\/h2>\n<p>As the CLI and its <code>AotPlugin<\/code> did not support AOT for server side code at the time of writing, the example directly uses the Angular Compiler. To configure it, I've created a copy of the file <code>tsconfig.json<\/code> with the name <code>tsconfig.server.json<\/code>. This file contains the following <code>angularCompilerOptions<\/code>:<\/p>\n<pre><code>\"compilerOptions\": {\n    [...]\n},\n[...]\n\"angularCompilerOptions\": {\n  \"genDir\": \"src\/aot\",\n  \"entryModule\": \".\/src\/app.server.module#AppServerModule\"\n}\n<\/code><\/pre>\n<p>The npm script <code>ngc:server<\/code> within the file <code>package.json<\/code> calls the Angular Compiler:<\/p>\n<pre><code>[...]\n\"scripts\": {\n    [...]\n    \"ngc:server\": \"ngc -p tsconfig.server.json\"\n}\n[...]\n<\/code><\/pre>\n<p>After calling this script (<code>npm run ngc:server<\/code>) the compiler creates the usual additional TypeScript files for the project. Using the <code>AppServerModuleNgFactory<\/code> that has been created for the server side root module <code>AppServerModule<\/code>, the file <code>main.server.ts<\/code> is starting up a node process which takes care of prerendering:<\/p>\n<pre><code>\/\/ main.server.ts\n\/\/ Modified version of equivalent file in \n\/\/ https:\/\/github.com\/robwormald\/ng-universal-demo\/\n\nimport 'zone.js\/dist\/zone-node';\nimport { platformServer, renderModuleFactory } from '@angular\/platform-server';\nimport { enableProdMode } from '@angular\/core';\nimport { AppServerModule } from '.\/app\/app.server.module';\nimport { AppServerModuleNgFactory } from '.\/aot\/src\/app\/app.server.module.ngfactory';\nimport * as express from 'express';\nimport {ngExpressEngine} from '.\/express-engine';\n\nenableProdMode();\n\nconst app = express();\n\napp.engine('html', ngExpressEngine({\n    baseUrl: 'http:\/\/localhost:8000',\n    bootstrap: [AppServerModuleNgFactory],\n}));\n\napp.set('view engine', 'html');\napp.set('views', '.')\n\napp.get('\/', (req, res) =&gt; {\n    res.render('index', {req});\n});\n\napp.get('\/home*', (req, res) =&gt; {\n    res.render('index', {req});\n});\n\napp.get('\/flight-booking*', (req, res) =&gt; {\n    res.render('index', {req});\n});\n\napp.get('\/passenger*', (req, res) =&gt; {\n    res.render('index', {req});\n});\n\napp.get('\/history*', (req, res) =&gt; {\n    res.render('index', {req});\n});\n\napp.use(express.static('.'));\n\napp.listen(8000,() =&gt; {\n    console.log('listening...');\n});\n<\/code><\/pre>\n<p>Please note, that these server side routes not only allow for prerendering specific parts of the Angular application but also return static files, like the bundles used on client side.<\/p>\n<p>This file is a modified version of a similar file in Rob's example. In addition, I took his express engine that kicks in prerendering:<\/p>\n<pre><code>\/\/ express-engine.ts\n\/\/ Taken from https:\/\/github.com\/robwormald\/ng-universal-demo\/\n\nimport { renderModuleFactory } from '@angular\/platform-server';\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst templateCache  = {};\n\nexport function ngExpressEngine(setupOptions){\n\n    return function(filePath, options, callback){\n        if(!templateCache[filePath]){\n            let file = fs.readFileSync(filePath);\n            templateCache[filePath] = file.toString();\n        }\n        renderModuleFactory(setupOptions.bootstrap[0], {\n            document: templateCache[filePath],\n            url: options.req.url\n        })\n        .then(string =&gt; {\n            callback(null, string);\n        });\n    }\n}\n<\/code><\/pre>\n<h2>Webpack configuration for server side rendering<\/h2>\n<p>To build the server side version, the example uses a copy of the existing <code>webpack.config.js<\/code> with the name <code>webpack.server.js<\/code>. Of course, in a real world project it would be a good idea to avoid a duplication of (configuration) code but for this demonstration it seems to be ok.<\/p>\n<p>This configuration uses the target <code>node<\/code> in order to get a bundle for the server side and just one entry point:<\/p>\n<pre><code>  \/\/ main.server.ts\n\n  [...]\n  target: 'node',\n  [...]\n  \"entry\": {\n    \"main\": [\n      \".\/src\/main.server.ts\"\n    ]\n  },\n<\/code><\/pre>\n<p>As the solution is using just one bundle, I've also removed the two usages of the <code>CommonsChunkPlugin<\/code>. In order to make experimenting easier, I've removed the <code>NoEmitOnErrorsPlugin<\/code>, too.<\/p>\n<p>In order to prevent webpack from overwriting the client side version, the configuration in question uses the name scheme <code>xyz.server.bundle.js<\/code> for the generated bundles:<\/p>\n<pre><code>  \"output\": {\n    \"path\": path.join(process.cwd(), \"dist\"),\n    \"filename\": \"[name].server.bundle.js\",\n    \"chunkFilename\": \"[id].server.chunk.js\"\n  },\n<\/code><\/pre>\n<p>To prevent some issues the solution leverages the <code>AotPlugin<\/code> in addition to directly using the Angular Compiler:<\/p>\n<pre><code>new AotPlugin({\n  \"entryModule\": __dirname + \"\/src\/app\/app.server.module.ts#AppServerModule\",\n  \"hostReplacementPaths\": {\n    \"environments\\\\environment.ts\": \"environments\\\\environment.ts\"\n  },\n  \"exclude\": [],\n  \"tsConfigPath\": \".\/tsconfig.server.json\",\n  \"skipCodeGeneration\": false\n}),\n<\/code><\/pre>\n<h2>Build scripts<\/h2>\n<p>For creating a build which involves using the Angular Compiler and starting webpack, the example uses some npm scripts within the file <code>package.json<\/code>:<\/p>\n<pre><code>\"scripts\": {\n    [...]\n    \"build\": \"npm run build:client\",\n    \"build:client\": \"webpack\",\n    \"build:server\": \"ngc -p tsconfig.server.json &amp;&amp; webpack --progress --config webpack.server.config.js\",\n    \"build:all\": \"npm run build:client &amp;&amp; npm run build:server\",\n    [...]\n}\n<\/code><\/pre>\n<p>After defining these scripts, one can call <code>npm run build:all<\/code> to build the application for both, the client side as well as the server side.<\/p>\n<h2>Starting<\/h2>\n<p>After building the application, one can switch to the <code>dist<\/code> folder and start the server.<\/p>\n<pre><code>cd dist\nnode main.server.bundle.js\n<\/code><\/pre>\n<p>This makes the application available via <code>http:\/\/localhost:8000<\/code>. The server prerenders the requested view. To follow that, just temporarily turn off JavaScript and see that you can at least navigate through the menu items (forms don't work without JavaScript). In addition to server side prerendering, Angular kicks in on client side after it has been loaded.<\/p>\n<h2>Further Thoughts<\/h2>\n<p>There are two more things, I've discussed with <a href=\"https:\/\/twitter.com\/robwormald\">Rob Wormald<\/a>. The first one is about transmitting the server side state to the client. Especially if the server fetches data from a Web API, it would come in handy to directly transfer the resulting state to the client. This prevents the client code from fetching the very same data once again, right after it kicks in. Rob suggest the usage of something like a Redux Store (see <a href=\"https:\/\/github.com\/ngrx\/store\">ngrx\/Store<\/a>) which can be easily transferred as a JSON-based \"data island\" to the client. For sure, these thoughts are worth their own article.<\/p>\n<p>The second part of our conversation was about the \"uncanny valley\" which is the time between receiving the prerendered view from the server and the moment the client side code kicks in. When the latter one happens, the application state is reset which also affects data the user has entered into forms so far. The solution in Angular 4 doesn't prevent this and we agreed that such an undertaking is quite challenging. Therefore, it seems to be a good idea to go with use case specific solutions for this. This can involve writing the application in a way that prevents such situations as well as leveraging your own or community based solutions which fit the scenario in question.&nbsp;A <a href=\"https:\/\/aerotwist.com\/blog\/when-everything-is-important-nothing-is\/\" target=\"_blank\" rel=\"noopener\">nice idea<\/a> regarding this as well as some very <a href=\"https:\/\/aerotwist.com\/blog\/when-everything-is-important-nothing-is\/\" target=\"_blank\" rel=\"noopener\">interesting performance measurings<\/a> can be found here.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Server Side Rendering With Angular<\/p>\n","protected":false},"author":9,"featured_media":2997,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2445","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-unkategorisiert"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Server Side Rendering With Angular - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Server Side Rendering With Angular - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"Server Side Rendering With Angular\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-07T10:28:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"853\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer, GDE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer, GDE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\"},\"author\":{\"name\":\"Manfred Steyer, GDE\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\"},\"headline\":\"Server Side Rendering With Angular\",\"datePublished\":\"2017-03-07T10:28:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\"},\"wordCount\":1154,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"articleSection\":[\"Unkategorisiert\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\",\"name\":\"Server Side Rendering With Angular - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"datePublished\":\"2017-03-07T10:28:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg\",\"width\":1280,\"height\":853},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Server Side Rendering With Angular\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\",\"name\":\"Manfred Steyer, GDE\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer, GDE\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Server Side Rendering With Angular - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/","og_locale":"en_US","og_type":"article","og_title":"Server Side Rendering With Angular - ANGULARarchitects","og_description":"Server Side Rendering With Angular","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/","og_site_name":"ANGULARarchitects","article_published_time":"2017-03-07T10:28:02+00:00","og_image":[{"width":1280,"height":853,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer, GDE","twitter_card":"summary_large_image","twitter_creator":"@daniel","twitter_misc":{"Written by":"Manfred Steyer, GDE","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/"},"author":{"name":"Manfred Steyer, GDE","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951"},"headline":"Server Side Rendering With Angular","datePublished":"2017-03-07T10:28:02+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/"},"wordCount":1154,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","articleSection":["Unkategorisiert"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/","name":"Server Side Rendering With Angular - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","datePublished":"2017-03-07T10:28:02+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/blog-2355684-1280.jpg","width":1280,"height":853},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/server-side-rendering-with-angular\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Server Side Rendering With Angular"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951","name":"Manfred Steyer, GDE","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","caption":"Manfred Steyer, GDE"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=2445"}],"version-history":[{"count":0,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2445\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/2997"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=2445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=2445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=2445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}