<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Donaldson</title>
    <description>The latest articles on DEV Community by Michael Donaldson (@mike183).</description>
    <link>https://dev.to/mike183</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F602446%2Fb398f48d-6d5d-4a30-945b-6d7c738fcd15.png</url>
      <title>DEV Community: Michael Donaldson</title>
      <link>https://dev.to/mike183</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mike183"/>
    <language>en</language>
    <item>
      <title>Visual Content Previews with Vue Storefront 2</title>
      <dc:creator>Michael Donaldson</dc:creator>
      <pubDate>Wed, 18 Aug 2021 09:55:33 +0000</pubDate>
      <link>https://dev.to/lexascms/visual-content-previews-with-vue-storefront-2-36me</link>
      <guid>https://dev.to/lexascms/visual-content-previews-with-vue-storefront-2-36me</guid>
      <description>&lt;p&gt;In the past couple of articles, I've walked through &lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo"&gt;integrating a headless CMS&lt;/a&gt; and also &lt;a href="https://dev.to/lexascms/implementing-personalised-content-with-vue-storefront-2-f4g"&gt;implementing content personalisation&lt;/a&gt; with Vue Storefront 2.&lt;/p&gt;

&lt;p&gt;In this article, we're going to take things even further and learn how to integrate Vue Storefront 2 with LexasCMS's &lt;a href="https://www.lexascms.com/features/content-previews/"&gt;visual content previews&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Content editors are often left guessing at how content will appear once published. Visual previews are instrumental in removing the need for this guesswork and give content editors the confidence that they need to work efficiently.&lt;/p&gt;

&lt;p&gt;In addition to this, LexasCMS's visual previews integrate deeply with its personalisation and scheduling features, enabling content editors to see exactly how any (past, present or future) content will appear through the eyes of specific visitors.&lt;/p&gt;

&lt;p&gt;Awesome right? Let's take a look at how it works 👇.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial
&lt;/h2&gt;

&lt;p&gt;Just like last time, we're going to be using the store which you created in the previous tutorials as a starting point. If you haven't completed these, don't worry as I'll also provide some instructions to get you caught up 🙂.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;p&gt;As with the previous tutorials, before getting started it's recommended that you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of Vue.js and Nuxt.js&lt;/li&gt;
&lt;li&gt;Node.js v12 or higher installed&lt;/li&gt;
&lt;li&gt;Yarn installed&lt;/li&gt;
&lt;li&gt;A LexasCMS account - &lt;a href="https://app.lexascms.com/signup"&gt;Click here to start a free trial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 0: Getting caught up
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you've already completed the previous tutorials, feel free to skip this section.&lt;/p&gt;

&lt;p&gt;For those of you you haven't, simply follow the steps below to catch up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 0.1: Create a new space on LexasCMS
&lt;/h4&gt;

&lt;p&gt;First you'll need to create a new space in LexasCMS which uses the &lt;strong&gt;E-commerce Tutorial (Vue Storefront)&lt;/strong&gt; template.&lt;/p&gt;

&lt;p&gt;To do this, simply follow Step 1 of the first tutorial &lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo/#step-1-create-a-new-space-on-lexascms"&gt;which you can find here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 0.2: Clone source code for previous tutorial
&lt;/h4&gt;

&lt;p&gt;After creating your space, you can clone the final source code for the previous tutorial by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--branch&lt;/span&gt; part-2-personalisation https://github.com/LexasCMS/tutorial-vsf-next.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 0.3: Install project dependencies
&lt;/h4&gt;

&lt;p&gt;Once you've cloned the source code, navigate into your project directory and install the projects dependencies using the commands below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;tutorial-vsf-next
yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 0.4: Configure your space ID
&lt;/h4&gt;

&lt;p&gt;Open the &lt;code&gt;middleware.config.js&lt;/code&gt; file within your code editor and replace &lt;code&gt;process.env.LEXASCMS_SPACE_ID&lt;/code&gt; within the &lt;code&gt;lexascms&lt;/code&gt; configuration with your actual space ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can find your space ID by navigating into the &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt; section of your space control panel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; module.exports = {
   integrations: {
     // ... 

     lexascms: {
       location: 'vsf-lexascms/server',
       configuration: {
&lt;span class="gd"&gt;-        spaceId: process.env.LEXASCMS_SPACE_ID
&lt;/span&gt;&lt;span class="gi"&gt;+        spaceId: 'YOUR_SPACE_ID'
&lt;/span&gt;       }
     }
   }
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 0.5: Start development server
&lt;/h4&gt;

&lt;p&gt;After your projects dependencies are installed, start your development server using the command shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your development server is up and running, navigate to &lt;a href="http://localhost:3000/"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt; in your web browser and you should see something like the below screenshot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b2iQVume--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rtuz3a2k6ttx5sidk14o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b2iQVume--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rtuz3a2k6ttx5sidk14o.jpg" alt="Development server running screenshot"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  0.6: Setup personalised content (optional)
&lt;/h4&gt;

&lt;p&gt;While optional, we recommend completing &lt;a href="https://dev.to/lexascms/implementing-personalised-content-with-vue-storefront-2-f4g/#step-1-create-new-audience-attribute"&gt;steps 1-4 of the previous tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition to allowing you to gain an understanding of LexasCMS's personalisation features, it will also enable you to experience the full benefits of the visual preview tool later on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Configure your preview URL
&lt;/h3&gt;

&lt;p&gt;The first thing we need to do is configure a preview URL which LexasCMS can use to load your project within its visual preview tool.&lt;/p&gt;

&lt;p&gt;To do this, navigate to the &lt;strong&gt;Settings &amp;gt; Previews&lt;/strong&gt; section of your space, and click on the &lt;strong&gt;Create Preview&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Create a preview with the following attributes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; Local Development &lt;br&gt;
&lt;strong&gt;Preview URL:&lt;/strong&gt; &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a02J1gzr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfhqiv2bbgbjsn3fhprh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a02J1gzr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfhqiv2bbgbjsn3fhprh.jpg" alt="Create preview screenshot"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Create an API key
&lt;/h3&gt;

&lt;p&gt;When retrieving content previews from LexasCMS's Content Delivery API, you must authenticate your requests by providing an API key.&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Settings &amp;gt; API Keys&lt;/strong&gt; section of you space, and click on the &lt;strong&gt;Create an API Key&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Create a new API key named &lt;strong&gt;Local Development&lt;/strong&gt;, being sure to enable the &lt;strong&gt;Content Delivery API (Preview)&lt;/strong&gt; permission as shown in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_0zmFnBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ome4n8uo4rni6xd1qd13.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_0zmFnBD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ome4n8uo4rni6xd1qd13.jpg" alt="Create API key screenshot"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Once the API key has been created, take note of the generated token, as you'll need it later.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Install LexasCMS code snippet
&lt;/h3&gt;

&lt;p&gt;In order for LexasCMS's visual preview tool to function correctly, you must install &lt;a href="https://www.lexascms.com/docs/content-previews/setup/#install-lexascms-code-snippet"&gt;a small code snippet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This code snippet must be embedded on every page and allows your project to communicate with LexasCMS's visual preview tool.&lt;/p&gt;

&lt;p&gt;To install the code snippet, make the following changes to your projects &lt;code&gt;nuxt.config.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; // ...

 export default {
   // ...

   head: {
     // ...

-    script: []
&lt;span class="gi"&gt;+    script: [
+      {
+        hid: 'lexascms',
+        defer: true,
+        innerHTML: '(function(e,t){void 0!==e.addEventListener&amp;amp;&amp;amp;e.addEventListener("load",function(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://static.lexascms.com/lexascms.js",e.parentNode.insertBefore(n,e)},!1)})(window,document)'
+      }
+    ],
+    __dangerouslyDisableSanitizersByTagID: {
+      lexascms: ['innerHTML']
+    }
&lt;/span&gt;   }

   // ...
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Configure API key
&lt;/h3&gt;

&lt;p&gt;Next, in your projects &lt;code&gt;middleware.config.js&lt;/code&gt; file, configure your API key by adding the &lt;code&gt;apiKey&lt;/code&gt; property to your &lt;code&gt;lexascms&lt;/code&gt; configuration as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Be sure to replace &lt;code&gt;YOUR_API_KEY_TOKEN&lt;/code&gt; with the generated token for the API key which you created in step 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; module.exports = {
   integrations: {
     // ... 

     lexascms: {
       location: 'vsf-lexascms/server',
       configuration: {
&lt;span class="gd"&gt;-        spaceId: '...'
&lt;/span&gt;&lt;span class="gi"&gt;+        spaceId: '...',
+.       apiKey: 'YOUR_API_KEY_TOKEN'
&lt;/span&gt;       }
     }
   }
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Update homepage source code
&lt;/h3&gt;

&lt;p&gt;When LexasCMS loads your project within it's visual preview tool, it provides a pre-configured request context via the &lt;code&gt;lexascmsRequestContext&lt;/code&gt; query parameter.&lt;/p&gt;

&lt;p&gt;If you followed the previous tutorial, you'll remember that we used the request context to set the values of our audience attributes when making a request to the Content Delivery API.&lt;/p&gt;

&lt;p&gt;When the &lt;code&gt;lexascmsRequestContext&lt;/code&gt; query parameter is present, we should pass its value as the request context for all requests to LexasCMS, instead of defining our own.&lt;/p&gt;

&lt;p&gt;As an example of how to do this, open the &lt;code&gt;pages/Home.vue&lt;/code&gt; file and update the &lt;code&gt;setup&lt;/code&gt; function to as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; // ...

 setup(_, context) {
   const { content: promoBanners, search } = useContent();

   onSSR(async () =&amp;gt; {
&lt;span class="gi"&gt;+    let requestContext;
+    const { lexascmsRequestContext, localTemp } = context.root.$route.query;
+    if (lexascmsRequestContext !== undefined) {
+      requestContext = lexascmsRequestContext;
+    } else {
+      requestContext = {
+        audienceAttributes: {
+          localTemperature: localTemp ? parseInt(localTemp, 10) : null
+        }
+      };
+    }
+
&lt;/span&gt;     await search({
       type: 'collection',
       contentType: 'promoBanner',
       params: {
         include: 'backgroundImage'
       },
&lt;span class="gd"&gt;-      context: {
-        audienceAttributes: {
-          localTemperature: context.root.$route.query.localTemp ? parseInt(context.root.$route.query.localTemp, 10) : null
-        }
-      }
&lt;/span&gt;&lt;span class="gi"&gt;+      context: requestContext
&lt;/span&gt;     });
   });

   return { promoBanners }
 },

 // ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this change will first check for the existence of the &lt;code&gt;lexascmsRequestContext&lt;/code&gt; query parameter before attempting to build its own request context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Previews in action
&lt;/h3&gt;

&lt;p&gt;After saving your changes, &lt;strong&gt;restart your development server&lt;/strong&gt; and head back into LexasCMS. Navigate to the &lt;strong&gt;Content Preview&lt;/strong&gt; section of your space.&lt;/p&gt;

&lt;p&gt;You should see your project appear in the main visual preview panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fyi3QIzt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7v51xoqf3kc2hoz2tpq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fyi3QIzt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7v51xoqf3kc2hoz2tpq.jpg" alt="Content preview screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To the right of the preview, there will be a sidebar which allows you to control the context of the preview.&lt;/p&gt;

&lt;p&gt;Just like we did in the previous tutorial, let's see what our store looks like when being viewed by a customer whose local temperature is 5°C.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Update&lt;/strong&gt; link next to the &lt;strong&gt;Audience Attributes&lt;/strong&gt; heading in the preview context sidebar to reveal the &lt;strong&gt;Update Audience Attributes&lt;/strong&gt; modal.&lt;/p&gt;

&lt;p&gt;From the modal, click the &lt;strong&gt;Add Attribute&lt;/strong&gt; button, select the &lt;strong&gt;Local Temperature&lt;/strong&gt; attribute and set it's value to &lt;strong&gt;5&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eZCRh7Sf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdblsowi9pe0uje8c18b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eZCRh7Sf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdblsowi9pe0uje8c18b.jpg" alt="Update audience attributes screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Confirm&lt;/strong&gt; button, followed by the &lt;strong&gt;Update Preview&lt;/strong&gt; button in the preview context sidebar. This will apply your changes and reload the preview in the specified context.&lt;/p&gt;

&lt;p&gt;You should now see that the preview has updated, and that the content from the &lt;strong&gt;Cold Climate&lt;/strong&gt; variation which we created in the previous tutorial is being displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v8r-LnJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3x7ky4jh830l73q3qsf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v8r-LnJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3x7ky4jh830l73q3qsf.jpg" alt="vsf-next-tutorial-5-content-preview-updated"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What did I say, awesome right? ✨&lt;/p&gt;

&lt;h2&gt;
  
  
  Live demo and GitHub repo
&lt;/h2&gt;

&lt;p&gt;A live demo of this tutorial as well as its source code can be found using the links below:&lt;/p&gt;

&lt;p&gt;Live demo: &lt;a href="https://lexascms-tutorial-vsf-next.vercel.app/"&gt;&lt;/a&gt;&lt;a href="https://lexascms-tutorial-vsf-next.vercel.app/"&gt;https://lexascms-tutorial-vsf-next.vercel.app/&lt;/a&gt; &lt;br&gt;
Source code: &lt;a href="https://github.com/LexasCMS/tutorial-vsf-next/tree/part-3-visual-previews"&gt;&lt;/a&gt;&lt;a href="https://github.com/LexasCMS/tutorial-vsf-next/tree/part-3-visual-previews"&gt;https://github.com/LexasCMS/tutorial-vsf-next/tree/part-3-visual-previews&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We'll definitely be writing more about Vue Storefront in the future, however this marks the end of our Vue Storefront 2 tutorial series.&lt;/p&gt;

&lt;p&gt;To recap, in this series of tutorials we've covered the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo"&gt;Integrating a headless CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/lexascms/implementing-personalised-content-with-vue-storefront-2-f4g"&gt;Personalised Content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Visual Content Previews (this article)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These tutorials have demonstrated not only how simple it is to integrate LexasCMS with Vue Storefront 2, but also the additional benefits that it brings to your e-commerce store.&lt;/p&gt;

&lt;p&gt;Did you find this series of tutorials helpful? &lt;a href="https://twitter.com/lexascms"&gt;Tweet at us to let us know&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>tutorial</category>
      <category>headlesscms</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Implementing Personalised Content with Vue Storefront 2</title>
      <dc:creator>Michael Donaldson</dc:creator>
      <pubDate>Wed, 11 Aug 2021 13:29:50 +0000</pubDate>
      <link>https://dev.to/lexascms/implementing-personalised-content-with-vue-storefront-2-f4g</link>
      <guid>https://dev.to/lexascms/implementing-personalised-content-with-vue-storefront-2-f4g</guid>
      <description>&lt;p&gt;A couple of weeks ago I wrote a tutorial which walked you through &lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo"&gt;integrating a headless CMS with Vue Storefront 2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This week we're going to take things a bit further, and I'll be showing you how you can use LexasCMS to bring personalised content to your e-commerce store.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is personalisation?
&lt;/h2&gt;

&lt;p&gt;Over the past several years personalisation has become an increasingly important part of e-commerce. So before we dive into the tutorial itself, it's probably a good idea to take a moment to explain what personalisation actually means.&lt;/p&gt;

&lt;p&gt;In e-commerce, personalisation refers to delivering content (e.g. promotions and product recommendations) which is tailored to the current customer based on information which is known about them.&lt;/p&gt;

&lt;p&gt;For example, if based on their purchase/browsing history you knew that a customer had an interest in shoes, you could tailor the promotions that they were shown to include your latest offers on footwear.&lt;/p&gt;

&lt;p&gt;Historically, personalisation has always been something which was reserved for larger companies who could afford access to expensive personalisation platforms. However tools and platforms (such as LexasCMS 😉) are now emerging which make personalisation accessible to companies of all sizes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial
&lt;/h2&gt;

&lt;p&gt;Now that we have a clear understanding of what personalisation is, let's get to the tutorial!&lt;/p&gt;

&lt;p&gt;In this tutorial, we're going to personalise an e-commerce store's homepage banner based on the temperature in the current customers location.&lt;/p&gt;

&lt;p&gt;To keep it simple, we'll base the personalisation on the value of a query parameter. However, in the real world you would likely base it on something more realistic such as the output from a realtime weather API (e.g. &lt;a href="https://openweathermap.org/api"&gt;OpenWeather API&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;As a starting point, we'll also be using the store which you created in the &lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo"&gt;previous articles&lt;/a&gt; tutorial.&lt;/p&gt;

&lt;p&gt;If you didn't complete this tutorial, that's not a problem as I'll also provide instructions on how to get caught up 😉.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;p&gt;As with the previous tutorial, before getting started it's recommended that you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of Vue.js and Nuxt.js&lt;/li&gt;
&lt;li&gt;Node.js v12 or higher installed&lt;/li&gt;
&lt;li&gt;Yarn installed&lt;/li&gt;
&lt;li&gt;A LexasCMS account - &lt;a href="https://app.lexascms.com/signup"&gt;Click here to start free trial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 0: Getting caught up
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you've already completed the tutorial from the &lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo"&gt;previous article&lt;/a&gt;, feel free to skip this section.&lt;/p&gt;

&lt;p&gt;If you haven't, you can simply follow the steps below to catch up 🙂.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 0.1: Create a new space on LexasCMS
&lt;/h4&gt;

&lt;p&gt;First you'll need to create a new space in LexasCMS which uses the &lt;strong&gt;E-commerce Tutorial (Vue Storefront)&lt;/strong&gt; template.&lt;/p&gt;

&lt;p&gt;To do this, simply follow &lt;strong&gt;Step 1&lt;/strong&gt; of the previous articles tutorial &lt;a href="https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo#step-1-create-a-new-space-on-lexascms"&gt;which you can find here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 0.2: Clone source code for previous tutorial
&lt;/h4&gt;

&lt;p&gt;After creating your space, you can clone the final source code for the previous tutorial by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/LexasCMS/tutorial-vsf-next.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 0.3: Install project dependencies
&lt;/h4&gt;

&lt;p&gt;Once you've cloned the source code, you'll need to navigate into your project directory and install the projects dependencies using the commands below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;tutorial-vsf-next
yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 0.4: Configure your space ID
&lt;/h4&gt;

&lt;p&gt;Open the &lt;code&gt;middleware.config.js&lt;/code&gt; file within your code editor and replace &lt;code&gt;process.env.LEXASCMS_SPACE_ID&lt;/code&gt; within the &lt;code&gt;lexascms&lt;/code&gt; configuration with your actual space ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can find your space ID by navigating into the &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt; section of your space control panel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; module.exports = {
   integrations: {
     // ... 

     lexascms: {
       location: 'vsf-lexascms/server',
       configuration: {
&lt;span class="gd"&gt;-        spaceId: process.env.LEXASCMS_SPACE_ID
&lt;/span&gt;&lt;span class="gi"&gt;+        spaceId: 'YOUR_SPACE_ID'
&lt;/span&gt;       }
     }
   }
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 0.5: Start development server
&lt;/h4&gt;

&lt;p&gt;After your projects dependencies are installed, start your development server using the command shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your development server is up and running, navigate to &lt;a href="http://localhost:3000/"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt; in your web browser and you should see something like the below screenshot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KMvcOwAs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3il0uy0qgl9sub12vxcz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KMvcOwAs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3il0uy0qgl9sub12vxcz.jpg" alt="Development server running screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create new audience attribute
&lt;/h3&gt;

&lt;p&gt;By this point you should have either completed the previous tutorial, or followed the steps in the previous section to get caught up!&lt;/p&gt;

&lt;p&gt;In LexasCMS, personalisation works by allowing you to segment your customers into groups called &lt;strong&gt;Audiences&lt;/strong&gt;. These audiences can then be targeted with specific variations of your content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audience attributes&lt;/strong&gt; are the characteristics (e.g. age, gender, location etc.) which are used to segment your customers into audiences.&lt;/p&gt;

&lt;p&gt;First things first, we'll need to create a new audience attribute.&lt;/p&gt;

&lt;p&gt;From your space's control panel, navigate to the &lt;strong&gt;Audiences &amp;gt; Attributes&lt;/strong&gt; section. Once there, click on the &lt;strong&gt;Create Attribute&lt;/strong&gt; button and create a new attribute with the following values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; Local Temperature &lt;br&gt;
&lt;strong&gt;Key:&lt;/strong&gt; localTemperature &lt;br&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Number&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CYX8JQKy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcd6fwd6texe0zy231ww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CYX8JQKy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcd6fwd6texe0zy231ww.png" alt="Create audience attribute screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Create new audience
&lt;/h3&gt;

&lt;p&gt;Next you'll need to create a new audience. As mentioned earlier, audiences are essentially groups which allow you to segment your customers based on custom rules and conditions which are defined by you.&lt;/p&gt;

&lt;p&gt;We're going to create an audience which captures customers whose local temperatures are less than 10°C.&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Audiences &amp;gt; Audiences&lt;/strong&gt; section and then click on the &lt;strong&gt;Create Audience&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Create an audience with the following values:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name:&lt;/strong&gt; Cold Climate &lt;br&gt;
&lt;strong&gt;Key:&lt;/strong&gt; coldClimate&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cOIGB28N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58ac7jftf2gqsq4wh1e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cOIGB28N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58ac7jftf2gqsq4wh1e0.png" alt="Create audience screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Configure audience conditions
&lt;/h3&gt;

&lt;p&gt;Once your audience has been created, you'll be automatically taken to the &lt;strong&gt;Edit Audience&lt;/strong&gt; screen. This is where you define the rules and conditions which determine whether or not a customer should be included within this audience.&lt;/p&gt;

&lt;p&gt;Add a new &lt;strong&gt;Attribute&lt;/strong&gt; condition by clicking the &lt;strong&gt;Add Condition&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XvFI7zIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uuuzyqyz2psj58gfavvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XvFI7zIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uuuzyqyz2psj58gfavvv.png" alt="Edit audience screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the newly created condition, select the &lt;strong&gt;Local Temperature&lt;/strong&gt; attribute, change the comparator to &lt;strong&gt;Less Than&lt;/strong&gt; and enter &lt;strong&gt;10&lt;/strong&gt; in the value field.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Save Changes&lt;/strong&gt; button and you should be left with an audience configuration which looks as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WQYeiOu8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3o06260edpmq3zs096j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WQYeiOu8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3o06260edpmq3zs096j.png" alt="Configure audience conditions screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Target your audience with a content variation
&lt;/h3&gt;

&lt;p&gt;In this step we're going to edit one of the existing promo banners and add a new variation which is targeted at our newly created audience.&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Content&lt;/strong&gt; section and open the promo banner named &lt;strong&gt;First promo banner from LexasCMS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Within the item, you'll see that there is currently just one variation named &lt;strong&gt;Default&lt;/strong&gt;. This is the variation of this promo banner which is currently being displayed on your homepage.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Create Variation&lt;/strong&gt; button to create a new variation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SDbz-KpX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf0683uoghhwjvyrgkf4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SDbz-KpX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf0683uoghhwjvyrgkf4.png" alt="Content items variations screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter a name for your new variation and then click the &lt;strong&gt;Create Variation&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Feel free to name the new variation whatever you'd like, however I'm going to call it &lt;strong&gt;Cold Climate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yKEfogal--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6orah54dotnrzy1eoct3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yKEfogal--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6orah54dotnrzy1eoct3.png" alt="Create variation screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once your new variation has been created, you'll automatically be taken to the content editing screen.&lt;/p&gt;

&lt;p&gt;From here, fill out the content fields as specified below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heading:&lt;/strong&gt; 10% off all winter coats! &lt;br&gt;
&lt;strong&gt;Sub Heading:&lt;/strong&gt; Cold Weather Collection &lt;br&gt;
&lt;strong&gt;Button Text:&lt;/strong&gt; Learn More &lt;br&gt;
&lt;strong&gt;Background Image:&lt;/strong&gt; Save and upload &lt;a href="https://assets.lexascms.com/2d433d53-536b-49cc-9437-ba787964a4a7/9671f60d-fae8-4f78-8dfb-40f03cd0162d/promo-banner-background.webp"&gt;this image&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next up, we need to assign our new variation to the audience which we created earlier.&lt;/p&gt;

&lt;p&gt;In the sidebar to the right of the screen, you'll see an &lt;strong&gt;Audience&lt;/strong&gt; heading as shown in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HdkpnVAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2bkci8jb0l4aaj0wnuo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HdkpnVAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2bkci8jb0l4aaj0wnuo.jpg" alt="Content editor screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tells you which audience the variation is currently assigned to, but since it isn't yet assigned to any there will be an &lt;strong&gt;Add Audience&lt;/strong&gt; link instead.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Add Audience&lt;/strong&gt; link to open the &lt;strong&gt;Update Audience&lt;/strong&gt; modal and then within the modal, select the &lt;strong&gt;Cold Climate&lt;/strong&gt; audience which you created earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0cpK1Sz1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixt3mywyev41t4prub50.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0cpK1Sz1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixt3mywyev41t4prub50.jpg" alt="Update audience screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Confirm&lt;/strong&gt; button to assign the selected audience.&lt;/p&gt;

&lt;p&gt;Now that an audience has been assigned to our new variation, it will only be delivered to customers whose characteristics match the conditions which we defined earlier.&lt;/p&gt;

&lt;p&gt;All that's left now is to activate the &lt;strong&gt;Published&lt;/strong&gt; toggle and click the &lt;strong&gt;Save Changes&lt;/strong&gt; button to apply all of your changes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 5: Update homepage to send audience attributes
&lt;/h3&gt;

&lt;p&gt;You may have noticed that up until this point we haven't touched a single line of code. This is actually part of LexasCMS's design and means that content editors can have complete freedom to experiment without the need to involve developers.&lt;/p&gt;

&lt;p&gt;Having said that, there is one small code change which we need to make before LexasCMS can begin to personalise your content.&lt;/p&gt;

&lt;p&gt;In your code editor, open your &lt;code&gt;pages/Home.vue&lt;/code&gt; file and update the &lt;code&gt;setup&lt;/code&gt; method as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;promoBanners&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;onSSR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;collection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;promoBanner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backgroundImage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;audienceAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;localTemperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localTemp&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localTemp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;promoBanners&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All that we've done is added a couple of arguments to the &lt;code&gt;setup&lt;/code&gt; function and added the &lt;code&gt;context&lt;/code&gt; parameter to our call to the &lt;code&gt;search&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;This &lt;code&gt;context&lt;/code&gt; parameter allows you to (amongst other things) provide values for each of your defined audience attributes.&lt;/p&gt;

&lt;p&gt;As explained earlier, to keep things simple we're pulling the value of our &lt;code&gt;localTemperature&lt;/code&gt; attribute from a query parameter. We're also passing it through the &lt;code&gt;parseInt&lt;/code&gt; function to ensure that it is of the correct type when provided to LexasCMS.&lt;/p&gt;

&lt;p&gt;Once you've saved your changes, go back to your browsers and reload your projects homepage (&lt;a href="http://localhost:3000/"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;You should see that nothing has changed and that it looks exactly as it did at the start of this tutorial. This is because we haven't yet specified the &lt;code&gt;localTemp&lt;/code&gt; query parameter.&lt;/p&gt;

&lt;p&gt;Reload the homepage again, but this time also add the &lt;code&gt;localTemp&lt;/code&gt; query parameter with any value less than 10 (e.g. &lt;a href="http://localhost:3000/?localTemp=5"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000/?localTemp=5"&gt;http://localhost:3000/?localTemp=5&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This time, you should see that your homepage has changed and that it's now displaying the content from the &lt;strong&gt;Cold Climate&lt;/strong&gt; variation which you created earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--radqkksC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/enr8moqi8x6tusc7breb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--radqkksC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/enr8moqi8x6tusc7breb.jpg" alt="Personalised homepage hero banner screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's all there is to it! 🙌&lt;/p&gt;

&lt;p&gt;All of the heavy lifting is handled for you by LexasCMS's Content Delivery API, meaning that you don't need to make any changes to your templates or add any complicated logic to your application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live demo and GitHub repo
&lt;/h2&gt;

&lt;p&gt;A live demo of this tutorial as well as its source code can be found using the links below:&lt;/p&gt;

&lt;p&gt;Live demo: &lt;a href="https://lexascms-tutorial-vsf-next.vercel.app/"&gt;&lt;/a&gt;&lt;a href="https://lexascms-tutorial-vsf-next.vercel.app/"&gt;https://lexascms-tutorial-vsf-next.vercel.app/&lt;/a&gt; &lt;br&gt;
Source code: &lt;a href="https://github.com/LexasCMS/tutorial-vsf-next/tree/part-2-personalisation"&gt;&lt;/a&gt;&lt;a href="https://github.com/LexasCMS/tutorial-vsf-next/tree/part-2-personalisation"&gt;https://github.com/LexasCMS/tutorial-vsf-next/tree/part-2-personalisation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Hopefully during this tutorial, I've managed to show you that implementing content personalisation doesn't have to complicated.&lt;/p&gt;

&lt;p&gt;Using LexasCMS, it's incredibly simple to integrate personalisation in a way which is both easy to maintain for developers and also provides content editors with the flexibility that they need to experiment.&lt;/p&gt;

&lt;p&gt;In our next post, we're going to be taking this project even further and I'll be showing you how to use LexasCMS's visual preview feature to preview your website through the eyes of your customers.&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>tutorial</category>
      <category>headlesscms</category>
      <category>personalisation</category>
    </item>
    <item>
      <title>Integrating a headless CMS with Vue Storefront 2</title>
      <dc:creator>Michael Donaldson</dc:creator>
      <pubDate>Wed, 28 Jul 2021 14:05:56 +0000</pubDate>
      <link>https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo</link>
      <guid>https://dev.to/lexascms/integrating-a-headless-cms-with-vue-storefront-2-3mjo</guid>
      <description>&lt;p&gt;With the recent rise of composable commerce, integrating headless CMSes into e-commerce websites is becoming increasingly common. One such tool which makes this incredibly straight forward, is Vue Storefront 2.&lt;/p&gt;

&lt;p&gt;For those of you who are new to it, Vue Storefront 2 is the latest version of &lt;a href="https://www.vuestorefront.io/"&gt;Vue Storefront&lt;/a&gt;, which is a platform-agnostic PWA framework for creating e-commerce websites.&lt;/p&gt;

&lt;p&gt;In this post we’re going to walk you through how to integrate a headless CMS (specifically LexasCMS 😉) with Vue Storefront 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial
&lt;/h2&gt;

&lt;p&gt;So enough with the preamble, let’s get straight to it! 🚀&lt;/p&gt;

&lt;p&gt;In this tutorial we're going to take a freshly generated Vue Storefront 2 project, and replace the homepage hero banner with one that is managed by your headless CMS (in this case LexasCMS).&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;p&gt;Before getting started with the tutorial, it is recommended that you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of Vue.js and Nuxt.js&lt;/li&gt;
&lt;li&gt;Node.js v12 or higher installed&lt;/li&gt;
&lt;li&gt;Yarn installed&lt;/li&gt;
&lt;li&gt;A LexasCMS account - &lt;a href="https://app.lexascms.com/signup"&gt;Click here to start free trial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Create a new space on LexasCMS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://app.lexascms.com/login"&gt;Sign in to your LexasCMS account&lt;/a&gt;, and then either create a new organisation or navigate into an existing one.&lt;/p&gt;

&lt;p&gt;From within your organisation, create a new space by clicking on the &lt;strong&gt;Create Space&lt;/strong&gt; button and filling out the required information (any plan type will work fine).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gk-Nmkdj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7inpllhe45jtzi1w24m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gk-Nmkdj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7inpllhe45jtzi1w24m.jpg" alt="Create space screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once your new space has been created, open it, and you will be presented with a &lt;strong&gt;Select Starter Template&lt;/strong&gt; modal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DJWrcFsl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uogspwtwvmu7hrqg95ob.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DJWrcFsl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uogspwtwvmu7hrqg95ob.jpg" alt="Select starter template screenshot"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;From the modal, select the &lt;strong&gt;'E-commerce Tutorial (Vue Storefront)'&lt;/strong&gt; template, and then click the &lt;strong&gt;Import Template&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;This template will automatically create the content types and sample content which will be needed for this tutorial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create a new Vue Storefront 2 project
&lt;/h3&gt;

&lt;p&gt;We'll be using the Vue Storefront CLI to generate a new project. If you don't already have this installed, you can install it by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn global add @vue-storefront/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, generate a new Vue Storefront 2 project using the command below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When prompted to choose an integration, just select &lt;strong&gt;commercetools&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vsf init lexascms-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new &lt;code&gt;lexascms-tutorial&lt;/code&gt; directory which will contain the code for your new project.&lt;/p&gt;

&lt;p&gt;Once it has finished, navigate into the new project directory and install your projects dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;lexascms-tutorial
yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After your projects dependencies are installed, start your development server using the command shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your development server is up and running, navigate to &lt;a href="http://localhost:3000"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; in your web browser and you should see something like the below screenshot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o8-geVC7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q18x99p82maqm8rljqx6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o8-geVC7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q18x99p82maqm8rljqx6.jpg" alt="Development server running screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Install LexasCMS integration
&lt;/h3&gt;

&lt;p&gt;Before content can be retrieved from your headless CMS, you'll need to install and configure the Vue Storefront integration of your chosen CMS (in this case LexasCMS).&lt;/p&gt;

&lt;p&gt;To install the LexasCMS integration for Vue Storefront, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add vsf-lexascms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation has finished, register the &lt;code&gt;vsf-lexascms&lt;/code&gt; integration in your projects &lt;code&gt;nuxt.config.js&lt;/code&gt; file as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="na"&gt;buildModules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vsf-lexascms/nuxt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, open the &lt;code&gt;middleware.config.js&lt;/code&gt; file in the root of your project and add the following configuration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Be sure to replace &lt;code&gt;YOUR_SPACE_ID&lt;/code&gt; with your actual space ID, which can be found in the &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt; section of your space control panel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;integrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="na"&gt;lexascms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vsf-lexascms/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;spaceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_SPACE_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the integration has been installed and configured, content can be retrieved using the &lt;code&gt;useContent&lt;/code&gt; composable. Before we make any changes to our homepage, let's take a look at how it works.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;useContent&lt;/code&gt; composable is imported directly from your CMS integration like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useContent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vsf-lexascms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The composable then provides access to a &lt;strong&gt;search&lt;/strong&gt; function, and three other properties: &lt;strong&gt;content&lt;/strong&gt;, &lt;strong&gt;loading&lt;/strong&gt; and &lt;strong&gt;error&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;search&lt;/strong&gt; is a function and is used for retrieving content from your CMS (in this case LexasCMS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;content&lt;/strong&gt;, &lt;strong&gt;loading&lt;/strong&gt; and &lt;strong&gt;error&lt;/strong&gt; are all computed properties which are populated by the &lt;strong&gt;search&lt;/strong&gt; function

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;content&lt;/strong&gt; contains the content which was retrieved by the search function&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;loading&lt;/strong&gt; is a boolean which communicates whether the &lt;strong&gt;search&lt;/strong&gt; function is currently running or not&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;error&lt;/strong&gt; is null unless an error is thrown by the &lt;strong&gt;search&lt;/strong&gt; function, in which case this contains the error message&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usage of the &lt;strong&gt;search&lt;/strong&gt; function will vary depending on the CMS that you're integrating with. However, you can find the full documentation for the LexasCMS integration &lt;a href="https://github.com/LexasCMS/vsf-next-lexascms#how-to-use"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Update homepage
&lt;/h3&gt;

&lt;p&gt;Now that you've seen how the &lt;code&gt;useContent&lt;/code&gt; composable works, let's use it to fetch the content for your homepage's hero banner.&lt;/p&gt;

&lt;p&gt;Start by opening the &lt;code&gt;pages/Home.vue&lt;/code&gt; file in your project, and adding the below import statements.&lt;/p&gt;

&lt;p&gt;You'll notice that we're also importing the &lt;code&gt;onSSR&lt;/code&gt; helper function from Vue Storefront. We'll use this to ensure that content is only fetched during server-side rendering.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onSSR&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue-storefront/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useContent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vsf-lexascms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, define a &lt;code&gt;setup&lt;/code&gt; function as shown below.&lt;/p&gt;

&lt;p&gt;This function uses the &lt;code&gt;useContent&lt;/code&gt; composable and &lt;code&gt;onSSR&lt;/code&gt; helper function to retrieve all of the promo banners from LexasCMS. These are then made available to your template as the &lt;code&gt;promoBanners&lt;/code&gt; variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;promoBanners&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;onSSR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;collection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;promoBanner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backgroundImage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;promoBanners&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've retrieved the promo banners, we just need to display them!&lt;/p&gt;

&lt;p&gt;Scroll back to the top of the &lt;code&gt;pages/Home.vue&lt;/code&gt; file and replace the current usage of the &lt;code&gt;SfHero&lt;/code&gt; component so that it looks as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SfHero&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hero"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SfHeroItem&lt;/span&gt;
        &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"promoBanner in promoBanners"&lt;/span&gt;
        &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"promoBanner.id"&lt;/span&gt;
        &lt;span class="na"&gt;:title=&lt;/span&gt;&lt;span class="s"&gt;"promoBanner.heading"&lt;/span&gt;
        &lt;span class="na"&gt;:subtitle=&lt;/span&gt;&lt;span class="s"&gt;"promoBanner.subHeading"&lt;/span&gt;
        &lt;span class="na"&gt;:button-text=&lt;/span&gt;&lt;span class="s"&gt;"promoBanner.buttonText"&lt;/span&gt;
        &lt;span class="na"&gt;:image=&lt;/span&gt;&lt;span class="s"&gt;"promoBanner.backgroundImage.url"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/SfHero&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will loop through the &lt;code&gt;promoBanners&lt;/code&gt; variable from the previous step, and render each of the retrieved promo banners using the &lt;code&gt;SfHeroItem&lt;/code&gt; component from &lt;a href="https://www.storefrontui.io/"&gt;Storefront UI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Restart your development server and navigate to &lt;a href="http://localhost:3000"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; in your web browser.&lt;/p&gt;

&lt;p&gt;You should see that the homepage hero banner is now being powered by your CMS content.&lt;/p&gt;

&lt;p&gt;Congratulations! You successfully integrated a headless CMS into a Vue Storefront 2 project 🎉.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live demo and GitHub repo
&lt;/h2&gt;

&lt;p&gt;A live demo of this tutorial as well as its source code can be found using the links below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://lexascms-tutorial-vsf-next.vercel.app"&gt;&lt;/a&gt;&lt;a href="https://lexascms-tutorial-vsf-next.vercel.app"&gt;https://lexascms-tutorial-vsf-next.vercel.app&lt;/a&gt; &lt;br&gt;
&lt;strong&gt;Source code:&lt;/strong&gt; &lt;a href="https://github.com/LexasCMS/tutorial-vsf-next"&gt;&lt;/a&gt;&lt;a href="https://github.com/LexasCMS/tutorial-vsf-next"&gt;https://github.com/LexasCMS/tutorial-vsf-next&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you have learned how simple it is to fetch content from a headless CMS using the &lt;code&gt;useContent&lt;/code&gt; composable in Vue Storefront 2.&lt;/p&gt;

&lt;p&gt;In future posts we'll show you how to take things further and implement features such as personalised content and visual previews using LexasCMS.&lt;/p&gt;

&lt;p&gt;Thanks for reading! 🤘&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ecommerce</category>
      <category>headlesscms</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using a Headless CMS to Personalize E-Commerce With LexasCMS</title>
      <dc:creator>Michael Donaldson</dc:creator>
      <pubDate>Wed, 24 Mar 2021 16:11:35 +0000</pubDate>
      <link>https://dev.to/lexascms/using-a-headless-cms-to-personalize-e-commerce-with-lexascms-bp3</link>
      <guid>https://dev.to/lexascms/using-a-headless-cms-to-personalize-e-commerce-with-lexascms-bp3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Why create a new headless CMS?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hey 👋, I’m &lt;a href="https://twitter.com/mike_183" rel="noopener noreferrer"&gt;Mike&lt;/a&gt;, one of &lt;a href="https://www.lexascms.com" rel="noopener noreferrer"&gt;LexasCMS’s&lt;/a&gt; co-founders.&lt;/p&gt;

&lt;p&gt;This is probably one of the first questions people ask when you tell them that you’ve created &lt;em&gt;another&lt;/em&gt; new &lt;a href="https://snipcart.com/blog/headless-ecommerce-guide" rel="noopener noreferrer"&gt;headless CMS&lt;/a&gt; for personalization. Give me a moment to explain, and you’ll see that it’s worth your time. 😉&lt;/p&gt;

&lt;p&gt;There’s somewhat of a running joke in the development community that almost every developer will decide to build a custom CMS at some point in their career. In fact, back in the mid/late 2000s, pretty much every web agency actually had its own bespoke CMS.&lt;/p&gt;

&lt;p&gt;Fast forward to 2021, and the way people consume content has changed radically. Users not only expect content to be accessible from all of their various platforms and devices, but they also expect it to be consistent.&lt;/p&gt;

&lt;p&gt;As a result, the past decade has seen an explosion of new headless CMSes being launched to meet the evolving demands of the world's digital ecosystem.&lt;/p&gt;

&lt;p&gt;So to take it back to the original question, why did we create LexasCMS?&lt;/p&gt;

&lt;p&gt;Well, while it’s true that there are a stunningly large number of headless CMSes to choose from, there are none that really hit the sweet spot when it comes to e-commerce.&lt;/p&gt;

&lt;p&gt;Important features–such as personalization, scheduling, and visual previews–are often either missing, not flexible enough, or require too much custom integration work.&lt;/p&gt;

&lt;p&gt;By focusing on e-commerce, we can ensure that LexasCMS provides the tools and features that storefront owners need to drive sales and run successful e-commerce businesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is LexasCMS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LexasCMS is an e-commerce focused headless CMS&lt;/strong&gt; bootstrapped and launched by myself and fellow co-founder &lt;a href="https://twitter.com/davepbond" rel="noopener noreferrer"&gt;David Bond&lt;/a&gt; in June 2020.&lt;/p&gt;

&lt;p&gt;I’ve known David almost my entire life. After going through school and college together, we began working as freelancers in 2010, working on projects of all shapes and sizes.&lt;/p&gt;

&lt;p&gt;Naturally, from the beginning, we had our own bespoke CMS (who didn’t, right?), which we would use as the base for most of our client projects. Over time, we continued to develop new features, fix bugs, and at one point, even began the process of packaging it for commercial purposes.&lt;/p&gt;

&lt;p&gt;Ultimately, we decided that with the headless CMS's rise, it probably wasn’t the right direction. Instead, we opted to use what we’d learned over the best part of a decade to create what would eventually become LexasCMS.&lt;/p&gt;

&lt;p&gt;During the initial planning for LexasCMS, we were conscious that we didn’t want to create “yet another headless CMS”. It needed to provide specific value which couldn’t be found in existing solutions.&lt;/p&gt;

&lt;p&gt;Around this time, we decided to focus on e-commerce and providing the specific features required by modern online businesses.&lt;/p&gt;

&lt;p&gt;👥 &lt;strong&gt;Content Personalization&lt;/strong&gt; - Personalization is one of the biggest features of modern e-commerce websites. With LexasCMS, editors can create multiple variations of their content and then target them at specific audiences based on their individual characteristics.&lt;/p&gt;

&lt;p&gt;🗓 &lt;strong&gt;Content Planning / Scheduling&lt;/strong&gt; - Many e-commerce businesses plan their content weeks or even months in advance. LexasCMS allows you to input precisely how your content should change over time and then handles the rest for you. No more babysitting late-night content deploys. 🙌&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👁 Visual Previews&lt;/strong&gt; - Navigate around your website in the context of specific visitors. You can even control the date/time of the preview context to see how it would look for them in the past or future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚙️ Third-Party Integrations (Coming Soon)&lt;/strong&gt; - LexasCMS will soon be able to link product and category data from your e-commerce platform directly with your CMS content. This will make it painless to implement features such as personalized product recommendations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s this post going to be about?
&lt;/h2&gt;

&lt;p&gt;In this post, I will show you how to create a personalized e-commerce store using LexasCMS, Snipcart, and &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;. I’ll also show you how to set up visual previews so that you can see how your website appears through the eyes of specific visitors.&lt;/p&gt;

&lt;p&gt;Before we get into the tutorial itself, I want to take a moment to explain what we mean by personalization and how LexasCMS makes it easier.&lt;/p&gt;

&lt;p&gt;Many years ago, personalization was as simple as including a customer’s name within a marketing email. Nowadays, requirements are a lot more in-depth and can refer to anything from displaying a customer’s name all the way through to customizing the contents of an entire webpage.&lt;/p&gt;

&lt;p&gt;Personalization is usually based on known information about the current customer. This information could be anything, but common examples include basic profile data, previous browsing/purchase history, their current location, or even the weather in their current location.&lt;/p&gt;

&lt;p&gt;Before LexasCMS, if you wanted to personalize your CMS content, you needed the help of a third-party personalization platform. This platform would be used to determine which audiences a customer was in, and then developers would use that information to manually query for the correct content from your CMS.&lt;/p&gt;

&lt;p&gt;The problem with this approach is that it places a lot of burden on the developer to calculate and retrieve the correct content. Additionally, using two separate services creates a disconnect between the content management and personalization configuration, which in some cases can also limit the freedom for content editors to experiment. Content editors must also learn and jump between two separate applications, adding further friction to the content management process.&lt;/p&gt;

&lt;p&gt;LexasCMS not only removes the need for an additional third-party platform but also removes almost all of the personalization logic from your application. Simply ask LexasCMS for a piece of content, describe the customer who is making the request, and it will automatically send back the most relevant variation of that content.&lt;/p&gt;

&lt;p&gt;This is possible because LexasCMS holds all of the audience and personalization configuration. Content editors can control which variations of content should be delivered to specific audiences, enabling LexasCMS’s Content Delivery &lt;a href="https://snipcart.com/blog/integrating-apis-introduction" rel="noopener noreferrer"&gt;API&lt;/a&gt; to automatically calculate which content is most relevant for any request.&lt;/p&gt;

&lt;p&gt;Well! With all that out of the way, let’s move on to the tutorial! 🤓&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❗️ Fair warning:&lt;/strong&gt; This is a pretty long tutorial, so if you just want to see the final result or the source code, feel free to skip to the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a personalized e-commerce store with LexasCMS, Snipcart &amp;amp; Next.js
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, we’re going to use &lt;a href="https://www.freecodecamp.org/news/an-introduction-to-next-js-for-everyone-507d2d90ab54/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; for our example e-commerce store, but why Next.js?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Editor note: We have a great video with our friend Colby Fayock explaining what is Next.js &lt;a href="https://www.youtube.com/watch?v=H4snDqITlmc" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main reason is that Next.js makes it incredibly simple to switch between Server-Side Rendering (SSR) and &lt;a href="https://snipcart.com/blog/choose-best-static-site-generator" rel="noopener noreferrer"&gt;Static Site Generation (SSG)&lt;/a&gt; on a per-route basis.&lt;/p&gt;

&lt;p&gt;Since we’re going to be personalizing some of the pages on our store, these routes will need to be rendered on the server so that the content can be tailored based on the current visitor’s characteristics.&lt;/p&gt;

&lt;p&gt;On the flip side, routes that don’t typically need to be personalized–such as product pages–can be statically generated to improve performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;p&gt;Before getting started with the tutorial, it is recommended that you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Basic knowledge of &lt;a href="https://www.freecodecamp.org/news/react-beginner-handbook/" rel="noopener noreferrer"&gt;React&lt;/a&gt; and &lt;a href="https://www.smashingmagazine.com/2020/10/getting-started-with-next-js/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;Node.js v12 or higher&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://yarnpkg.com/getting-started/install" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;  A LexasCMS account - &lt;a href="https://app.lexascms.com/signup" rel="noopener noreferrer"&gt;Click here to start a free trial&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  A Snipcart account - &lt;a href="https://app.snipcart.com/register" rel="noopener noreferrer"&gt;Click here to create a free account&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Create a new space on LexasCMS
&lt;/h3&gt;

&lt;p&gt;Start by &lt;a href="https://app.lexascms.com/login" rel="noopener noreferrer"&gt;signing into your account&lt;/a&gt; and then either creating a new organization or navigating into an existing one.&lt;/p&gt;

&lt;p&gt;From within your organization, create a new space by clicking on the &lt;strong&gt;Create Space&lt;/strong&gt; button and filling out the required information. When choosing a plan type, please select &lt;strong&gt;Starter&lt;/strong&gt; or above, as the hobby plan does not have access to LexasCMS’s personalization features.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92vy26sqk9bhkadn0obe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92vy26sqk9bhkadn0obe.png" alt="Create Space LexasCMS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once your new space has been created, open it, and you should be presented with a &lt;strong&gt;Select Starter Template&lt;/strong&gt; modal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu4ms15xr62lq17kjd9n7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu4ms15xr62lq17kjd9n7.png" alt="Starter Template LexasCMS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go ahead and select the &lt;strong&gt;‘E-commerce Tutorial (Snipcart)’&lt;/strong&gt; template.&lt;/p&gt;

&lt;p&gt;To save you the trouble of doing it yourself, this template will automatically create all of the content types and sample content that you will need to complete this tutorial.&lt;/p&gt;

&lt;p&gt;For those interested in what exactly the template created, feel free to browse around the &lt;strong&gt;Content&lt;/strong&gt; and &lt;strong&gt;Content Model&lt;/strong&gt; sections of your space.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create a new Next.js project
&lt;/h3&gt;

&lt;p&gt;Next up, we’re going to create a new project based on Next.js. You can do so by running the following command in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create next-app lexascms-snipcart-tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create your new project and install its dependencies within a directory named &lt;strong&gt;lexascms-snipcart-tutorial&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once it has finished, navigate into your new project directory and start your development server using the commands shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;lexascms-snipcart-tutorial
yarn run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After your development server is up and running, navigate to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; in your web browser, and you should see something like the below screenshot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7jv1wy0h83ohlg31swt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7jv1wy0h83ohlg31swt.png" alt="Next.js"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Install and configure TailwindCSS
&lt;/h3&gt;

&lt;p&gt;Nobody likes to look at an ugly website, so for the sake of your eyes, we’re going to install &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;TailwindCSS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t used TailwindCSS before, you should definitely check it out! It’s an awesome utility-first CSS framework that was created by &lt;a href="https://twitter.com/adamwathan" rel="noopener noreferrer"&gt;Adam Wathan&lt;/a&gt; and &lt;a href="https://twitter.com/steveschoger" rel="noopener noreferrer"&gt;Steve Schoger&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since TailwindCSS is actually a &lt;a href="https://postcss.org/" rel="noopener noreferrer"&gt;PostCSS&lt;/a&gt; plugin, we’ll also need to install that as well.&lt;/p&gt;

&lt;p&gt;Install both modules by running the following command from the root of your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; postcss tailwindcss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you’ll need to configure PostCSS to use the TailwindCSS plugin. You can do this by creating a file named &lt;strong&gt;&lt;code&gt;postcss.config.js&lt;/code&gt;&lt;/strong&gt; in the root of your project directory with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, open the &lt;strong&gt;&lt;code&gt;styles/global.css&lt;/code&gt;&lt;/strong&gt; file, and replace its content with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Create LexasCMS helper
&lt;/h3&gt;

&lt;p&gt;Before we start creating our store, we’ll need to create a helper which will be used to fetch content from LexasCMS using its GraphQL based Content Delivery API.&lt;/p&gt;

&lt;p&gt;Let’s start by installing some dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add graphql graphql-request base-64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new file named &lt;strong&gt;&lt;code&gt;lib/lexascms.js&lt;/code&gt;&lt;/strong&gt; with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Base64&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base-64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GraphQLClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;graphql-request&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requestContext&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Define space ID&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spaceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_LEXASCMS_SPACE_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Define API key&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Define headers&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="c1"&gt;// Add Authorization header if required&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle LexasCMS request context&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requestContext&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lexascmsRequestContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;requestContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;lexascmsRequestContext&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;lexascmsRequestContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requestContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-lexascms-context&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lexascmsRequestContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Create client&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;spaceId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.spaces.lexascms.com/delivery/graphql`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Send request&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still, in the &lt;strong&gt;&lt;code&gt;lib/lexascms.js&lt;/code&gt;&lt;/strong&gt; file, replace &lt;strong&gt;YOUR_LEXASCMS_SPACE_ID&lt;/strong&gt; with your actual space ID, which can be retrieved from the &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt; section of your space control panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To keep things simple, we’re just hardcoding the space ID. In a real-world project, you would most likely want to retrieve this value from a pre-configured environment variable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwtzjq8ko73l457rmig3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwtzjq8ko73l457rmig3.png" alt="Space ID"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Create a homepage
&lt;/h3&gt;

&lt;p&gt;We’re going to start by creating a layout component. This component will wrap every page in our project to include common elements such as headers and footers.&lt;/p&gt;

&lt;p&gt;Create a new file at &lt;strong&gt;&lt;code&gt;components/layout.js&lt;/code&gt;&lt;/strong&gt; and inside it paste the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-5"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"max-w-screen-lg mx-auto pt-8 pb-16"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center justify-between mb-10"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl font-bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My Shop&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to the &lt;strong&gt;&lt;code&gt;pages/index.js&lt;/code&gt;&lt;/strong&gt; file and replace its contents with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/layout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../lib/lexascms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;homepage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col gap-2 items-center justify-center bg-gray-200 text-white h-96 rounded bg-cover bg-center"&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;backgroundImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;`linear-gradient(0deg, rgba(0,0,0,0.25), rgba(0,0,0,0.25)), url(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;homepage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promoBanner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-extrabold text-4xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;homepage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promoBanner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;homepage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promoBanner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subHeading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-semibold text-2xl text-center mt-16"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Products you might like&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid sm:grid-cols-3 gap-6 mt-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;homepage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;featuredProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/products/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Thumbnail`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center justify-between mt-3 mb-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                $&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-500"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
                      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-11 bg-gray-900 hover:bg-gray-800 text-white uppercase text-xs tracking-wide font-bold rounded mt-4 transition-colors duration-150 ease-in-out"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                Add to basket
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Define homepage query&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;homepageQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`{
    homepageCollection(limit: 1) {
      items {
        promoBanner {
          heading
          subHeading
          backgroundImage {
            url
          }
        }
        featuredProducts {
          items {
            id
            slug
            name
            price
            description
            image {
              url
            }
          }
        }
      }
    }
  }`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch homepage content&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;homepageQuery&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Return&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;homepage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;homepageCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By exporting the &lt;strong&gt;getServerSideProps&lt;/strong&gt; function, we’re telling Next.js that we would like this page to be rendered on the server as opposed to being statically generated.&lt;/p&gt;

&lt;p&gt;After saving your changes, restart your development server, and the homepage of your project should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo7x3rdntno4x9x264ft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo7x3rdntno4x9x264ft.png" alt="My Shop Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Create a product page
&lt;/h3&gt;

&lt;p&gt;Next up, we’re going to create a product page. Since product pages are not typically personalized, we can statically generate them to improve performance.&lt;/p&gt;

&lt;p&gt;Create a new file called &lt;strong&gt;&lt;code&gt;pages/products/[slug].js&lt;/code&gt;&lt;/strong&gt; and paste in the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../components/layout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../lib/lexascms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid sm:grid-cols-2 gap-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Image`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium text-2xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium text-xl text-gray-600 my-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            $&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-500"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
                  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-11 bg-gray-900 hover:bg-gray-800 text-white uppercase text-xs tracking-wide font-bold rounded mt-4 transition-colors duration-150 ease-in-out"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Add to basket
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Define product slugs query&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productSlugsQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`{
    productCollection {
      items {
        slug
      }
    }
  }`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch product slugs&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productSlugs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productSlugsQuery&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Return&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productSlugs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Define product query&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`{
    productCollection(filter: { slug: { _eq: "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" } }) {
      items {
        id
        slug
        name
        price
        description
        image {
          url
        }
      }
    }
  }`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch product data&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;productQuery&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Return&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we’re exporting the &lt;strong&gt;getStaticPaths&lt;/strong&gt; and &lt;strong&gt;getStaticProps&lt;/strong&gt; functions, which tells Next.js that we want this route to be statically generated.&lt;/p&gt;

&lt;p&gt;After saving your changes again, go back to your browser and click on one of the product thumbnails to open the product page.&lt;/p&gt;

&lt;p&gt;Depending on which product you selected, you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitn68knizojl94z43ytv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitn68knizojl94z43ytv.png" alt="My Shop T-Shirt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Implement personalization in the headless CMS
&lt;/h3&gt;

&lt;p&gt;Now that you have a basic e-commerce store, we’re going to personalize the homepage!&lt;/p&gt;

&lt;p&gt;To keep things simple, we’ll base the personalization on the value of a query parameter. However, in a real-world project, you would likely base it on data from a more realistic source such as profile information, order history, or even data fetched from third-party APIs.&lt;/p&gt;

&lt;p&gt;When using LexasCMS, personalization is handled entirely by its &lt;a href="https://www.lexascms.com/docs/api-reference/content-delivery/" rel="noopener noreferrer"&gt;Content Delivery API&lt;/a&gt;. This keeps your application code simple and ensures that content teams are free to experiment without the need for developers to make code changes.&lt;/p&gt;

&lt;p&gt;As a simple example, we’re going to adjust the homepage banner and its featured products based on the visitor’s local temperature.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 7.1: Create an Audience Attribute
&lt;/h4&gt;

&lt;p&gt;Audience attributes are the characteristics that are used to segment your visitors into any of your defined audiences.&lt;/p&gt;

&lt;p&gt;Head back into LexasCMS and navigate to the &lt;strong&gt;Audiences &amp;gt; Attributes&lt;/strong&gt; section. Once there, click on the &lt;strong&gt;Create Attribute&lt;/strong&gt; button and create an attribute with the following values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; Local Temperature&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key:&lt;/strong&gt; localTemperature&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhejbjnb6lupeq0k5c40w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhejbjnb6lupeq0k5c40w.png" alt="Create Audience Attribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 7.2: Create an Audience
&lt;/h4&gt;

&lt;p&gt;Audiences allow you to segment visitors based on custom rules and conditions which you define. The rules and conditions themselves are defined using audience attributes.&lt;/p&gt;

&lt;p&gt;We’re going to create a new audience that will only include visitors whose local temperature is greater than 20°C.&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Audiences &amp;gt; Audiences&lt;/strong&gt; section and then click on the &lt;strong&gt;Create Audience&lt;/strong&gt; button. Create an audience with the following values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; Warm Climate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key:&lt;/strong&gt; warmClimate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2lfke4ry04mhxjpfojk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2lfke4ry04mhxjpfojk.png" alt="Create New Audience"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 7.3: Configure your Audience’s conditions
&lt;/h4&gt;

&lt;p&gt;After creating your audience, you’ll be taken to the &lt;strong&gt;Edit Audience&lt;/strong&gt; screen. This is where you define the rules and conditions which determine whether or not a visitor should be included within this audience.&lt;/p&gt;

&lt;p&gt;Add an &lt;strong&gt;Attribute&lt;/strong&gt; condition by clicking the &lt;strong&gt;Add Condition&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9guq21flzxynre3uvmq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9guq21flzxynre3uvmq0.png" alt="Add Condition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the condition has been added, select the &lt;strong&gt;Local Temperature&lt;/strong&gt; attribute which you created earlier, change the comparator to &lt;strong&gt;Greater Than&lt;/strong&gt;, and enter &lt;strong&gt;20&lt;/strong&gt; in the &lt;strong&gt;Value&lt;/strong&gt; field.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Save Changes&lt;/strong&gt; button, and your audience should now look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14r7qtw4bkwkwnz9243r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14r7qtw4bkwkwnz9243r.png" alt="Local Temperature Attribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 7.4: Target your new audience with a variation
&lt;/h4&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Content&lt;/strong&gt; section and locate the existing content item named &lt;strong&gt;Homepage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Within the item, you’ll notice that there are two variations. One of which is currently a draft named &lt;strong&gt;Warm Climate&lt;/strong&gt; and the other named &lt;strong&gt;Default,&lt;/strong&gt; which is already published.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Default&lt;/strong&gt; is the variation that is currently being displayed in your project&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Warm Climate&lt;/strong&gt; is the variation we’re going to target members of our newly created audience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click on the &lt;strong&gt;Warm Climate&lt;/strong&gt; variation to open it, and then look in the sidebar on the right of the screen for an &lt;strong&gt;Audience&lt;/strong&gt; heading. This tells you which audience the variation is currently assigned to. Since one is yet to be assigned, there will be an &lt;strong&gt;Add Audience&lt;/strong&gt; link instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1zzq88nk4q2cv4vcqja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1zzq88nk4q2cv4vcqja.png" alt="Add Audience"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Add Audience&lt;/strong&gt; link to reveal the &lt;strong&gt;Update Audience&lt;/strong&gt; modal and then select the &lt;strong&gt;Warm Climate&lt;/strong&gt; audience which you created earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbspcpjbwse66o7u9akj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbspcpjbwse66o7u9akj9.png" alt="Update Audience Warm Climate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Confirm&lt;/strong&gt; button to apply your selection.&lt;/p&gt;

&lt;p&gt;Once a variation has been assigned to an audience, it will only be delivered to visitors whose characteristics match the defined rules and conditions for the assigned audience.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 7.7: Publish your new variation
&lt;/h4&gt;

&lt;p&gt;Now that your audience has been assigned to the variation enable the &lt;strong&gt;Published&lt;/strong&gt; toggle and click the &lt;strong&gt;Save Changes&lt;/strong&gt; button.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 7.8: Personalize your homepage
&lt;/h4&gt;

&lt;p&gt;In your code editor, open your &lt;strong&gt;&lt;code&gt;pages/index.js&lt;/code&gt;&lt;/strong&gt; file and update the &lt;strong&gt;getServerSideProps&lt;/strong&gt; function declaration to include &lt;strong&gt;&lt;code&gt;{ query }&lt;/code&gt;&lt;/strong&gt; as the first argument.&lt;/p&gt;

&lt;p&gt;Your function blueprint should then look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, find the call to &lt;strong&gt;request&lt;/strong&gt; within your &lt;strong&gt;getServerSideProps&lt;/strong&gt; function, and update it to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="c1"&gt;// Define request context&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;requestContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;audienceAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;localTemperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localTemp&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localTemp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch homepage content&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;homepageQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;requestContext&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This takes the &lt;strong&gt;localTemp&lt;/strong&gt; query parameter value and passes it as the value for your &lt;strong&gt;localTemperature&lt;/strong&gt; audience attribute. The audience attributes are then sent with your query to LexasCMS’s Content Delivery API, which uses the information to determine which variations of your content should be returned.&lt;/p&gt;

&lt;p&gt;Notice how we haven’t touched the query itself or made any changes to our templates? This is exactly what makes LexasCMS’s personalization feature, so simple to integrate and maintain since all of the heavy lifting is handled by its Content Delivery API.&lt;/p&gt;

&lt;p&gt;Save your changes. It’s now time to see the magic happen. ✨&lt;/p&gt;

&lt;p&gt;Go back to your browser and reload your project's homepage (&lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;You should see that nothing has changed and that it looks exactly the same as it did before. This is because we haven’t provided the &lt;strong&gt;&lt;code&gt;localTemp&lt;/code&gt;&lt;/strong&gt; query parameter.&lt;/p&gt;

&lt;p&gt;Try reloading the homepage again, but this time add the &lt;strong&gt;&lt;code&gt;localTemp&lt;/code&gt;&lt;/strong&gt; query parameter with a value which is &lt;strong&gt;greater than&lt;/strong&gt; &lt;strong&gt;20&lt;/strong&gt; (e.g. &lt;a href="http://localhost:3000/?localTemp=25" rel="noopener noreferrer"&gt;http://localhost:3000/?localTemp=25&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This time, you should notice that your homepage has changed and that it’s now displaying the content from the &lt;strong&gt;Warm Climate&lt;/strong&gt; variation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7syy0aqfwhydhkri4wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7syy0aqfwhydhkri4wx.png" alt="My Shop Warm Climate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You just personalized your first website page using LexasCMS. 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Implement Snipcart
&lt;/h3&gt;

&lt;p&gt;What good is an e-commerce website if you can’t buy anything? Fortunately, Snipcart makes it amazingly simple to turn our website into a fully functioning e-commerce store!&lt;/p&gt;

&lt;p&gt;Start by creating a new file named &lt;strong&gt;&lt;code&gt;pages/_document.js&lt;/code&gt;&lt;/strong&gt; and paste in the below contents, be sure to replace &lt;strong&gt;SNIPCART_API_KEY&lt;/strong&gt; with your &lt;a href="https://docs.snipcart.com/v3/dashboard/account-configuration#3-api-keys" rel="noopener noreferrer"&gt;Snipcart’s API Key&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyDocument&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"preconnect"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://app.snipcart.com"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"preconnect"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.snipcart.com"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.snipcart.com/themes/v3.0.27/default/snipcart.css"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.snipcart.com/themes/v3.0.27/default/snipcart.js"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;hidden&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"snipcart"&lt;/span&gt; &lt;span class="na"&gt;data-api-key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"SNIPCART_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This includes some external styles and scripts which Snipcart requires.&lt;/p&gt;

&lt;p&gt;Next, open the &lt;strong&gt;&lt;code&gt;pages/index.js&lt;/code&gt;&lt;/strong&gt; file and locate the &lt;strong&gt;Add to Basket&lt;/strong&gt; button within the template. Update the button so that it looks the same as the snippet below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"snipcart-add-item h-11 bg-gray-900 hover:bg-gray-800 text-white uppercase text-xs tracking-wide font-bold rounded mt-4 transition-colors duration-150 ease-in-out"&lt;/span&gt;
        &lt;span class="na"&gt;data-item-id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;data-item-price&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;data-item-url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/products/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;data-item-description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;data-item-image&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;data-item-name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Add to basket
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we’ve added a &lt;strong&gt;&lt;code&gt;snipcart-add-item&lt;/code&gt;&lt;/strong&gt; class and a few data attributes. Snipcart uses them to describe the product and determine its price.&lt;/p&gt;

&lt;p&gt;Make the same changes to the Add to Basket button on your product page.&lt;/p&gt;

&lt;p&gt;Restart your development server and then reload your project to find that the Add to Basket buttons are now functional!&lt;/p&gt;

&lt;p&gt;Congratulations again! You now have a fully functioning and personalized e-commerce store. 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Setup visual previews
&lt;/h3&gt;

&lt;p&gt;While not strictly required, being able to preview your website through your visitors' eyes is a powerful capability for content editors to wield.&lt;/p&gt;

&lt;p&gt;Fortunately, LexasCMS’s visual preview feature provides this ability while also being pretty simple to implement.&lt;/p&gt;

&lt;p&gt;Start by heading back into LexasCMS and navigating to the &lt;strong&gt;Settings &amp;gt; Previews&lt;/strong&gt; section of your space.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Create Preview&lt;/strong&gt; button and create a new preview with the following attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; Local Development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preview URL:&lt;/strong&gt; &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweki2vuqqa77y40jonfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweki2vuqqa77y40jonfb.png" alt="Create Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you’ve created the preview, navigate to &lt;strong&gt;Settings &amp;gt; API Keys&lt;/strong&gt; and click the &lt;strong&gt;Create an API Key&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Create a new API key named &lt;strong&gt;Local Development&lt;/strong&gt;, being sure to enable the &lt;strong&gt;Content Delivery API (Preview)&lt;/strong&gt; permission.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzweg478wtpzcf14rp1pa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzweg478wtpzcf14rp1pa.png" alt="Create API Key"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the API Key has been created, copy the generated token as you’ll need it in the next step.&lt;/p&gt;

&lt;p&gt;Open the &lt;strong&gt;&lt;code&gt;lib/lexascms.js&lt;/code&gt;&lt;/strong&gt; file in your code editor and replace the value of the &lt;strong&gt;apiKey&lt;/strong&gt; variable with your newly generated API Key. Like with the space ID, you would likely pull your API Key from a pre-configured environment variable in a real-world project.&lt;/p&gt;

&lt;p&gt;Next, open the &lt;strong&gt;&lt;code&gt;pages/_document.js&lt;/code&gt;&lt;/strong&gt; file and paste the below snippet before the closing body tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt; &lt;span class="na"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`(function(e,t){void 0!==e.addEventListener&amp;amp;&amp;amp;e.addEventListener("load",function(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script")
          n.type="text/javascript",n.async=!0,n.src="https://static.lexascms.com/lexascms.js",e.parentNode.insertBefore(n,e)},!1)})(window,document)`&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script allows your project to communicate with LexasCMS’s visual preview tool.&lt;/p&gt;

&lt;p&gt;When LexasCMS loads your project within its preview tool, it provides a pre-configured request context via the &lt;strong&gt;&lt;code&gt;lexascmsRequestContext&lt;/code&gt;&lt;/strong&gt; query parameter. When this query parameter is present, you should pass its value as the request context for all requests to LexasCMS instead of building your own.&lt;/p&gt;

&lt;p&gt;To do this, open your &lt;strong&gt;&lt;code&gt;pages/index.js&lt;/code&gt;&lt;/strong&gt; file and locate the definition of the &lt;strong&gt;requestContext&lt;/strong&gt; variable within your &lt;strong&gt;getServerSideProps&lt;/strong&gt; function. Replace it with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="c1"&gt;// Define request context&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;requestContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lexascmsRequestContext&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;requestContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lexascmsRequestContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;requestContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;audienceAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;localTemperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localTemp&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localTemp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This change will check for the existence of the &lt;strong&gt;&lt;code&gt;lexascmsRequestContext&lt;/code&gt;&lt;/strong&gt; query parameter before attempting to build its own request context.&lt;/p&gt;

&lt;p&gt;Restart your development server, and head back into LexasCMS.&lt;/p&gt;

&lt;p&gt;After navigating to the &lt;strong&gt;Content Preview&lt;/strong&gt; section of your space, you should see your project appear within the preview window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbbm9vhmtkdwh42otksc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbbm9vhmtkdwh42otksc.png" alt="My Shop Content Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sidebar to the right provides controls that allow you to modify the context of the preview. Let’s set the value for our &lt;strong&gt;Local Temperature&lt;/strong&gt; audience attribute and see what happens.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Update&lt;/strong&gt; link next to the &lt;strong&gt;Audience Attributes&lt;/strong&gt; heading to reveal the &lt;strong&gt;Update Audience Attributes&lt;/strong&gt; modal.&lt;/p&gt;

&lt;p&gt;Using the &lt;strong&gt;Add Attribute&lt;/strong&gt; button in the model, add the &lt;strong&gt;Local Temperature&lt;/strong&gt; attribute and set its value to &lt;strong&gt;25&lt;/strong&gt; (or anything greater than 20).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv1k28xq6glw34v91l5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv1k28xq6glw34v91l5y.png" alt="Update Audience Attribute Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Confirm&lt;/strong&gt; button, followed by the &lt;strong&gt;Update Preview&lt;/strong&gt; button in the sidebar to apply your changes.&lt;/p&gt;

&lt;p&gt;You should see your project reload with the configured context and that the content from the &lt;strong&gt;Warm Climate&lt;/strong&gt; variation is now being displayed. 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91rl5aobicam90y3u0kp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91rl5aobicam90y3u0kp.png" alt="My Shop Warm Climate Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="demo"&gt; Live Demo and GitHub repo &lt;/h2&gt;

&lt;p&gt;You can find a live demo of this tutorial as well as its source code using the links below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://lexascms-tutorial-snipcart.vercel.app/" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/LexasCMS/tutorial-snipcart" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;Personalization is already a big part of the e-commerce industry, and its importance is only going to grow as time moves on.&lt;/p&gt;

&lt;p&gt;Hopefully, this post has shown you that by using LexasCMS, you can easily create personalized websites. Websites that allow content editors to experiment freely and simplify build and maintenance for developers.&lt;/p&gt;

&lt;p&gt;We’re only just getting started with our plans for LexasCMS, and we have tons of exciting ideas which we can’t wait to share.&lt;/p&gt;

&lt;p&gt;To keep up with LexasCMS’s latest updates, &lt;a href="https://twitter.com/lexascms" rel="noopener noreferrer"&gt;follow us on Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Want to learn more about LexasCMS? Try it for free by &lt;a href="https://app.lexascms.com/signup" rel="noopener noreferrer"&gt;creating an account&lt;/a&gt; and starting your trial today.&lt;/p&gt;

&lt;p&gt;Any questions or feedback? &lt;a href="https://twitter.com/lexascms" rel="noopener noreferrer"&gt;Tweet at us&lt;/a&gt; or &lt;a href="https://www.lexascms.com/contact/" rel="noopener noreferrer"&gt;email us&lt;/a&gt; to let us know!&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>headlesscms</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
