 {"id":566,"date":"2021-06-29T09:05:40","date_gmt":"2021-06-29T16:05:40","guid":{"rendered":"https:\/\/www.mavice.com\/blog\/?p=566"},"modified":"2021-08-10T11:46:33","modified_gmt":"2021-08-10T18:46:33","slug":"map-spa-components-to-aem-components","status":"publish","type":"post","link":"https:\/\/www.mavice.com\/blog\/map-spa-components-to-aem-components\/","title":{"rendered":"Map SPA components to AEM components"},"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\/getting-started-with-aem-headless\/spa-editor\/react\/map-components.html?lang=en\">documentation<\/a>.<\/em><\/p>\n\n\n\n<p>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\n\n\n<p>This chapter takes a deeper-dive into the AEM JSON model API and how the JSON content exposed by an AEM component can be automatically injected into a Vue component as props.<\/p>\n\n\n\n<h2 id=\"objective\">Objective<\/h2>\n\n\n\n<ol><li>Learn how to map AEM components to SPA Components.<\/li><li>Inspect how a Vue component uses dynamic properties passed from AEM.<\/li><li>Learn how to use out of the box&nbsp;<a href=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-core-components\/using\/introduction.html?lang=en\">AEM Core Components<\/a><\/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 inspect how the provided&nbsp;<code>Text<\/code>&nbsp;SPA component is mapped to the AEM&nbsp;<code>Text<\/code>component. AEM Core Components like the&nbsp;<code>Image<\/code> component will be used in the SPA and authored in AEM. Out of the box features of the&nbsp;<strong>Layout Container<\/strong>&nbsp;and&nbsp;<strong>Template Editor<\/strong>&nbsp;policies will also be used to create a view that is a little more varied in appearance.<\/p>\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>. This chapter is a continuation of the&nbsp;<a href=\"https:\/\/www.mavice.com\/blog\/integrate-a-spa\/\">Integrate the SPA<\/a>&nbsp;chapter, however to follow along all you need is a SPA-enabled AEM project.<\/p>\n\n\n\n<h2 id=\"mapping-approach\">Mapping Approach<\/h2>\n\n\n\n<p>The basic concept is to map a SPA Component to an AEM Component. AEM components, run server-side, export content as part of the JSON model API. The JSON content is consumed by the SPA, running client-side in the browser. A 1:1 mapping between SPA components and an AEM component is created.<br><\/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\/06\/Screen-Shot-2021-06-29-at-11.16.43-AM.png\" alt=\"\" class=\"wp-image-567\" width=\"378\" height=\"402\" srcset=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/06\/Screen-Shot-2021-06-29-at-11.16.43-AM.png 926w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/06\/Screen-Shot-2021-06-29-at-11.16.43-AM-281x300.png 281w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/06\/Screen-Shot-2021-06-29-at-11.16.43-AM-768x819.png 768w, https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/06\/Screen-Shot-2021-06-29-at-11.16.43-AM-640x683.png 640w\" sizes=\"(max-width: 378px) 100vw, 378px\" \/><figcaption><em>High-level overview of mapping an AEM Component to a Vue Component<\/em><br><\/figcaption><\/figure><\/div>\n\n\n\n<h2 id=\"inspect-the-text-component\">Inspect the Text Component<\/h2>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/github.com\/adobe\/aem-project-archetype\">AEM Project Archetype<\/a>&nbsp;provides a&nbsp;<code>Text<\/code>&nbsp;component that is mapped to the AEM&nbsp;<a href=\"https:\/\/docs.adobe.com\/content\/help\/en\/experience-manager-core-components\/using\/components\/text.html\">Text component<\/a>. This is an example of a&nbsp;<strong>content<\/strong>&nbsp;component, in that it renders&nbsp;<em>content<\/em>&nbsp;from AEM.<\/p>\n\n\n\n<p>Let\u2019s see how the component works.<\/p>\n\n\n\n<h3 id=\"inspect-the-json-model\">Inspect the JSON model<\/h3>\n\n\n\n<ol><li>Before jumping into the SPA code, it is important to understand the JSON model that AEM provides. Navigate to the&nbsp;<a href=\"https:\/\/www.aemcomponents.dev\/content\/core-components-examples\/library\/page-authoring\/text.html\">Core Component Library<\/a>&nbsp;and view the page for the Text component. The Core Component Library provides examples of all the AEM Core Components.<\/li><li>Select the&nbsp;<strong>JSON<\/strong>&nbsp;tab for one of the examples:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/text-json.png?lang=en\" alt=\"Text JSON model\">You should see three properties:&nbsp;<code>text<\/code>,&nbsp;<code>richText<\/code>, and&nbsp;<code>:type<\/code>.<code>:type<\/code>&nbsp;is a reserved property that lists the&nbsp;<code>sling:resourceType<\/code>&nbsp;(or path) of the AEM Component. The value of&nbsp;<code>:type<\/code>&nbsp;is what is used to map the AEM component to the SPA component.<code>text<\/code>&nbsp;and&nbsp;<code>richText<\/code>&nbsp;are additional properties that will be exposed to the SPA component.<br><\/li><li>View the JSON output at&nbsp;<a href=\"http:\/\/localhost:4502\/content\/wknd-spa-vue\/us\/en.model.json\">http:\/\/localhost:4502\/content\/wknd-spa-vue\/us\/en.model.json<\/a>. You should be able to find an entry similar to:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><code>\"text\": {    <\/code>\n<code> \"id\": \"text-a647cec03a\",    <\/code>\n<code> \"text\": \"&lt;p&gt;Hello World! Updated content!&lt;\/p&gt;\\r\\n\",     <\/code>\n <code>\"richText\": true,   <\/code>\n<code> \":type\": \"wknd-spa-vue\/components\/text\",  <\/code>\n<code> \"dataLayer\": {}  <\/code>\n<code>}<\/code><\/code><\/pre>\n\n\n\n<h3 id=\"inspect-the-text-spa-component\"><br>Inspect the Text SPA component<\/h3>\n\n\n\n<ol><li>In the IDE of your choice open up the AEM Project for the SPA. Expand the&nbsp;<code>ui.frontend<\/code>&nbsp;module and open the file&nbsp;<code>Text.vue<\/code>&nbsp;under&nbsp;<code>ui.frontend\/src\/components\/Text\/Text.<\/code>vue.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">&lt;template&gt;\n  &lt;div&gt;\n    &lt;div\n      <em>v-if<\/em>=\"richText\"\n      <em>:id<\/em>=\"modelId\"\n      <em>data-rte-editelement\n      v-html<\/em>=\"getRichTextContent()\"\n    &gt;&lt;\/div&gt;\n    &lt;div <em>v-else\n         :id<\/em>=\"modelId\"\n         <em>data-rte-editelement\n         v-html<\/em>=\"text\"&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script&gt;\n<em>import <\/em>DOMPurify <em>from <\/em>'dompurify'\n<em>import <\/em>extractModelId <em>from <\/em>'..\/..\/utils\/extract-model-id'\n\n<em>export default <\/em>{\n  name: 'Text',\n  props: {\n    cqPath: {\n      type: String\n    },\n    richText: {\n      type: Boolean\n    },\n    text: {\n      type: String\n    }\n  },\n  computed: {\n    modelId () {\n      <em>return <\/em>extractModelId(<em>this<\/em>.cqPath)\n    }\n  },\n  methods: {\n    getRichTextContent () {\n      <em>return <\/em>DOMPurify.sanitize(<em>this<\/em>.text)\n    }\n  }\n}\n\n&lt;\/script&gt;\n&lt;style <em>scoped lang<\/em>=\"scss\"&gt;\n&lt;\/style&gt;<\/code><\/pre>\n\n\n\n<p><br>2. <code>Text<\/code>&nbsp;is a standard Vue component. The component uses&nbsp;<code>this.richText<\/code>&nbsp;to determine whether the content to render is going to be rich text or plain text. The actual \u201ccontent\u201d used comes from&nbsp;<code>this.text<\/code>.To avoid a potential XSS attack, the rich text is escaped via&nbsp;<code>DOMPurify<\/code>&nbsp;before using&nbsp;<a href=\"https:\/\/reactjs.org\/docs\/dom-elements.html#dangerouslysetinnerhtml\">dangerouslySetInnerHTML<\/a>&nbsp;to render the content. Recall the&nbsp;<code>richText<\/code>&nbsp;and&nbsp;<code>text<\/code>&nbsp;properties from the JSON model earlier in the exercise.<br><br><\/p>\n\n\n\n<ol start=\"3\"><li>Next take a look at the&nbsp;<code>MapTo<\/code>&nbsp;within map-components.js.<br><\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><em>\/\/ Text Component Mapping\n<\/em>MapTo('wknd-spa-vue\/components\/text')(\n  Text,\n  {\n    emptyLabel: 'Text',\n    isEmpty: <em>function <\/em>(props) {\n      <em>return <\/em>!props || !props.text || props.text.trim().length &lt; 1\n    },\n    resourceType: 'wknd-spa-vue\/components\/text'\n  }\n)<\/code><\/pre>\n\n\n\n<p><br>The above code is responsible for mapping the SPA Text component to the AEM Compoennt and determining when to render the placeholder in the AEM author environment. If the&nbsp;<code>isEmpty<\/code>&nbsp;method returns&nbsp;<strong>true<\/strong>&nbsp;then the placeholder will be rendered.<\/p>\n\n\n\n<p><code>MapTo<\/code>&nbsp;is provided by the AEM SPA Editor JS SDK (<code>@mavice\/aem-vue-editable-components<\/code>). The path&nbsp;<code>wknd-spa-vue\/components\/text<\/code>&nbsp;represents the&nbsp;<code>sling:resourceType<\/code>&nbsp;of the AEM component. This path gets matched with the&nbsp;<code>:type<\/code>&nbsp;exposed by the JSON model observed earlier.&nbsp;<code>MapTo<\/code>&nbsp;takes care of parsing the JSON model response and passing the correct values as&nbsp;<code>props<\/code>&nbsp;to the SPA component.<br><br>You can find the AEM&nbsp;<code>Text<\/code>&nbsp;component definition at&nbsp;<code>ui.apps\/src\/main\/content\/jcr_root\/apps\/wknd-spa-vue\/components\/text<\/code>.<\/p>\n\n\n\n<h2 id=\"use-react-core-components\">Use Vue Core Components<\/h2>\n\n\n\n<ol><li>In the project code open the file&nbsp;<code>map-components.js<\/code>&nbsp;at&nbsp;<code>ui.frontend\/src<\/code>.<br>This file imports all of the SPA components that map to AEM components. Given the dynamic nature of the SPA Editor implementation, we must explicitly reference any SPA components that are tied to AEM author-able components. This allows an AEM author to choose to use a component wherever they want in the application.<\/li><\/ol>\n\n\n\n<ol start=\"2\"><li>The following import statements include SPA components written in the project:<br><\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>import <\/em>Text <em>from <\/em>'.\/components\/Text\/Text'<br><em>import <\/em>Image <em>from <\/em>'.\/component\/Image\/Image'<\/pre>\n\n\n\n<h3 id=\"update-aem-policies\">Update AEM Policies<\/h3>\n\n\n\n<p>Policies are a feature of AEM templates gives developers and power-users granular control over which components are available to be used. The AEM Core Components are included in the SPA Code but need to be enabled via a policy before they can be used in the application.<\/p>\n\n\n\n<ol><li>From the AEM Start screen navigate to&nbsp;<strong>Tools<\/strong>&nbsp;&gt;&nbsp;<strong>Templates<\/strong>&nbsp;&gt;<strong>&nbsp;<a href=\"http:\/\/localhost:4502\/libs\/wcm\/core\/content\/sites\/templates.html\/conf\/wknd-spa-vue\">WKND SPA Vue<\/a><\/strong>.<\/li><li>Select and open the&nbsp;<strong>SPA Page<\/strong>&nbsp;template for editing.<\/li><li>Select the&nbsp;<strong>Layout Container<\/strong>&nbsp;and click it\u2019s&nbsp;<strong>policy<\/strong>&nbsp;icon to edit the policy:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/edit-spa-page-template.png?lang=en\" alt=\"layout container policy\"><\/li><li>Under&nbsp;<strong>Allowed Components<\/strong>&nbsp;&gt;&nbsp;<strong>WKND SPA Vue &#8211; Content<\/strong>&nbsp;&gt; check&nbsp;<strong>Image<\/strong>.<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/update-components-available.png?lang=en\" alt=\"Updated Components available\">Under&nbsp;<strong>Default Components<\/strong>&nbsp;&gt;&nbsp;<strong>Add mapping<\/strong>&nbsp;and choose the&nbsp;<strong>Image &#8211; WKND SPA Vue &#8211; Content<\/strong>&nbsp;component:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/default-components.png?lang=en\" alt=\"Set default components\">Enter a&nbsp;<strong>mime type<\/strong>&nbsp;of&nbsp;<code>image\/*<\/code>.Click&nbsp;<strong>Done<\/strong>&nbsp;to save the policy updates.<\/li><\/ol>\n\n\n\n<ol start=\"5\"><li>In the&nbsp;<strong>Layout Container<\/strong>&nbsp;click the&nbsp;<strong>policy<\/strong>&nbsp;icon for the&nbsp;<strong>Text<\/strong>&nbsp;component. Create a new policy named&nbsp;<strong>WKND SPA Text<\/strong>. Under&nbsp;<strong>Plugins<\/strong>&nbsp;&gt;&nbsp;<strong>Formatting<\/strong>&nbsp;&gt; check all the boxes to enable additional formatting options:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/enable-formatting-rte.png?lang=en\" alt=\"Enable RTE Formatting\">Under&nbsp;<strong>Plugins<\/strong>&nbsp;&gt;&nbsp;<strong>Paragraph Styles<\/strong>&nbsp;&gt; check the box to&nbsp;<strong>Enable paragraph styles<\/strong>:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/text-policy-enable-paragraphstyles_c1.png?lang=en\" alt=\"Enable paragraph styles\">Click&nbsp;<strong>Done<\/strong>&nbsp;to save the policy update.<br><\/li><li>Create an Image component in the components folder and map it to the AEM component within map-components.js<br><\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;template&gt;<br>&lt;img <em>:src<\/em>=\"src\"\/&gt;<br>&lt;\/template&gt;<br><br>&lt;script&gt;<br><em>export <\/em><em>default <\/em>{<br>  name: 'Image',<br>  props: {<br>    src: {<br>      type: String<br>    }<br>  }<br>}<br>&lt;\/script&gt;<br><br>&lt;style <em>scoped<\/em>&gt;<br><br>&lt;\/style&gt;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>\/\/ Image Component Mapping<br><\/em>MapTo('wknd-spa-vue\/components\/image')(<br>  Image,<br>  {<br>    emptyLabel: 'Image',<br>    isEmpty: <em>function <\/em>(props) {<br>      <em>return <\/em>!props || !props.src || props.src.trim().length &lt; 1<br>    },<br>    resourceType: 'wknd-spa-vue\/components\/image'<br>  }<br>)<\/pre>\n\n\n\n<h3 id=\"author-content\"><br>Author Content<\/h3>\n\n\n\n<ol><li>Navigate to the&nbsp;<strong>Homepage<\/strong>&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>.<\/li><li>You should now be able to use the additional components&nbsp;<strong>Image<\/strong>&nbsp;on the page.<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/www.mavice.com\/blog\/wp-content\/uploads\/2021\/06\/Screen-Shot-2021-06-29-at-11.46.19-AM-1024x572.png\" alt=\"This image has an empty alt attribute; its file name is Screen-Shot-2021-06-29-at-11.46.19-AM-1024x572.png\"\/><\/figure>\n\n\n\n<ol start=\"3\"><li>You should also be able to edit the&nbsp;<code>Text<\/code>&nbsp;component and add additional paragraph styles in&nbsp;<strong>full-screen<\/strong>&nbsp;mode.<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/full-screen-rte.png?lang=en\" alt=\"Full Screen Rich Text Editing\"><\/li><li>You should also be able to drag+drop an image from the&nbsp;<strong>Asset finder<\/strong>:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/drag-drop-image.png?lang=en\" alt=\"Drag and Drop image\"><\/li><\/ol>\n\n\n\n<h2 id=\"inspect-the-layout-container\">Inspect the Layout Container<\/h2>\n\n\n\n<p>Support for the&nbsp;<strong>Layout Container<\/strong>&nbsp;is automatically provided by the AEM SPA Editor SDK. The&nbsp;<strong>Layout Container<\/strong>, as indicated by the name, is a&nbsp;<strong>container<\/strong>&nbsp;component. Container components are components that accept JSON structures which represent&nbsp;<em>other<\/em>&nbsp;components and dynamically instantiate them.<\/p>\n\n\n\n<p>Let\u2019s inspect the Layout Container further.<\/p>\n\n\n\n<ol><li>In a browser navigate to&nbsp;<a href=\"http:\/\/localhost:4502\/content\/wknd-spa-vue\/us\/en.model.json\">http:\/\/localhost:4502\/content\/wknd-spa-vue\/us\/en.model.json<\/a><img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/responsive-grid-modeljson.png?lang=en\" alt=\"JSON model API - Responsive Grid\">The&nbsp;<strong>Layout Container<\/strong>&nbsp;component has a&nbsp;<code>sling:resourceType<\/code>&nbsp;of&nbsp;<code>wcm\/foundation\/components\/responsivegrid<\/code>&nbsp;and is recognized by the SPA Editor using the&nbsp;<code>:type<\/code>&nbsp;property, just like the&nbsp;<code>Text<\/code>&nbsp;and&nbsp;<code>Image<\/code>&nbsp;components.The same capabilities of re-sizing a component using&nbsp;<a href=\"https:\/\/docs.adobe.com\/content\/help\/en\/experience-manager-65\/authoring\/siteandpage\/responsive-layout.html#defining-layouts-layout-mode\">Layout Mode<\/a>&nbsp;are available with the SPA Editor.<\/li><li>Return 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>. Add additional&nbsp;<strong>Image<\/strong>&nbsp;components and try re-sizing them using the&nbsp;<strong>Layout<\/strong>&nbsp;option:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/responsive-grid-layout-change.gif?lang=en\" alt=\"Re-size image using Layout mode\"><\/li><li>Re-open the JSON model&nbsp;<a href=\"http:\/\/localhost:4502\/content\/wknd-spa-vue\/us\/en.model.json\">http:\/\/localhost:4502\/content\/wknd-spa-vue\/us\/en.model.json<\/a>&nbsp;and observe the&nbsp;<code>columnClassNames<\/code>&nbsp;as part of the JSON:<img src=\"https:\/\/experienceleague.adobe.com\/docs\/experience-manager-learn\/assets\/responsive-grid-classnames.png?lang=en\" alt=\"Cloumn Class names\">The class name&nbsp;<code>aem-GridColumn--default--4<\/code>&nbsp;indicates the component should be 4 columns wide based on a 12 column grid. More details about the&nbsp;<a href=\"https:\/\/adobe-marketing-cloud.github.io\/aem-responsivegrid\/\">responsive grid can be found here<\/a>.<\/li><li>Return to the IDE and in the&nbsp;<code>ui.apps<\/code>&nbsp;module there is a client-side library defined at&nbsp;<code>ui.apps\/src\/main\/content\/jcr_root\/apps\/wknd-spa-vue\/clientlibs\/clientlib-grid<\/code>. Open the file&nbsp;<code>less\/grid.less<\/code>.This file determines the breakpoints (<code>default<\/code>,&nbsp;<code>tablet<\/code>, and&nbsp;<code>phone<\/code>) used by the&nbsp;<strong>Layout Container<\/strong>. This file is intended to be customized per project specifications. Currently the breakpoints are set to&nbsp;<code>1200px<\/code>&nbsp;and&nbsp;<code>768px<\/code>.<\/li><\/ol>\n\n\n\n<h2 id=\"congratulations\"><br>Congratulations!<\/h2>\n\n\n\n<p>Congratulations, you learned how to map SPA components to AEM Components and you used the AEM Core Components. You also got a chance to explore the responsive capabilities of the&nbsp;<strong>Layout Container<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>*This article was modeled from the current Adobe React SPA&nbsp;documentation. 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&#8230;.<\/p>\n","protected":false},"author":2,"featured_media":618,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,36],"tags":[21,41],"_links":{"self":[{"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts\/566"}],"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=566"}],"version-history":[{"count":3,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts\/566\/revisions"}],"predecessor-version":[{"id":619,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/posts\/566\/revisions\/619"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/media\/618"}],"wp:attachment":[{"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/media?parent=566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/categories?post=566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mavice.com\/blog\/wp-json\/wp\/v2\/tags?post=566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}