{"id":16267,"date":"2017-02-22T12:15:40","date_gmt":"2017-02-22T10:15:40","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=16267"},"modified":"2017-02-21T13:26:14","modified_gmt":"2017-02-21T11:26:14","slug":"taking-mixed-approach-single-page-applications","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/","title":{"rendered":"Taking A Mixed Approach To Single-Page Applications"},"content":{"rendered":"<p>A co-worker came up to me with an interesting situation.<\/p>\n<p>The client he was working with would be building hundreds of single-page applications and all would need to be tied into a single shell application. He had first attempted to use an iFrame contained within another Single-Page Application to display the child applications.<\/p>\n<p>While this worked, he came up against another requirement: the child applications may or may not need access to data from the parent shell application.<\/p>\n<p>It was at this point he came to me for suggestions. I had been playing with this exact idea for sometime; how can you manage a collection of Single-Page Applications and still share data between them?<\/p>\n<p>At this point, I decided to create a hybrid solution of mixing Single-Page Applications with a server-rendered shell application. The following is the process I took for creating this solution. I\u2019ll highlight some of the pain points I ran into while building it out along with some suggestions for further enhancements.<\/p>\n<h2>Step One: Building the Child Single-Page Application<\/h2>\n<p>The first thing I needed to do was to build a child single-page application. The client would be using Angular 1.x, so I found the highly-rated Yeoman generator <a href=\"https:\/\/github.com\/Swiip\/generator-gulp-angular\" target=\"_blank\">generator-gulp-angular<\/a>. This generator was chosen because it uses many best practices for creating an AngularJS 1.x application.<\/p>\n<p>Once the generator runs, you have an application which allows the developer to use Browsersync for live development, the ability to use Gulp to run several types of builds, Bower to manage the front end assets, and has both unit testing and end to end testing built-in.<\/p>\n<p>Running the generator is straightforward and produces a runnable application pretty quickly. I did take the time to clean out many of the default examples items in the application and added in some client-specific features, such as the SASS styles, and a single required feature for example purposes.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication1.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16269\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication1.png\" alt=\"\" width=\"287\" height=\"441\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication1.png 287w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication1-195x300.png 195w\" sizes=\"(max-width: 287px) 100vw, 287px\" \/><\/a><\/p>\n<p>I was impressed at how well the generator followed <a href=\"https:\/\/github.com\/johnpapa\/angular-styleguide\" target=\"_blank\">John Papa\u2019s Angular 1.x style guide<\/a>. I also found that <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=alexandersage.angular1-code-snippets\" target=\"_blank\">VS Code snippets for Angular 1.x<\/a> worked well with the generated code right out of the box. We quickly had a child application developed in just a handful of hours.<\/p>\n<p><strong>angular service example<\/strong><\/p>\n<pre class=\"brush:java\">(function () {\r\n  'use strict';\r\n\r\n  angular\r\n    .module('gulpAngular')\r\n    .service('apiService', Service)\r\n\r\n  \/** @ngInject *\/\r\n  function Service($http) {\r\n\r\n    var getAll = function () {\r\n        return $http.get('data\/users.get.json');\r\n      },\r\n      getById = function (userId) {\r\n        return $http.get('data\/' + userId + '.get.json');\r\n      }\r\n\r\n    return {\r\n      GetAll: getAll,\r\n      GetById: getById\r\n    };\r\n  }\r\n}());<\/pre>\n<p>The single-page application used Gulp for managing all of its build and run tasks. I took advantage of this and was able to build an optimized production version of the application. What happened is that it took all of the SASS files and compiled them down into a single file.<\/p>\n<p>Gulp also condensed all of its vendor-specific files and created one each for the styles and for the scripts. Lastly, Gulp took all of the HTML templates and application-specific scripts and compiled them down also into a single file. The build scripts also created an optimized HTML index file and packaged all of the assets into a distribution folder.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication2.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16270\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication2.png\" alt=\"\" width=\"345\" height=\"359\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication2.png 345w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication2-288x300.png 288w\" sizes=\"(max-width: 345px) 100vw, 345px\" \/><\/a><\/p>\n<p>Okay, step one is completed. We now have a working single-page application that has been optimized for production and is ready to placed into a shell application.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication3.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16271\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication3.png\" width=\"860\" height=\"317\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication3.png 1547w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication3-300x111.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication3-768x283.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication3-1024x377.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<h2>Step Two: The Shell<\/h2>\n<p>So the initial problem was with the integration of the child SPA and the containing shell.<\/p>\n<p>While it\u2019s easy to have hyperlinks just bring up an HTML page in an iFrame, it\u2019s really pretty difficult to have the parent and the iFrame work well together. My thought was, why not have the SPA just be a page in the shell in the first place and avoid the iFrame all together.<\/p>\n<p>I had worked with NodeJS quite a bit at a former client. There, we had actually used the power of templating to render a single-page application which combined a header and footer from external sources. From this experience I felt that it would be easy to integrate additional single-page applications into a larger parent shell application.<\/p>\n<p>I used the <a href=\"http:\/\/expressjs.com\/en\/starter\/generator.html\" target=\"_blank\">default ExpressJS application generator<\/a> to get a simple application up and running. I had chosen Handlebars as my default templating engine during the scaffolding phase because of its similarity to the client-side markup used with AngularJS.<\/p>\n<p>The layout for the shell came from <a href=\"https:\/\/blackrockdigital.github.io\/startbootstrap-sb-admin-2\/pages\/index.html\" target=\"_blank\">startbootstrap.com<\/a> where I used one of the templates that looked fairly close to what was needed by the client.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication4.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16272\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication4.png\" alt=\"\" width=\"263\" height=\"723\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication4.png 263w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication4-109x300.png 109w\" sizes=\"(max-width: 263px) 100vw, 263px\" \/><\/a><\/p>\n<p>A couple of the design decisions that I made was to keep a separation between the single-page applications that will be imported into the shell and any pages which are created with ExpressJS and Handlebars. I did this by breaking out the routes with separate JavaScript files; one for the single-page applications and one for the internal routes which could be used by Express.<\/p>\n<p>I also added a JavaScript file for API calls which might be made. My former client had used Node to marshall quite a bit of the data coming from third-party APIs and I figured this would be a nice example to place in the shell application.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication5.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16273\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication5.png\" alt=\"\" width=\"197\" height=\"117\" \/><\/a><\/p>\n<p>In the view\u2019s folder I broke out the Express <code>partials<\/code> (internal page templates using Handlebars) and where the single-page application pages would live at, the <code>apps<\/code> folder.<\/p>\n<p>Now here is where it gets a little hairy. Since this was a prototype, I went ahead and left it this way since it worked, but it could definitely be enhanced some with some creative Gulp scripting.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication6.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16274\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication6.png\" alt=\"\" width=\"205\" height=\"277\" \/><\/a><\/p>\n<p>Each page in the <code>apps<\/code> folder is essentially the index page of our exported child SPA. But the child SPA wasn\u2019t scripted to live inside of another application, it generated a full HTML page with the head and body tags along with all of the script tags added.<\/p>\n<p><strong>exported index page<\/strong><\/p>\n<pre class=\"brush:xml; wrap-lines:false\">&lt;!doctype html&gt;&lt;html ng-app=gulpAngular&gt;&lt;head&gt;&lt;meta charset=utf-8&gt;&lt;title&gt;KCS - Angular Reference&lt;\/title&gt;&lt;meta name=description content=\"\"&gt;&lt;meta name=viewport content=\"width=device-width\"&gt;&lt;link href=https:\/\/maxcdn.bootstrapcdn.com\/font-awesome\/4.7.0\/css\/font-awesome.min.css rel=stylesheet&gt;&lt;!-- Place favicon.ico and apple-touch-icon.png in the root directory --&gt;&lt;link rel=stylesheet href=styles\/vendor-04c8db0ab4.css&gt;&lt;link rel=stylesheet href=styles\/app-fbcced86b7.css&gt;&lt;\/head&gt;&lt;body&gt;&lt;!--[if lt IE 10]&gt;\r\n      \r\n\r\nYou are using an &lt;strong&gt;outdated&lt;\/strong&gt; browser. Please &lt;a href=\"http:\/\/browsehappy.com\/\"&gt;upgrade your browser&lt;\/a&gt; to improve your experience.\r\n\r\n    &lt;![endif]--&gt;\r\n\r\n&lt;div ui-view&gt;&lt;\/div&gt;\r\n\r\n\r\n&lt;img src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-wp-preserve=\"%3Cscript%20src%3Dscripts%2Fvendor-5b6b3f5db1.js%3E%3C%2Fscript%3E\" data-mce-resize=\"false\" data-mce-placeholder=\"1\" class=\"mce-object\" width=\"20\" height=\"20\" alt=\"&lt;script&gt;\" title=\"&lt;script&gt;\" \/&gt;&lt;img src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-wp-preserve=\"%3Cscript%20src%3Dscripts%2Fapp-9bd529611d.js%3E%3C%2Fscript%3E\" data-mce-resize=\"false\" data-mce-placeholder=\"1\" class=\"mce-object\" width=\"20\" height=\"20\" alt=\"&lt;script&gt;\" title=\"&lt;script&gt;\" \/&gt;&lt;\/body&gt;&lt;\/html&gt;<\/pre>\n<p>Now by default, this won\u2019t \u201cjust work\u201d out of the box. Here are the steps I used to correct this:<\/p>\n<p>I copied the entire exported single-page application folder into the shell\u2019s <code>public<\/code> folder. From here, all of the assets are accessible when a rendered page is sent to the browser.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication7.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16275\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication7.png\" alt=\"\" width=\"300\" height=\"420\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication7.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication7-214x300.png 214w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Next I created a Handlebars template in the <code>apps<\/code> folder and named it the same as the folder found in the <code>public<\/code> folder. I opened up the <code>index.html<\/code> from the <code>public<\/code> folder and I copied only the script tags and the items necessary for Angular to work. Then I pasted those items into the Handlebars template.<\/p>\n<p>Like I said before, we\u2019re making the single-page applications index page here, but we didn\u2019t need the <code>body<\/code> tags and <code>head<\/code> tags. After adjusting the paths of the scripts and styles, I saved that file.<\/p>\n<p><strong>spa handlebars index page<\/strong><\/p>\n<pre class=\"brush:xml; wrap-lines:false\">{{!--&lt;link rel=stylesheet href=\"..\/app_puu\/styles\/vendor-04c8db0ab4.css\" \/&gt;--}}\r\n  &lt;link rel=stylesheet href=\"..\/app_puu\/styles\/app-81ae878e3a.css\" \/&gt;\r\n\r\n  \r\n\r\n&lt;div ng-app=\"gulpAngular\" id=\"inner-app\"&gt;\r\n\r\n&lt;div ui-view&gt;&lt;\/div&gt;\r\n\r\n\r\n  &lt;\/div&gt;\r\n\r\n\r\n \r\n\r\n   &lt;img src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-wp-preserve=\"%3Cscript%20src%3D%22..%2Fapp_puu%2Fscripts%2Fvendor-5b6b3f5db1.js%22%3E%3C%2Fscript%3E\" data-mce-resize=\"false\" data-mce-placeholder=\"1\" class=\"mce-object\" width=\"20\" height=\"20\" alt=\"&lt;script&gt;\" title=\"&lt;script&gt;\" \/&gt;\r\n   &lt;img src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-wp-preserve=\"%3Cscript%20src%3D%22..%2Fapp_puu%2Fscripts%2Fapp-b586be956c.js%22%3E%3C%2Fscript%3E\" data-mce-resize=\"false\" data-mce-placeholder=\"1\" class=\"mce-object\" width=\"20\" height=\"20\" alt=\"&lt;script&gt;\" title=\"&lt;script&gt;\" \/&gt;<\/pre>\n<p>In the <code>routes<\/code> folder, I added the single-page application to the <code>application<\/code> specific route file. Nothing special here, the route is written just like any other in Express.<\/p>\n<p>What we\u2019re given here by the design is the ability to pass data from Node into our single-page application before it is rendered to the browser. At this point we have all the power of having a server-rendered page available for us to use if needed.<\/p>\n<p><strong>spa route added<\/strong><\/p>\n<pre class=\"brush:java\">module.exports = {    \r\n\tregister: function (app) {               \r\n\t\tapp.get('\/puu', function (req, res){                \r\n\t\t\tvar data = {puu: true, title: 'Pricing User Update'};                    \r\n\t\t\tres.render('apps\/puu', data);        \r\n\t\t});    \r\n\t}\r\n};<\/pre>\n<p>Last thing done, opened up the shell\u2019s layout template and added a hyperlink to the navigation. At this point we should be done adding a single-page application to the shell.<\/p>\n<p><strong>hyperlink added to layout page<\/strong><\/p>\n<pre class=\"brush:java\">&lt;ul id=\"demo\" class=\"collapse\"&gt;                               \r\n\t\r\n\r\n&lt;li class=\"{{#if puu}}active{{\/if}}\"&gt;\r\n\t\t&lt;a href=\"\/puu\"&gt;&lt;i class=\"fa fa-user-o fa-fw\" aria-hidden=\"true\"&gt;&lt;\/i&gt;Pricing User Update&lt;\/a&gt; \r\n\t&lt;\/li&gt;\r\n\r\n\r\n                        \r\n&lt;\/ul&gt;<\/pre>\n<h2>Step 3: Does It Work?<\/h2>\n<p>Using the ExpressJS NPM scripts, I fired up the shell and navigated to our localhost instance in the browser. The prototype only has a handful of pages because I wanted to keep it lean for the moment. The landing page and Handlebars pages work exactly as expected.<\/p>\n<p>Opening up the single-page application section, we see our hyperlink for the child SPA that we imported and yes, it does work. The page renders, and the single-page application is displaying data and works as it did in its own development environment.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication8.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16276\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication8.png\" width=\"860\" height=\"259\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication8.png 1894w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication8-300x90.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication8-768x232.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/02\/Singlepageapplication8-1024x309.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<h2>Lessons Learned and Potential Improvements<\/h2>\n<p>So I learned a few things from this prototype that, while not painful, were quite annoying. The child application was developed using a completely different stylesheet setup and when the child and the parent were combined together, the shell\u2019s styles and the SPA\u2019s styles clashed and several things\/styles on both sides were lost. Taking more time to design a site-wide style would probably alleviate this pain point.<\/p>\n<p>Secondly, while it isn\u2019t difficult to manually add code from the generated index page, it can be very error prone. On a review of this application with a fellow developer, we thought that having Gulp script out a Handlebars page from within the SPA\u2019s build step would be helpful to avoid the copying part. And doing additional research we thought that the hyperlink and routing steps could be somewhat more dynamic if the information came from a database.<\/p>\n<p>And while I said that the application pulled data just fine, that\u2019s only after I went and adjusted where the folder containing my static data was located at. Paths from within the SPA are localized to the <code>public<\/code> folder and the layering I had could not be resolved. While this was an issue for the prototype, when real production-ready single-page applications are used, they should be using remote APIs so this would not be as much of an issue.<\/p>\n<h2>Summary<\/h2>\n<p>So the prototype worked as expected. I successfully took a single-page application built 100% outside of the shell application, imported it into the shell and was able to bring it up within the shell at runtime. We avoided the iFrame issues of not being able to talk to the shell. And we gave the entire application the ability to render data both from the server and across sections, as all items were now rendered together.<\/p>\n<p>We inherited a few advantages of being able to secure the SPAs at the server-level by completely blocking a user\u2019s access at runtime. We avoided having a single SPA with hundreds of views and potentially having large memory leaks happen over time by rendering only the necessary single-page application and dropping it out of memory on a navigation change.<\/p>\n<p>All in all, I feel that this was a successful prototype.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/keyholesoftware.com\/2017\/02\/20\/taking-a-mixed-approach-to-single-page-applications\/\">Taking A Mixed Approach To Single-Page Applications<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a>\u00a0Chris Berry at the <a href=\"http:\/\/keyholesoftware.com\/\">Keyhole Software<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all would need to be tied into a single shell application. He had first attempted to use an iFrame contained within another Single-Page Application to display the child applications. While this &hellip;<\/p>\n","protected":false},"author":152,"featured_media":909,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-16267","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular-js"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Taking A Mixed Approach To Single-Page Applications - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all\" \/>\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.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Taking A Mixed Approach To Single-Page Applications - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-02-22T10:15:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Chris Berry\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Chris Berry\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\"},\"author\":{\"name\":\"Chris Berry\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/ccc4ed8f5b57822a38890b90b3933432\"},\"headline\":\"Taking A Mixed Approach To Single-Page Applications\",\"datePublished\":\"2017-02-22T10:15:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\"},\"wordCount\":1677,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"articleSection\":[\"Angular.js\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\",\"name\":\"Taking A Mixed Approach To Single-Page Applications - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"datePublished\":\"2017-02-22T10:15:40+00:00\",\"description\":\"A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaScript\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Angular.js\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/angular-js\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Taking A Mixed Approach To Single-Page Applications\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/ccc4ed8f5b57822a38890b90b3933432\",\"name\":\"Chris Berry\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/efe294b70d517ef4fded0fb5a107eff40750199a5536277a5b4ec8795346f14a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/efe294b70d517ef4fded0fb5a107eff40750199a5536277a5b4ec8795346f14a?s=96&d=mm&r=g\",\"caption\":\"Chris Berry\"},\"description\":\"Chris is a Consultant at Keyhole with a focus on .NET and JavaScript technologies. He likes to dive in and look at the architecture of an application to learn how all of the moving pieces are handled. In the end, he loves to pass along what he's learned and to help people make some good design choices for all aspects of a project.\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/chris-berry\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Taking A Mixed Approach To Single-Page Applications - Web Code Geeks - 2026","description":"A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all","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.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/","og_locale":"en_US","og_type":"article","og_title":"Taking A Mixed Approach To Single-Page Applications - Web Code Geeks - 2026","og_description":"A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all","og_url":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-02-22T10:15:40+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","type":"image\/jpeg"}],"author":"Chris Berry","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Chris Berry","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/"},"author":{"name":"Chris Berry","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/ccc4ed8f5b57822a38890b90b3933432"},"headline":"Taking A Mixed Approach To Single-Page Applications","datePublished":"2017-02-22T10:15:40+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/"},"wordCount":1677,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","articleSection":["Angular.js"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/","url":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/","name":"Taking A Mixed Approach To Single-Page Applications - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","datePublished":"2017-02-22T10:15:40+00:00","description":"A co-worker came up to me with an interesting situation. The client he was working with would be building hundreds of single-page applications and all","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/taking-mixed-approach-single-page-applications\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JavaScript","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/"},{"@type":"ListItem","position":3,"name":"Angular.js","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/angular-js\/"},{"@type":"ListItem","position":4,"name":"Taking A Mixed Approach To Single-Page Applications"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/ccc4ed8f5b57822a38890b90b3933432","name":"Chris Berry","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/efe294b70d517ef4fded0fb5a107eff40750199a5536277a5b4ec8795346f14a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/efe294b70d517ef4fded0fb5a107eff40750199a5536277a5b4ec8795346f14a?s=96&d=mm&r=g","caption":"Chris Berry"},"description":"Chris is a Consultant at Keyhole with a focus on .NET and JavaScript technologies. He likes to dive in and look at the architecture of an application to learn how all of the moving pieces are handled. In the end, he loves to pass along what he's learned and to help people make some good design choices for all aspects of a project.","url":"https:\/\/www.webcodegeeks.com\/author\/chris-berry\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/16267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/152"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=16267"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/16267\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/909"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=16267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=16267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=16267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}