 {"id":514,"date":"2021-04-06T22:50:19","date_gmt":"2021-04-07T05:50:19","guid":{"rendered":"https:\/\/www.mavice.com\/blog\/?p=514"},"modified":"2023-02-16T18:18:23","modified_gmt":"2023-02-17T02:18:23","slug":"integrate-a-spa","status":"publish","type":"post","link":"https:\/\/www.mavice.com\/blog\/integrate-a-spa\/","title":{"rendered":"Integrate a SPA"},"content":{"rendered":"\n<p><em>*This article was modeled from the current Adobe React SPA&nbsp;<a href=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/spa-react-tutorial\/integrate-spa.html?lang=en\">documentation<\/a>.<\/em><\/p>\n\n\n\n<p>Understand how the source code for a Single Page Application (SPA) written in Vue can be integrated with an Adobe Experience Manager (AEM) Project. Learn to use modern front-end tools, like a webpack dev server, to rapidly develop the SPA against the AEM JSON model API.<\/p>\n\n\n\n<h2 id=\"objective\">Objective<\/h2>\n\n\n\n<ol><li>Understand how the SPA project is integrated with AEM with client-side libraries.<\/li><li>Learn how to use a webpack development server for dedicated front-end development.<\/li><li>Explore the use of a&nbsp;<strong>proxy<\/strong>&nbsp;and static&nbsp;<strong>mock<\/strong>&nbsp;file for developing against the AEM JSON model API<\/li><\/ol>\n\n\n\n<h2 id=\"what-you-will-build\">What you will build<\/h2>\n\n\n\n<p>This chapter will add a simple&nbsp;<code>Header<\/code>&nbsp;component to the SPA. In the process of building out this static&nbsp;<code>Header<\/code>&nbsp;component several approaches to AEM SPA development will be used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"281\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-1024x281.png\" alt=\"\" class=\"wp-image-516\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-1024x281.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-300x82.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-768x211.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-1536x422.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-360x99.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-1040x285.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM-640x176.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-05-at-1.20.56-PM.png 1924w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>The SPA is extended to add a static&nbsp;Header&nbsp;component<br><\/figcaption><\/figure>\n\n\n\n<h2 id=\"prerequisites\">Prerequisites<\/h2>\n\n\n\n<p>Review the required tooling and instructions for setting up a&nbsp;<a href=\"https:\/\/www.mavice.com\/blog\/create-your-first-vue-spa-in-aem\/\">local development environment<\/a>.<\/p>\n\n\n\n<h3 id=\"get-the-code\">Get the code<\/h3>\n\n\n\n<ol><li>Download the starting point for this tutorial via Git:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">$ git clone https:\/\/github.com\/mavicellc\/aem-guides-wknd-spa.git\n$ cd aem-guides-wknd-spa\n$ git checkout Vue\/integrate-spa-start<\/code><\/pre>\n\n\n\n<p><br>2. Deploy the code base to a local AEM instance using Maven:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">$ mvn clean install -PautoInstallSinglePackage<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>3. If using&nbsp;<a href=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/spa-react-tutorial\/overview.html?lang=en#compatibility\">AEM 6.x<\/a>&nbsp;add the&nbsp;<code>classic<\/code>&nbsp;profile:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">$ mvn clean install -PautoInstallSinglePackage -Pclassic<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>You can always view the finished code on&nbsp;<a href=\"https:\/\/github.com\/adobe\/aem-guides-wknd-spa\/tree\/React\/integrate-spa-solution\">GitHub<\/a>&nbsp;or check the code out locally by switching to the branch&nbsp;<code>Vue\/integrate-spa-solution<\/code>.<\/p>\n\n\n\n<h2>Integration approach<\/h2>\n\n\n\n<p>Two modules were created as part of the AEM project:&nbsp;<code>ui.apps<\/code>&nbsp;and&nbsp;<code>ui.frontend<\/code>.<br><br>The&nbsp;<code>ui.frontend<\/code>&nbsp;module is a&nbsp;<a href=\"https:\/\/webpack.js.org\/\">webpack<\/a>&nbsp;project that contains all of the SPA source code. A majority of the SPA development and testing will be done in the webpack project. When a production build is triggered, the SPA is built and compiled using webpack. The compiled artifacts (CSS and Javascript) are copied into the&nbsp;<code>ui.apps<\/code>&nbsp;module which is then deployed to the AEM runtime.<\/p>\n\n\n\n<h3>Inspect the SPA integration<\/h3>\n\n\n\n<p>Next, inspect the&nbsp;<code>ui.frontend<\/code>&nbsp;module to understand the SPA that has been auto-generated by the&nbsp;<a href=\"https:\/\/docs.adobe.com\/content\/help\/en\/experience-manager-core-components\/using\/developing\/archetype\/uifrontend-react.html\">AEM Project archetype<\/a>.<\/p>\n\n\n\n<ol><li>In the IDE of your choice open up the AEM Project for the WKND SPA. <\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"703\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-1024x703.png\" alt=\"\" class=\"wp-image-518\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-1024x703.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-300x206.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-768x527.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-1536x1055.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-2048x1406.png 2048w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-360x247.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-1040x714.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.11.51-AM-640x439.png 640w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>2. Expand and inspect the&nbsp;<code>ui.frontend<\/code>&nbsp;folder. Open the file&nbsp;<code>ui.frontend\/package.json<\/code><\/p>\n\n\n\n<p>3. Under the&nbsp;<code>dependencies<\/code>&nbsp;you should see several related to&nbsp;<code>Vu<\/code>e.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.15.12-AM.png\" alt=\"\" class=\"wp-image-519\" width=\"700\" height=\"172\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.15.12-AM.png 934w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.15.12-AM-300x74.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.15.12-AM-768x189.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.15.12-AM-360x89.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.15.12-AM-640x158.png 640w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<p>The&nbsp;<code>ui.frontend<\/code>&nbsp;is a Vue application based on the <a href=\"https:\/\/cli.vuejs.org\/guide\/creating-a-project.html\">Vue CLI Template<\/a>.<\/p>\n\n\n\n<p>4. There are also two dependencies prefixed with&nbsp;<code>@adobe<\/code>, and one prefixed with @mavice.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"120\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-1024x120.png\" alt=\"\" class=\"wp-image-521\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-1024x120.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-300x35.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-768x90.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-360x42.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-1040x122.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM-640x75.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.17.58-AM.png 1298w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The above modules make up the&nbsp;<a href=\"https:\/\/docs.adobe.com\/content\/help\/en\/experience-manager-65\/developing\/headless\/spas\/spa-blueprint.html\">AEM SPA Editor JS SDK<\/a>&nbsp;and provide the functionality to make it possible to map SPA Components to AEM Components.<\/p>\n\n\n\n<p>5. In the&nbsp;<code>package.json<\/code>&nbsp;file there are three&nbsp;<code>scripts<\/code>&nbsp;defined:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"177\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-1024x177.png\" alt=\"\" class=\"wp-image-522\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-1024x177.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-300x52.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-768x133.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-360x62.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-1040x180.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM-640x111.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.20.20-AM.png 1262w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>These are standard build scripts made&nbsp;available&nbsp;by the Vue CLI.<\/p>\n\n\n\n<p>The only difference is the addition of&nbsp;<code>&amp;&amp; clientlib<\/code>&nbsp;to the&nbsp;<code>build<\/code>&nbsp;script. This extra instruction is responsible for copying the compiled SPA into the&nbsp;<code>ui.apps<\/code>&nbsp;module as a client-side library during a build.<\/p>\n\n\n\n<p>The npm module&nbsp;<a href=\"https:\/\/github.com\/wcm-io-frontend\/aem-clientlib-generator\">aem-clientlib-generator<\/a>&nbsp;is used to facilitate this.<br><\/p>\n\n\n\n<p>6. Inspect the file&nbsp;<code>ui.frontend\/clientlib.config.js<\/code>. This configuration file is used by&nbsp;<a href=\"https:\/\/github.com\/wcm-io-frontend\/aem-clientlib-generator#clientlibconfigjs\">aem-clientlib-generator<\/a>&nbsp;to determine how to generate the client library.<\/p>\n\n\n\n<p>7. Inspect the file&nbsp;<code>ui.frontend\/pom.xml<\/code>. This file transforms the&nbsp;<code>ui.frontend<\/code>&nbsp;folder into a&nbsp;<a href=\"http:\/\/maven.apache.org\/guides\/mini\/guide-multiple-modules.html\">Maven module<\/a>. The&nbsp;<code>pom.xml<\/code>&nbsp;file has been updated to use the&nbsp;<a href=\"https:\/\/github.com\/eirslett\/frontend-maven-plugin\">frontend-maven-plugin<\/a>&nbsp;to&nbsp;<strong>test<\/strong>&nbsp;and&nbsp;<strong>build<\/strong>&nbsp;the SPA during a Maven build.<\/p>\n\n\n\n<p>8. Inspect the file&nbsp;<code>main.<\/code>ts&nbsp;at&nbsp;<code>ui.frontend\/src\/main.ts<\/code>:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"772\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-1024x772.png\" alt=\"\" class=\"wp-image-523\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-1024x772.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-300x226.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-768x579.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-360x271.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-1040x784.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM-640x482.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.23.38-AM.png 1332w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><code>main.ts<\/code>&nbsp;is the entrypoint of the SPA.&nbsp;<code>ModelManager<\/code>&nbsp;is provided by the AEM SPA Editor JS SDK. It is responsible for calling and injecting the&nbsp;<code>pageModel<\/code>&nbsp;(the JSON content) into the application.<\/p>\n\n\n\n<h3>Add a Header component<\/h3>\n\n\n\n<p>Next, add a new component to the SPA and deploy the changes to a local AEM instance.<\/p>\n\n\n\n<ol><li>In the&nbsp;<code>ui.frontend<\/code>&nbsp;module, beneath&nbsp;<code>ui.frontend\/src\/components<\/code>&nbsp;create a new folder named&nbsp;<code>Header<\/code>.<\/li><li>Create a file named&nbsp;<code>Header.<\/code>vue&nbsp;beneath the&nbsp;<code>Header<\/code>&nbsp;folder.<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"673\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-1024x673.png\" alt=\"\" class=\"wp-image-524\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-1024x673.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-300x197.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-768x505.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-1536x1009.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-360x237.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-1040x683.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM-640x421.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.29.20-AM.png 1808w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>3. Populate&nbsp;<code>Header.<\/code>vue&nbsp;with the following:<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"483\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-1024x483.png\" alt=\"\" class=\"wp-image-526\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-1024x483.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-300x141.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-768x362.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-1536x724.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-2048x965.png 2048w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-360x170.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-1040x490.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.31.45-AM-1-640x302.png 640w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>4. Open the file&nbsp;<code>ui.frontend\/src\/App.js<\/code>. This is the application entry-point.<\/p>\n\n\n\n<p>5. Make the following updates to&nbsp;<code>App.ts<\/code>&nbsp;to include the static&nbsp;<code>Header<\/code>:<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"513\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-1024x513.png\" alt=\"\" class=\"wp-image-527\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-1024x513.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-300x150.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-768x385.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-1536x769.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-2048x1026.png 2048w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-360x180.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-1040x521.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.38.01-AM-640x321.png 640w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>6. Open a new terminal and navigate into the&nbsp;<code>ui.frontend<\/code>&nbsp;folder and run the&nbsp;<code>npm run build<\/code>&nbsp;command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">$ npm run build<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"297\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-1024x297.png\" alt=\"\" class=\"wp-image-528\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-1024x297.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-300x87.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-768x223.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-1536x446.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-360x104.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-1040x302.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM-640x186.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.43.53-AM.png 1758w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>7. Navigate to the&nbsp;<code>ui.apps<\/code>&nbsp;folder Beneath&nbsp;<code>ui.apps\/src\/main\/content\/jcr_root\/apps\/wknd-spa-vue\/clientlibs\/clientlib-vue<\/code>&nbsp;you should see the compiled SPA files have been copied from the <code>ui.frontend\/build<\/code>&nbsp;folder.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"606\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-1024x606.png\" alt=\"\" class=\"wp-image-529\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-1024x606.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-300x178.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-768x455.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-360x213.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-1040x615.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM-640x379.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-1.45.37-AM.png 1514w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>8. Return to the terminal and navigate into the&nbsp;<code>ui.apps<\/code>&nbsp;folder. Execute the following Maven command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><code>$ mvn clean install -PautoInstallPackage <\/code><\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"207\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-1024x207.png\" alt=\"\" class=\"wp-image-530\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-1024x207.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-300x61.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-768x155.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-360x73.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-1040x210.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM-640x129.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.03.58-AM.png 1368w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This will deploy the&nbsp;<code>ui.apps<\/code>&nbsp;package to a local running instance of AEM.<\/p>\n\n\n\n<p>9. Open a browser tab and navigate to&nbsp;<a href=\"http:\/\/localhost:4502\/editor.html\/content\/wknd-spa-react\/us\/en\/home.html\">http:\/\/localhost:4502\/editor.html\/content\/wknd-spa-vue\/us\/en\/home.html<\/a>. You should now see the contents of the&nbsp;<code>Header<\/code>&nbsp;component being displayed in the SPA.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"239\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-1024x239.png\" alt=\"\" class=\"wp-image-531\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-1024x239.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-300x70.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-768x180.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-360x84.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-1040x243.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM-640x150.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.05.31-AM.png 1210w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Steps 6-8 are executed automatically when triggering a Maven build from the root of the project (i.e&nbsp;<code>mvn clean install -PautoInstallSinglePackage<\/code>). You should now understand the basics of the integration between the SPA and AEM client-side libraries. Notice that you can still edit and add&nbsp;<code>Text<\/code>&nbsp;components in AEM beneath the static&nbsp;<code>Header<\/code>&nbsp;component.<\/p>\n\n\n\n<h2 id=\"proxy-json\">Webpack Dev Server &#8211; Proxy the JSON API<\/h2>\n\n\n\n<p>As seen in the previous exercises, performing a build and syncing the client library to a local instance of AEM takes a few minutes. This is acceptable for final testing, but is not ideal for the majority of the SPA development.<\/p>\n\n\n\n<p>A&nbsp;<a href=\"https:\/\/webpack.js.org\/configuration\/dev-server\/\">webpack-dev-server<\/a>&nbsp;can be used to rapidly develop the SPA. The SPA is driven by a JSON model generated by AEM. In this exercise the JSON content from a running instance of AEM will be&nbsp;<strong>proxied<\/strong>&nbsp;into the development server.<\/p>\n\n\n\n<ol><li>Return to the IDE and open the file&nbsp;<code>ui.frontend\/package.json<\/code>.<\/li><\/ol>\n\n\n\n<p>Look for a block of code like the following:<br><\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"342\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-1024x342.png\" alt=\"\" class=\"wp-image-532\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-1024x342.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-300x100.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-768x256.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-360x120.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-1040x347.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM-640x214.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.07.51-AM.png 1042w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/cli.vuejs.org\/config\/#devserver\">Vue CLI <\/a>provides an easy mechanism to proxy API requests. All unknown requests will be proxied through&nbsp;<code>localhost:4502<\/code>, the local AEM quickstart.<\/p>\n\n\n\n<p>2. Open a terminal window and navigate to the&nbsp;<code>ui.frontend<\/code>&nbsp;folder. Run the command&nbsp;<code>npm run serve<\/code>:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"641\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-1024x641.png\" alt=\"\" class=\"wp-image-533\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-1024x641.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-300x188.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-768x481.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-360x225.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-1040x651.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM-640x401.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.09.52-AM.png 1418w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>3. Open a new browser tab (if not already opened) and navigate to&nbsp;<a href=\"http:\/\/localhost:8080\/content\/wknd-spa-vue\/us\/en\/home.html\">http:\/\/localhost:8080\/content\/wknd-spa-vue\/us\/en\/home.html<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-1024x427.png\" alt=\"\" class=\"wp-image-534\" width=\"697\" height=\"290\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-1024x427.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-300x125.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-768x320.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-1536x641.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-360x150.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-1040x434.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM-640x267.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.10.45-AM.png 1808w\" sizes=\"(max-width: 697px) 100vw, 697px\" \/><\/figure><\/div>\n\n\n\n<p>You should see the same content as in AEM, but without any of the authoring capabilities enabled.<\/p>\n\n\n\n<p>4. Return to the IDE and create a new folder named&nbsp;<code>media<\/code>&nbsp;at&nbsp;<code>ui.frontend\/src\/media<\/code>.<\/p>\n\n\n\n<p>5. Download and add the following WKND logo to the&nbsp;<code>assets<\/code>&nbsp;folder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><code>import wkndLogoDark from '..\/..\/media\/wknd-logo-dk.png'; <\/code><\/code><\/pre>\n\n\n\n<p><br>6. Make the following updates to&nbsp;<code>Header.js<\/code>&nbsp;to include the logo as part of the header:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"343\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-1024x343.png\" alt=\"\" class=\"wp-image-537\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-1024x343.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-300x101.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-768x258.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-1536x515.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-2048x687.png 2048w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-360x121.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-1040x349.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.20.55-AM-1-640x215.png 640w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Wanna know why we are using &#8216;reqiure&#8217; ? Check this out. <\/em><\/p>\n\n\n\n<p><a href=\"https:\/\/cli.vuejs.org\/guide\/html-and-static-assets.html#relative-path-imports\">https:\/\/cli.vuejs.org\/guide\/html-and-static-assets.html#relative-path-imports<\/a><\/p>\n\n\n\n<p>Next, Save the changes to&nbsp;<code>Header.<\/code>vue.<br><br>Return to the browser at&nbsp;<a href=\"http:\/\/localhost:8080\/content\/wknd-spa-vue\/us\/en\/home.html\">http:\/\/localhost:8080\/content\/wknd-spa-vue\/us\/en\/home.html<\/a>. You should immediately see the changes to the app reflected.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"576\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-1024x576.png\" alt=\"\" class=\"wp-image-538\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-1024x576.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-300x169.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-768x432.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-360x203.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-640x360.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM-1040x585.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-2.24.09-AM.png 1368w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>You can continue to make content updates in AEM and see them reflected in&nbsp;<strong>webpack-dev-server<\/strong>, since we are proxying the content.<\/p>\n\n\n\n<p>9. Stop the webpack dev server with&nbsp;<code>ctrl+c<\/code>&nbsp;in the terminal.<\/p>\n\n\n\n<h2 id=\"mock-json\"><em>Webpack Dev Server &#8211; Mock JSON API (Coming Soon)<\/em><\/h2>\n\n\n\n<p>Mock JSON API Functionality is currently in development.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3>Add Styles with Sass<\/h3>\n\n\n\n<p>This project will use&nbsp;<a href=\"https:\/\/sass-lang.com\/\">Sass<\/a>&nbsp;for a few useful features like variables. Sass is already included when creating the project from the Vue CLI.<\/p>\n\n\n\n<p>Use either the Proxy of Mock approach for handling the JSON model API.<br><br>1. Return to the IDE and beneath&nbsp;<code>ui.frontend\/src<\/code>&nbsp;create a new folder named&nbsp;<code>styles<\/code>.<br><br>2. Create a new file beneath&nbsp;<code>ui.frontend\/src\/styles<\/code>&nbsp;named&nbsp;<code>_variables.scss<\/code>&nbsp;and populate it with the following variables:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><code>\/\/_variables.scss <\/code>\n<code>\/\/== Colors <\/code>\n<code>\/\/ <\/code>\n<code>\/\/## Gray and brand colors for use across theme. <\/code>\n<code>$black:                  #202020; <\/code>\n<code>$gray:                   #696969; <\/code>\n<code>$gray-light:             #EBEBEB; <\/code>\n<code>$gray-lighter:           #F7F7F7; <\/code>\n<code>$white:                  #FFFFFF; <\/code>\n<code>$yellow:                 #FFEA00; <\/code>\n<code>$blue:                   #0045FF; <\/code>\n<code>\/\/== Typography <\/code>\n<code>\/\/ <\/code>\n<code>\/\/## Font, line-height, and color for body text, headings, and more. $font-family-sans-serif:  \"Helvetica Neue\", Helvetica, Arial, sans-serif; <\/code>\n<code>$font-family-serif:       Georgia, \"Times New Roman\", Times, serif; $font-family-base:        $font-family-sans-serif; <\/code>\n<code>$font-size-base:          18px; $line-height-base:        1.5; <\/code>\n<code>$line-height-computed:    floor(($font-size-base * $line-height-base)); <\/code>\n\n<code>\/\/ Functional Colors $brand-primary:             <\/code>\n<code>$yellow; $body-bg:                   <\/code>\n<code>$white; $text-color:                <\/code>\n<code>$black; $text-color-inverse:        <\/code>\n<code>$gray-light; $link-color:                <\/code>\n<code>$blue; \/\/Layout $max-width: 1024px; <\/code>\n\n<code>\/\/ Spacing <\/code>\n<code>$gutter-padding: 12px;<\/code><\/code><\/pre>\n\n\n\n<p><br>3. Replace the contents with the following in App.scss with the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><em>@import <\/em>'.\/styles\/variables';\n\nbody {\n  background-color: $body-bg;\n  font-family: $font-family-base;\n  margin: 0;\n  padding: 0;\n  font-size: $font-size-base;\n  text-align: left;\n  color: $text-color;\n  line-height: $line-height-base;\n}\n\n<em>\/\/spacing for header\n<\/em>body.<em>page <\/em>{\n  padding-top: 75px;\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>4. Replace the &lt;style&gt; tag in Header.vue with the following:<br><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;style <em>lang<\/em>=\"scss\"&gt;<br>  .<em>Header <\/em>{<br>    width: 100%;<br>    position: fixed;<br>    top: 0;<br>    left:0;<br>    z-index: 99;<br>    background-color: $brand-primary;<br>    box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.24);<br>  }<br><br>  .<em>Header-container <\/em>{<br>    display: flex;<br>    max-width: $max-width;<br>    margin: 0 auto;<br>    padding-left: $gutter-padding;<br>    padding-right: $gutter-padding;<br>  }<br><br>  .<em>Logo <\/em>{<br>    z-index: 100;<br>    display: flex;<br>    padding-top: $gutter-padding;<br>    padding-bottom: $gutter-padding;<br>  }<br><br>  .<em>Logo-img <\/em>{<br>    width: 100px;<br>  }<br>&lt;\/style&gt;<\/pre>\n\n\n\n<p>5. Finally, add the _variables.scss to the loaderOptions for SASS within the vue.config.js file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">module.exports = {\n  css: {\n    loaderOptions: {\n      sass: {\n        prependData: `@import \"@\/styles\/_variables.scss\";`\n      }\n    }\n  },\n...\n...<\/pre>\n\n\n\n<p>6. Start the&nbsp;<strong>webpack-dev-server<\/strong> and return to the browse<strong>r<\/strong>:&nbsp;<a href=\"http:\/\/localhost:8080\/content\/wknd-spa-react\/us\/en\/home.html\">http:\/\/localhost:8080\/content\/wknd-spa-<\/a><a href=\"http:\/\/localhost:8080\/content\/wknd-spa-vue\/us\/en\/home.html\">vue<\/a><a href=\"http:\/\/localhost:8080\/content\/wknd-spa-react\/us\/en\/home.html\">\/us\/en\/home.html<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">$ npm run serve<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"868\" height=\"295\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-4.47.09-PM.png\" alt=\"\" class=\"wp-image-542\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-4.47.09-PM.png 868w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-4.47.09-PM-300x102.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-4.47.09-PM-768x261.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-4.47.09-PM-360x122.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-06-at-4.47.09-PM-640x218.png 640w\" sizes=\"(max-width: 868px) 100vw, 868px\" \/><\/figure>\n\n\n\n<p>You should now see the updated styles added to the&nbsp;<code>Header<\/code>&nbsp;component.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3>Deploy SPA updates to AEM<\/h3>\n\n\n\n<p>The changes made to the&nbsp;<code>Header<\/code>&nbsp;are currently only visible through the&nbsp;<strong>webpack-dev-server<\/strong>. Deploy the updated SPA to AEM to see the changes.<br><br>1. Navigate to the root of the project (<code>aem-guides-wknd-spa<\/code>) and deploy the project to AEM using Maven:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">$ cd ..\n$ mvn clean install -PautoInstallSinglePackage<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>2. Navigate to&nbsp;<a href=\"http:\/\/localhost:4502\/editor.html\/content\/wknd-spa-vue\/us\/en\/home.html\">http:\/\/localhost:4502\/editor.html\/content\/wknd-spa-vue\/us\/en\/home.html<\/a>. You should see the updated&nbsp;<code>Header<\/code>&nbsp;with logo and styles applied.<br><\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"434\" src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-1024x434.png\" alt=\"\" class=\"wp-image-543\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-1024x434.png 1024w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-300x127.png 300w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-768x326.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-1536x651.png 1536w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-360x153.png 360w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-1040x441.png 1040w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM-640x271.png 640w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/04\/Screen-Shot-2021-04-07-at-1.33.03-AM.png 1740w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now that the updated SPA is in AEM, authoring can continue.<\/p>\n\n\n\n<h2 id=\"congratulations\">Congratulations!<\/h2>\n\n\n\n<p>Congratulations, you have updated the SPA and explored the integration with AEM! You now know two different approaches for developing the SPA against the AEM JSON model API using a&nbsp;<strong>webpack-dev-server<\/strong>.<\/p>\n\n\n\n<p>You can always view the finished code on&nbsp;<a href=\"https:\/\/github.com\/mavicellc\/aem-guides-wknd-spa\/tree\/Vue\/integrate-spa-solution\">GitHub<\/a>&nbsp;or check the code out locally by switching to the branch&nbsp;<code>Vue\/integrate-spa-solution<\/code>.<\/p>\n\n\n\n<h3 id=\"next-steps\">Next Steps<\/h3>\n\n\n\n<p><a href=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/spa-react-tutorial\/map-components.html?lang=en\">Map SPA components to AEM components<\/a>&nbsp;&#8211; Learn how to map Vue components to Adobe Experience Manager (AEM) components with the AEM SPA Editor JS SDK. Component mapping enables users to make dynamic updates to SPA components within the AEM SPA Editor, similar to traditional AEM authoring.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>*This article was modeled from the current Adobe React SPA&nbsp;documentation. Understand how the source code for a Single Page Application (SPA) written in Vue can be integrated with an Adobe Experience Manager (AEM) Project. Learn to use modern front-end tools, like a webpack dev server, to rapidly develop the SPA&#8230;<\/p>\n","protected":false},"author":2,"featured_media":560,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,36],"tags":[],"_links":{"self":[{"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts\/514"}],"collection":[{"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/comments?post=514"}],"version-history":[{"count":13,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts\/514\/revisions"}],"predecessor-version":[{"id":694,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts\/514\/revisions\/694"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/media\/560"}],"wp:attachment":[{"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/media?parent=514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/categories?post=514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/tags?post=514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}