<?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>Forem: Rose Chege</title>
    <description>The latest articles on Forem by Rose Chege (@chegerose).</description>
    <link>https://forem.com/chegerose</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%2F887078%2Fc19b6460-094e-43c2-bd90-3f553f354ef8.png</url>
      <title>Forem: Rose Chege</title>
      <link>https://forem.com/chegerose</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chegerose"/>
    <language>en</language>
    <item>
      <title>The Best Strategies to Slim Docker Images: How to Reduce Docker Image Size</title>
      <dc:creator>Rose Chege</dc:creator>
      <pubDate>Tue, 02 May 2023 12:49:15 +0000</pubDate>
      <link>https://forem.com/chegerose/the-best-strategies-to-slim-docker-images-how-to-reduce-docker-image-size-3l2c</link>
      <guid>https://forem.com/chegerose/the-best-strategies-to-slim-docker-images-how-to-reduce-docker-image-size-3l2c</guid>
      <description>&lt;p&gt;Do YOU WANT to SLIM your Docker images? I wrote the following article, The Best Strategies to Slim Docker Images, using a Node.js application approach. *&lt;em&gt;Give it a view and support my journey to becoming a technical article writer. *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Learn &lt;a href="https://thriveread.com/slim-and-reduce-docker-image-size/"&gt;tips and How to Reduce Docker Image Size by roughly 90.37% of its initial size&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me know your comment about it. I will appreciate it.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>containers</category>
      <category>devops</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Top 5 Cloud-Native Message Queues (MQs) with Node.js Support</title>
      <dc:creator>Rose Chege</dc:creator>
      <pubDate>Tue, 13 Sep 2022 12:53:12 +0000</pubDate>
      <link>https://forem.com/chegerose/top-5-cloud-native-message-queues-mqs-with-nodejs-support-ak5</link>
      <guid>https://forem.com/chegerose/top-5-cloud-native-message-queues-mqs-with-nodejs-support-ak5</guid>
      <description>&lt;p&gt;Message queues (MQs) allow you to run distributed services. This article will go over MQs in further detail. Then Discuss the benefits cloud-native has to provide for your application and why we need it for MQs. Finally, highlight the top five cloud native MQs that can be easily run with Node.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Beginning: Synchronous
&lt;/h3&gt;

&lt;p&gt;The application's scalability model is a tremendous consideration when rolling out your application. Take an example of a simple application using a &lt;a href="https://en.wikipedia.org/wiki/Request%E2%80%93response" rel="noopener noreferrer"&gt;request-response&lt;/a&gt; model. You have three major components to facilitate your services: a client, a server, and the database to process your system data.&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%2Fn1gns6fjuad4fduwbxuu.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%2Fn1gns6fjuad4fduwbxuu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/state-the-core-components-of-an-http-response/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using this approach, once the client sends the request to the server, it has to wait for the processing to finish before getting back a response. However, this itself being a problem, it doesn't pose any technical processing problems to a simple application with just a few random users. Here you are running a synchronous model that your database can comfortably handle.&lt;/p&gt;

&lt;p&gt;What if your system starts to get popular? Your server will start handling time-consuming tasks to fit the demand of the growing user base. Imagine your synchronous model handling these requests each at a time. Your client, in this case, cannot proceed with any other operations. Once you open the http connection, you cannot close the connection until you get a response from the server.&lt;/p&gt;

&lt;p&gt;The client will have to wait longer for a response as the server receives more and more requests. You will end up with a backlog of requests. Even when the client expects a simple success message as the response, it has to wait for the first request to get processed, as requests get expected in the order they are received. By the fact that &lt;a href="https://smartbear.com/blog/5-10-15-seconds-how-long-will-you-wait-for-a-web-p/" rel="noopener noreferrer"&gt;53% of mobile users abandon sites&lt;/a&gt; take over 3 seconds to respond, your system paradigm ends up creating a huge gap between user expectations and the application capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing Asynchronous
&lt;/h3&gt;

&lt;p&gt;One of the best ways to solve this problem is to create an asynchronous communication model. An asynchronous model will execute that first request and the rest of any received requests simultaneously.&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%2Fp8rl05hqjbjcbentpkb5.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%2Fp8rl05hqjbjcbentpkb5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.smashingmagazine.com/2017/03/simplify-android-networking-volley-http-library/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The beauty of this approach is that when the client sends a request to the server, it doesn't have to wait for the server to get any response. It can actually go ahead and do some other operations. Here your application is running to its full potential with no limitations on what it can do at any given time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting a Message Queue: Asynchronous Approach
&lt;/h3&gt;

&lt;p&gt;One of the best ways to achieve asynchronous communication is to use a message queue (MQ). A message queue enables the client to reduce the wait time for a task to finish and, as a result, execute other tasks during that time. Additionally, it allows a server to carry out tasks in the order it chooses.&lt;/p&gt;

&lt;p&gt;Message queues are a service to service asynchronous communication used to build highly decoupled and reliable microservice applications. It allows one service to communicate with another service by sending messages to each other.&lt;/p&gt;

&lt;p&gt;Message queuing uses a broker for centralized data management to ensure that the communication is delivered in a reliable fashion between the services.&lt;/p&gt;

&lt;p&gt;This architecture uses messages as the data. The server, also known as the producer, creates the messages (the data) and sends them to the centralized message queuing manager (the broker). The client, also known as the consumer, retrieves the message from the queue and processes the data.&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%2Fzp4ofczwfzsttkl9zuxa.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%2Fzp4ofczwfzsttkl9zuxa.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hevodata.com/learn/message-queues/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way, the producers can send any amount of data without worrying about consumer availability. The application can now manage multiple heavy scaling tasks using this microservice-based architecture. When the client requires data, it simply requests messages from the queue anytime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node.js for Message Queuing
&lt;/h3&gt;

&lt;p&gt;You have decided to run your system asynchronously. Thanks to the message queuing architecture. But then again, you need to implement this architecture to leverage your system's capabilities. One of the best ways to &lt;a href="https://docs.memphis.dev/memphis-new/sdks/node.js-typescript" rel="noopener noreferrer"&gt;implement messages queues is using Node.js (Typescript/NestJS)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@chegerose84/5-enhancements-that-will-boost-your-node-js-app-ca0c57ab191d" rel="noopener noreferrer"&gt;Node.js is a popular technology&lt;/a&gt; that offers a wide range of features for your application. This include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asynchronous/Non-blocking thread execution. Node.js allows you to create Non-blocking servers/API. Every Node.js API is non-blocking. The subsequent tasks in the stack are continuously run while waiting for a response for something outside of the execution chain. Its single-threaded asynchronous capabilities make it well-suited to real-time communication processes. This is the exact architecture that you would desire to build your servers with. The fact that message queues are Asynchronous, your application performs at full potential.&lt;/li&gt;
&lt;li&gt;Event-driven. A node.js server is Event-driven. It uses Event Loop to handle multiple clients simultaneously. It uses its multiple threads pool for concurrent executions. This way, each time a request is sent, a dedicated thread is created to handle that specific request. This, again, makes it easier for non-blocking executions.&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%2Fhu65q427rsxcsvnkpijh.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%2Fhu65q427rsxcsvnkpijh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scoutapm.com/blog/nodejs-architecture-and-12-best-practices-for-nodejs-development" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;br&gt;
The above are a few advantages that Node.js offers. They make it easier and more scalable to build microservices applications. Adding the benefits of message queues, the combination allows you to create complex and high performant apps.&lt;/p&gt;

&lt;p&gt;There are many message queues that you can use to run with Node.js. However, setting up one requires layers of infrastructure such as databases, networks, servers, OS, security, etc. Setting up all these elements to run your infrastructure can be challenging to maintain and monitor. Yet, it reduces your infrastructure portability. Downtime of one layer can hugely affect the whole application as the entire infrastructure is closely coupled to run all these layers together.&lt;/p&gt;

&lt;p&gt;To overcome such challenges, we need modern solutions that exploit a modern infrastructure's flexibility, scalability, and resilience. A huge thanks to cloud native computing that allows you to run and host applications in the cloud to take advantage of the inherent characteristics of a cloud computing software delivery paradigm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Going Serverless: Running Message Queues as a Service (Cloud Native)
&lt;/h3&gt;

&lt;p&gt;As of right now, almost every IT tool or product is accessible as a service. A delivery model that allows you to run serverless architecture. And Message Queues haven't been left on the cloud bandwagon. Cloud-native is built to offer a serverless development strategy created specifically to properly exploit the cloud computing architecture.&lt;/p&gt;

&lt;p&gt;Serverless architecture, a cloud-native development methodology, allows developers to create applications without provisioning servers or to handle scaling management. Instead, such tasks are abstracted and handled by the cloud provider. This allows developers to create vendor agnostic, auto-provisioning, and highly scalable applications with the faster release of production-ready and fault-tolerant models.&lt;/p&gt;

&lt;p&gt;This is facilitated by the fact that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud natives are microservices centric - this way, your messages queues still run loosely coupled. Specific features can be updated without causing any downtime to your apps.&lt;/li&gt;
&lt;li&gt;They are created with Continuous Integration/Continuous Delivery (CI/CD) pipelines in mind. This brings the concept of Accelerated Software Development Lifecycle (SDLC) to your team and members to collaborate at different levels, such as designing, development, and testing.&lt;/li&gt;
&lt;li&gt;CI/CD is packed with automation. This allows you to make high-impact changes with minimal effort.&lt;/li&gt;
&lt;li&gt;Cloud Native Architecture is container orchestrated. You don't have to be concerned about the platform, operating system, or runtime environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To sum up, cloud native apps principles are:&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%2F8frnm9tgsgffn2r2auxw.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%2F8frnm9tgsgffn2r2auxw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.techtarget.com/searchcloudcomputing/definition/cloud-native-application" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now imagine running your whole Message Queue architecture as a service. This is a huge step forward with a tone of benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automation opportunities allow you to focus on other pressing challenges.&lt;/li&gt;
&lt;li&gt;Portability - message queues become vendor agnostic. Containers allow you to connect to different microservices components through port mapping. This way, you avoid &lt;a href="https://www.cloudflare.com/learning/cloud/what-is-vendor-lock-in/" rel="noopener noreferrer"&gt;vendor lock-in&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Increased Reliability. You have reduced downtime, and the failure of one component doesn't affect adjacent services.&lt;/li&gt;
&lt;li&gt;Easy to manage and scale your architecture.&lt;/li&gt;
&lt;li&gt;Language - cloud native message queues are built to work with modern languages and frameworks such as Node.js, Typescript, Go, Python, Rust, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since cloud native can be easily implemented with a wide range of frameworks and languages, choosing what you want to work with is easy. Node.js is an excellent candidate for message queueing. We have seen that Node.js compliments the message queuing architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Top 5 Cloud-Native MQs with Node.js Support
&lt;/h3&gt;

&lt;p&gt;Let's dive and learn about Node.js top cloud native message queues (MQs) that Node.js supports.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Memphis
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://memphis.dev/" rel="noopener noreferrer"&gt;Memphis&lt;/a&gt; is an open-source, real-time data processing platform with an embedded distributed messaging queue. It is made to eliminate the heavy-lifting tasks for in-app streaming use cases.&lt;/p&gt;

&lt;p&gt;Memphis is cloud native. It thrives by offering a Real-Time Data Processing Platform for the producer-consumer paradigm.&lt;/p&gt;

&lt;h5&gt;
  
  
  What makes Memphis special
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Memphis is a distributed message broker built for async communication&lt;/li&gt;
&lt;li&gt;It supports numerous &lt;a href="https://docs.memphis.dev/memphis-new/deployment/cloud-deployment" rel="noopener noreferrer"&gt;Cloud Deployment&lt;/a&gt; platforms.&lt;/li&gt;
&lt;li&gt;Unlike other message brokers and queues that use topics and queues, Memphis uses stations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A station provides easy-to-use messaging queues. It abstracts you from creating a never-ending stream of producers, consumers, orchestrations, manual scaling, and decentralized monitoring. A station handles all this for you. And that's what makes Memphis a unique platform. &lt;a href="https://docs.memphis.dev/memphis-new/dashboard-ui/stations" rel="noopener noreferrer"&gt;Check out how to create a station&lt;/a&gt; in just a few clicks.&lt;/p&gt;

&lt;p&gt;Here is a basic example of Memphis station at work:&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%2Fvxqmbwyu1ovb4n5nx8tr.jpeg" 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%2Fvxqmbwyu1ovb4n5nx8tr.jpeg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Memphis is great for cloud-native app development. It uses modern tools to create a development stack. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker - Allows your application to leverage the virtualized containers and isolated resources and run microservices at scale.&lt;/li&gt;
&lt;li&gt;Kubernetes - It offers orchestration services that let you decide how and where to run your containers.&lt;/li&gt;
&lt;li&gt;Terraform - an IaC (Infrastructure as Code) tool that defines resources as code.&lt;/li&gt;
&lt;li&gt;Node.js support. Node.js is a popular JavaScript runtime. It is great for creating real-time applications and microservices of any kind. Node.js allows you to create virtual servers and routes for connecting microservices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Memphis has great support for &lt;a href="https://docs.memphis.dev/memphis-new/sdks/node.js-typescript" rel="noopener noreferrer"&gt;Node.js and Typescript&lt;/a&gt;. Check out &lt;a href="https://docs.memphis.dev/memphis-new/sdks/node.js-typescript" rel="noopener noreferrer"&gt;Memphis SDKs for Node.js and Typescript and start creating Producers/Consumers&lt;/a&gt;. Memphis also has support for other server-side languages such as &lt;a href="https://docs.memphis.dev/memphis-new/sdks/go" rel="noopener noreferrer"&gt;Go&lt;/a&gt; and &lt;a href="https://docs.memphis.dev/memphis-new/sdks/python" rel="noopener noreferrer"&gt;Python&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Have you deployed your Memphis message queue? Choose your preferred environment and run a Broker like never before. You can run Memphis on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.memphis.dev/memphis-new/deployment/kubernetes" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.memphis.dev/memphis-new/deployment/docker-compose" rel="noopener noreferrer"&gt;Docker-Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.memphis.dev/memphis-new/deployment/cloud-deployment" rel="noopener noreferrer"&gt;Cloud providers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Rabbitmq
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.rabbitmq.com/" rel="noopener noreferrer"&gt;RabbitMQ&lt;/a&gt; is an open-source distributed message broker. Due to the rise of the microservice architecture, where every concern has its own run time that scales independently, RabbitMQ is a tool that allows these microservices to communicate asynchronously with a variety of different protocols to run large-scale applications.&lt;/p&gt;

&lt;p&gt;RabbitMQ uses Advanced Message Queueing Protocol (AMQP). This allows middleware brokers such as RabbitMQ to conform with client applications and communicate effectively.&lt;/p&gt;

&lt;p&gt;RabbitMQ uses Exchanges to manage messages. When a producer sends a message, it is not registered immediately to the queue. The message is quickly registered to RabbitMQ Exchange, which uses bindings and routing keys to determine which queue a message belongs to. Here is a basic example of RabbitMQ infrastructure:&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%2Fpxeda9mdd7x0777qovk7.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%2Fpxeda9mdd7x0777qovk7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cloudamqp.com/blog/part1-rabbitmq-for-beginners-what-is-rabbitmq.html" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check this guide and learn &lt;a href="https://www.cloudamqp.com/blog/part1-rabbitmq-for-beginners-what-is-rabbitmq.html" rel="noopener noreferrer"&gt;what RabbitMQ is, and the important concept around it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;RabbitMQ uses distributed deployment mechanism. You can set up instances in a highly available manner. Just like Memphis, RabbitMQ is cloud available. This allows you to run a highly available cluster on top of infrastructure such as &lt;a href="https://www.rabbitmq.com/kubernetes/operator/operator-overview.html" rel="noopener noreferrer"&gt;kubernetes&lt;/a&gt; in the cloud.&lt;/p&gt;

&lt;p&gt;Leveraging such features creates huge cross-language support for favourite programming languages suitable for developing scalable apps. You can run your cloud support RabbitMQ architecture with popular Node.js and take advantage of its features.&lt;/p&gt;

&lt;p&gt;Here are &lt;a href="https://www.rabbitmq.com/devtools.html#node-dev" rel="noopener noreferrer"&gt;RabbitMQ features that you can comfortably run with Node.js&lt;/a&gt;&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%2Fpy4a3zzui02vrzf4xexf.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%2Fpy4a3zzui02vrzf4xexf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.rabbitmq.com/devtools.html#node-dev" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Kafka
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://kafka.apache.org/" rel="noopener noreferrer"&gt;Kafka&lt;/a&gt; is a distributed platform for pushing events for high-performance data pipelines. &lt;a href="https://kafka.apache.org/" rel="noopener noreferrer"&gt;Over 80% of all Fortune 100 organizations use Kafka&lt;/a&gt; to run their infrastructure events.&lt;/p&gt;

&lt;p&gt;These events are generated from different services. Kafka then streams and persists these events to other targets. Kafka is made to connect hundreds of event sources.&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%2Fz732a9l01ftyw50uk0iq.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%2Fz732a9l01ftyw50uk0iq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.confluent.io/what-is-apache-kafka/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kafka is well known for her performance. As a distributed platform, building a message queuing system on top of Kafka becomes very easy. Check this &lt;a href="https://www.projectpro.io/article/apache-kafka-architecture-/442" rel="noopener noreferrer"&gt;A-Z Guide and learn about Apache Kafka Architecture and Its Components&lt;/a&gt;.&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%2Fbgp0mtaps5esvqrqaqnl.jpeg" 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%2Fbgp0mtaps5esvqrqaqnl.jpeg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unixcop.com/kafka-and-zookeeper-ha-cluster-setup/" rel="noopener noreferrer"&gt;Image source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To build scale and speed streaming events, Kafka has five core functions. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kafka.apache.org/documentation/#theproducer" rel="noopener noreferrer"&gt;Publisher&lt;/a&gt; - This forms the data source that publishes streams of events to Kafka topics.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kafka.apache.org/documentation/#theconsumer" rel="noopener noreferrer"&gt;Consumer&lt;/a&gt; - forms a subscribed application that takes data from any subscribed Kafka topics.&lt;/li&gt;
&lt;li&gt;Process - Kafka uses &lt;a href="https://kafka.apache.org/32/documentation/streams/" rel="noopener noreferrer"&gt;streams API&lt;/a&gt; as a processor. This allows Kafka to consume incoming events from different sources and produce the outgoing data stream to one or more topics.&lt;/li&gt;
&lt;li&gt;Connect - &lt;a href="https://www.confluent.io/blog/kafka-connect-tutorial/#:~:text=Kafka%20Connect%20is%20the%20pluggable,with%20topics%20full%20of%20events" rel="noopener noreferrer"&gt;Kafka Connect&lt;/a&gt; allows you to scale streaming data between Apache Kafka and other systems. This links Kafka topics to existing applications and brings data to the Kafka cluster and from other external sources.&lt;/li&gt;
&lt;li&gt;Store - Kafka provides a major data storage tool for your events.&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%2F58l3trcg2trc9mvaeu5e.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%2F58l3trcg2trc9mvaeu5e.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.confluent.io/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what makes Kafka popular?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some advantages that make Kafka popular include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;High Throughput&lt;/li&gt;
&lt;li&gt;Low Latency&lt;/li&gt;
&lt;li&gt;Fault Tolerance&lt;/li&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;li&gt;Durability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite its popularity and advantages, Kafka is a challenging infrastructure to set up, deploy, scale and manage for on-premises production.&lt;/p&gt;

&lt;p&gt;To avoid such challenges, Kafka is now built and can be &lt;a href="https://www.cloudkarafka.com/" rel="noopener noreferrer"&gt;managed as a service in the cloud&lt;/a&gt;. This allows the cloud to perform hard tasks, such as complex cluster sizing and provisioning, building, and maintaining the Kafka infrastructure. Instead, you focus on building your application logic as the cloud handles the heavy lifting. This makes it easy to deploy Kafka without requiring specific Kafka infrastructure management expertise.&lt;/p&gt;

&lt;p&gt;To showcase your producers and consumers, Kafka supports various programming languages. Kafka cloud platforms, such as &lt;a href="https://developer.confluent.io/get-started/nodejs/" rel="noopener noreferrer"&gt;Confluent Cloud&lt;/a&gt;, allow you to build and consume Kafka using Node.js.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Strimzi
&lt;/h4&gt;

&lt;p&gt;Given that many message queue technologies are leveraging dynamic technologies such as Kubernetes. We have seen it's easier to run your Kafka streams using a cloud-native platform. &lt;a href="https://strimzi.io/" rel="noopener noreferrer"&gt;Strimzi&lt;/a&gt; provides deployment configurations for Kafka. Strimzi allows you to run Apache Kafka cluster on Kubernetes. This allows you to spread brokers across availability zones and dedicated nodes.&lt;/p&gt;

&lt;p&gt;Strimzi is a &lt;a href="https://www.cncf.io/" rel="noopener noreferrer"&gt;Cloud Native Computing Foundation&lt;/a&gt; sandbox project. Basically, it bridges &lt;a href="https://strimzi.io/docs/operators/in-development/overview.html" rel="noopener noreferrer"&gt;Kube-native management of Kafka's wide features&lt;/a&gt; such as cluster, topics, users, Kafka MirrorMaker and Kafka Connect. This way, you can expose Kafka outside Kubernetes using NodePort, OpenShift Routes, Ingress, and Load balancer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tulios/kafkajs/issues/1251" rel="noopener noreferrer"&gt;Once Kafka runs on Kube-native support that Strimzi offers&lt;/a&gt;, you can now start utilizing Node.js to create your streams and use libraries such as &lt;a href="https://kafka.js.org/docs/getting-started" rel="noopener noreferrer"&gt;KafkaJS&lt;/a&gt;, a modern Apache Kafka client for Node.js.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Redpanda
&lt;/h4&gt;

&lt;p&gt;Kafka architecture uses Zookeeper to keep track of a cluster of Kafka brokers.&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%2Fphlkj4com4aqhpecvu0u.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%2Fphlkj4com4aqhpecvu0u.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unixcop.com/kafka-and-zookeeper-ha-cluster-setup/" rel="noopener noreferrer"&gt;Image source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://redpanda.com/" rel="noopener noreferrer"&gt;Redpanda&lt;/a&gt; is a streaming data platform that is Kafka-API compatible, ZooKeeper-free, and JVM-free. Kafka API is great. &lt;a href="https://redpanda.com/blog/redpanda-vs-kafka-faster-safer" rel="noopener noreferrer"&gt;Redpanda is built to make Kafka fast&lt;/a&gt;. Redpanda allows you to pick the deployment option that best suits your needs.&lt;/p&gt;

&lt;p&gt;This include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.redpanda.com/docs/deployment/production-deployment/" rel="noopener noreferrer"&gt;Using Terraform and Ansible&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.redpanda.com/docs/deployment/kubernetes-connectivity/" rel="noopener noreferrer"&gt;Configuring the Kubernetes Operator for Connectivity&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its capacity to utilize infrastructure such as Kubernetes allows you to run &lt;a href="https://docs.redpanda.com/docs/quickstart/kubernetes-qs-cloud/" rel="noopener noreferrer"&gt;Kubernetes on Cloud&lt;/a&gt; and access Redpanda outside the Kubernetes network.&lt;/p&gt;

&lt;p&gt;Redpanda allows you to create &lt;a href="https://docs.redpanda.com/docs/quickstart/kubernetes-qs-cloud/#create-a-kubernetes-cluster" rel="noopener noreferrer"&gt;Kubernetes cluster and run your broker using cloud providers&lt;/a&gt; such as Google Kubernetes Engine, Amazon EKS, and DigitalOcean.&lt;/p&gt;

&lt;p&gt;Redpanda, being Kafka API compatible, allows you leverage to the countless client libraries created for Kafka, such as &lt;a href="https://kafka.js.org/docs/getting-started" rel="noopener noreferrer"&gt;KafkaJS client for Node.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check this guide and learn &lt;a href="https://docs.redpanda.com/docs/development/guide-nodejs/" rel="noopener noreferrer"&gt;how to use Node.js with Redpanda&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;There are many Message Queues that you can use. However, a message queue running as cloud-native outstands the rest. It gives you the capacity to run servers queuing with scalability at the core. This article helped you learn more about cloud-native MQs and the best choices you can use with Node.js.&lt;/p&gt;

</description>
      <category>node</category>
      <category>cloudnative</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>5 enhancements that will boost your Node.js app</title>
      <dc:creator>Rose Chege</dc:creator>
      <pubDate>Thu, 18 Aug 2022 10:13:00 +0000</pubDate>
      <link>https://forem.com/chegerose/5-enhancements-that-will-boost-your-nodejs-app-3pj5</link>
      <guid>https://forem.com/chegerose/5-enhancements-that-will-boost-your-nodejs-app-3pj5</guid>
      <description>&lt;p&gt;During your application workflows, there are many aspects needed to ensure the code you write executes with efficiency at its best. Consider you have built a Node.js application. Upon production deployment, you realize your application is getting a lot slower and slower.&lt;/p&gt;

&lt;p&gt;Well, at this point, the question running in your mind is what can you do to speed up and run your Node.js app faster? In this article, we will discuss tips and tools you need to massively scale and speed up the Node.js applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;An overview&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/en/docs/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; is an open-source cross-platform runtime environment for JavaScript. It is used for running server-side applications. Node.js is used to build applications of all levels that require a data-intensive model.&lt;/p&gt;

&lt;p&gt;Node.js is dominant in the field of server-side web development. It ranks as one of the most popular Web frameworks and technologies. This &lt;a href="https://survey.stackoverflow.co/2022/#most-popular-technologies-webframe" rel="noopener noreferrer"&gt;Stack Overflow survey&lt;/a&gt; gives a transparent look at how Node.js contests with other server-side technologies such as Django, Laravel, Ruby on rails, and Flask.&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%2F4ixivgwfz73ayufqec85.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%2F4ixivgwfz73ayufqec85.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://survey.stackoverflow.co/2022/#most-popular-technologies-webframe" rel="noopener noreferrer"&gt;ImageSource&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are justifications behind of tremendous popularity of Node.js. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node.js is very easy to understand. Node.js is built with JavaScript bare bones, the &lt;a href="https://survey.stackoverflow.co/2022/#most-popular-technologies-language" rel="noopener noreferrer"&gt;commonly used programming language&lt;/a&gt;. Due to JavaScript's popularity, it becomes relatively easy to get you up and running with Node.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node.js has a giant ecosystem, the Node Package Manager (NPM). &lt;a href="https://survey.stackoverflow.co/2022/#most-popular-technologies-tools-tech" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; is a Node.js registry that allows the use and access of open source libraries that cover the entire Node.js web development pipeline. These libraries allow you to install code that you can use on the fly. This conclusively saves a lot of development time while still delivering light, scalable, and high-speed apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node.js is blazingly light and fast, allowing developers to create high-performant applications. It is built on a high-performance &lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8 engine&lt;/a&gt; to compile and executes the JavaScript code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a developer, you want to exclusively exploit the Node.js capacity to build highly scalable applications. Nevertheless, you need different tools to ensure your Node.js applications run even faster. Let\'s discuss tips and tools developers can use to optimize and boost the already fast architecture that Node.js delivers.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How to boost your Node.js app?&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Using a message broker&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A message broker is a software that provides stable, reliable communication between two or more applications/subsets of an application. Basically, a message broker runs an architecture technique that allows you to break applications apart while still ensuring asynchronous communication.&lt;/p&gt;

&lt;p&gt;In this case, a message is the piece of information that you want to get processed from one application to another. A broker acts as a medium where actual data payloads are transmitted between the applications. A message broker uses a queue system to hold. It manages queues with the order they are received and delivers them to the actual party.&lt;/p&gt;

&lt;p&gt;Here is a general architecture of how a message broker works:&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%2Fhy0qckcoym517h798w86.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%2Fhy0qckcoym517h798w86.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have an idea of what a message broker is. How does it enhance the scalability of an application? To answer this question, let\'s learn the higher-level advantages that a message broker offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Simplified Decoupling - A message broker eliminates the dependencies between applications. A message broker act as the middleman between a client and the server. It\'s the work of the server to send data to a broker. A server doesn\'t have to be in direct contact with its message recipient. When the client needs the data, it just gets the messages from the broker at any time. It is not essential to use a discovery methodology to identify the location of server instances. The message broker takes care of these situations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased Architectural Reliability - The server can send messages whether or not the client is active and vice versa. The only component that must be running is a message broker. When a server sends messages, its job is done. It is now the work of the broker to deliver the messages to the appropriate recipients.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous Processing - Assume you are running a Node.js full-scale API using the REST architecture. The server and client are tightly coupled together to make requests and responses and exchange data. The two communicate directly using designated endpoints based on the HTTP protocol. What happens here is if the client sends a request, it expects an immediate response from the server. A REST communication is synchronously designed. It works with pre-defined requests that must return a response. If the response fails, undesirable user experiences can happen, such as a timeout error. On the other side, message brokers are Asynchronous. No one has to wait. Timeout errors can never occur in such architectures.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How does this benefit your Node.js apps?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Improved system performance - Message brokers use message queues for asynchronous communication. High-demand processes can be isolated into independent processes. This ensures data transfer is optimized as no system component is ever held up while waiting for the other. That will help accelerate your application performance and enhance the user experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability - The server and the client can all expand and contract in response to data demands. Components can keep adding entries to the queue even when demand peaks without fearing the system crash. Likewise, clients can be scaled up and workload distributed based on incoming data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great examples of message brokers can be found in this &lt;a href="https://github.com/aliyr/Nodejs-Developer-Roadmap" rel="noopener noreferrer"&gt;repo&lt;/a&gt;, and a new one I recently found is &lt;a href="https://memphis.dev" rel="noopener noreferrer"&gt;Memphis&lt;/a&gt;. It\'s a great fit for node.js/typescript/NestJS (Read more here [Memphis SDKs for Node.js/Typescript] &lt;a href="https://docs.memphis.dev/memphis-new/sdks/node.js-typescript)" rel="noopener noreferrer"&gt;https://docs.memphis.dev/memphis-new/sdks/node.js-typescript)&lt;/a&gt;) with a modern dev-first approach.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Build Node.js with gRPC&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://grpc.io/" rel="noopener noreferrer"&gt;gRPC&lt;/a&gt; is an open-source remote procedure call (RPC) framework used to build scalable fast communication microservices. It helps you create a high-performant communication protocol between services. An RPC framework uses a client to directly invoke a function on the server. In simple terms, RPC is a protocol that allows a program to execute a procedure of another program located on another computer without explicitly coding the details of the network interaction. It\'s automatically handled by the underlying framework.&lt;/p&gt;

&lt;p&gt;What makes the gRPC framework special?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It uses the HTTP/2 protocol. Architectures such as REST use the traditional HTPP 1.1 as the transfer protocol. This protocol is based on a request-response model using generic HTTP methods, such as GET, POST, PUT, and DELETE. If many clients submit requests, they are each accepted one at a time. HTTP/2 protocol supports a bidirectional communication model alongside the request-response model. It is possible to serve multiple requests and responses simultaneously. This creates a loose coupling between server and client, allowing you to build fast and efficient applications that support streaming with low latency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It uses &lt;a href="https://developers.google.com/protocol-buffers/docs/overview" rel="noopener noreferrer"&gt;Protocol buffers&lt;/a&gt; (protobuf) as the message format. When exchanging data using a SOAP protocol, the exchange of information happens over XML. When using REST, the data are exchanged using JSON format. In gRPC, data is exchanged over protocol buffers. Protocol buffers are lightweight, faster, and efficient as compared to both XML and JSON. It has fewer payloads. Under the hood, it performs serialization of the structured data. The protobuf compiler turns the data structure into the protobuf binary format, which is used to describe the communication format between the client and the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Language agnostic - The majority of modern languages and frameworks largely support gRPC, such as Node.js, Python, Go Java, PHP, and C#. A client and the server can be built with different languages/frameworks. It is more flexible than conventional APIs since clients can use any function, not only the typical GET, POST, and DELETE methods.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How does running Node.js with gRPC benefit your application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Faster communication - gRPC uses HTTP/2. This minimizes latency and network bandwidth usage to ensure a smoother user experience. At the same time, it is API-driven, which provides you flexibility in interface design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased application performance - REST uses synchronous calls. This ensures that the server has returned a response before execution continues. However, gRPC Asynchronous queries return instantaneously, and the response is processed as an independent task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lightweight messages - Protocol buffers are considered smaller compared to JSON messages with a &lt;a href="https://auth0.com/blog/beating-json-performance-with-protobuf/" rel="noopener noreferrer"&gt;difference of up to 30 percent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;gRPC and Message Brokers help you handle and manage your application messages. Check &lt;a href="https://memphis.dev/blog/grpc-vs-message-broker/" rel="noopener noreferrer"&gt;how gRPC compares to Message Broker&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Optimizing Node.js with clustering&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Node.js is single-threaded. It uses only one CPU to execute an application by default. This means if you have 8 CPUs on your machine,&lt;a href="https://nodejs.org/docs/latest-v17.x/api/worker_threads.html" rel="noopener noreferrer"&gt;Node.js threads&lt;/a&gt; are spawned to only utilize one CPU even when performing CPU-intensive operations. This hinders the application from utilizing the full power the underlying bare metals have which can lead to a server deadlock situation.&lt;/p&gt;

&lt;p&gt;To solve this, Node.js uses clusters. A cluster is a group of node instances running on a computer. In this case, Node.js uses the main CPU as its master instance and other available CPUs as the worker instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/api/cluster.html#how-it-works" rel="noopener noreferrer"&gt;Node.js clustering&lt;/a&gt; allows networked Node.js applications to be scaled across the number of available CPUs. Here is a basic example of node clustering.&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%2F3awufvb18b0xx55ngmf5.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%2F3awufvb18b0xx55ngmf5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pm2.keymetrics.io/docs/usage/cluster-mode/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This computer has 4 processors. By default, Node.js's single-threaded nature will only utilize one the CPU. However, we can spawn tasks across the available CPUs using the Node.js &lt;a href="https://nodejs.org/api/cluster.html" rel="noopener noreferrer"&gt;cluster module&lt;/a&gt; under the hood. Node.js can run the child process and share the server ports while still being able to communicate with the parent Node process. Depending on the number of CPUs provided, it significantly boosts the performance, efficiency, and reliability of your application.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4. Load balancing&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Let's assume you have a web app, an online shop to be specific. Users will access your shop using a domain name. This domain will communicate with the server to get things done on the user\'s end. However, when you have large traffic accessing your online shop, the demand for resources will increase.&lt;/p&gt;

&lt;p&gt;You may be required to set up an additional server to distribute the traffic. A situation that will make you have multiple replicas of your application. But how do you instruct the users to use the resources from replica servers? If they all connect to the initial server, then you will run out of resources, leaving you with other instances servers unutilized.&lt;/p&gt;

&lt;p&gt;At this point, what you need is to balance the traffic to access all servers. And what you are exactly doing is load balancing to distribute the traffic evenly. This gives an optimal performance of your application and ensures no node is getting overloaded.&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%2F1pb2ndh364gyzp5okvss.jpg" 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%2F1pb2ndh364gyzp5okvss.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codeburst.io/load-balancers-an-analogy-cc64d9430db0" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Load balancing is a process of distributing application tasks within a given set of resources to ensure efficient usability of overall resources. This way, all your client requests get evenly and equally distributed to the backend nodes managing your application.&lt;/p&gt;

&lt;p&gt;It is essential to have a load balancer configured to your Node.js in order to scale your deployment based on the resources demand. One of the popular tools used to deploy Load Balancing in Node.js is &lt;a href="https://docs.nginx.com/nginx/deployment-guides/load-balance-third-party/node-js/#configuring-basic-load-balancing" rel="noopener noreferrer"&gt;NGINX&lt;/a&gt;. Nginx is an Open Source tool that allows you to configure HTTP and HTTPS Servers for the client traffic.&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%2Fg74nv632n7kpwgq418gs.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%2Fg74nv632n7kpwgq418gs.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://faun.pub/how-to-configure-nginx-as-a-load-balancer-docker-flask-nginx-de95766b749b" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By disrupting traffic, a load balancer can prevent application failure and increase performance and availability. How does building Node.js Distributed systems with a load balancer benefits your application?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Horizontal Scalability - Distributing your application instance allows it to manage a broader amount of incoming requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced server downtime&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flexibility&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redundancy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Efficiency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;5. Caching&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Caching is the temporary storing of data that is likely to be accessed repetitively. This practice uses a memory buffer to temporarily save application lookups.&lt;/p&gt;

&lt;p&gt;A cache streamlines service delivery by ensuring any repetitive task is not retrieved from the server but a memory buffer. This way, if a request is by the client, it will first check any lookups saved in the cache without hitting the server.&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%2Fxz4shr6ilfl6erpdc98j.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%2Fxz4shr6ilfl6erpdc98j.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://allmywebneeds.com/web-design/what-is-caching-and-why-do-i-need-it-for-my-website-server-side-caching-explained" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When running a server that delivers frequently requested resources from the same request, it increases data delays to the clients. Serving such computations from a cache layer allows you to deliver data and respond to requests with minimum delays.&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%2Fguzop60rtepxixs65qcn.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%2Fguzop60rtepxixs65qcn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://allmywebneeds.com/web-design/what-is-caching-and-why-do-i-need-it-for-my-website-server-side-caching-explained" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first time a request is sent and a call made to the server is called a cache miss. The output will be saved in the cache before returning the data to the user.&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%2Fxv4ckngeeugspt35gchn.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%2Fxv4ckngeeugspt35gchn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tcpwave.com/WHITE-PAPERS/cache-hit-ratio.htm" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the requested data is found in the cache memory, It\'s called a cache hit. The result will be returned from the cache store and the complex data query doesn\'t need to be processed again.&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%2Fhlz2pauhwsoef4wvz7ls.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%2Fhlz2pauhwsoef4wvz7ls.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tcpwave.com/WHITE-PAPERS/cache-hit-ratio.htm" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important to always check the cache hit rates and polish the caching strategy accordingly. A cache layer is not infinite. Therefore, you need effective cache management. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Invalidate a cache after a certain period.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Removing cache to ensure &lt;a href="https://www.cloudflare.com/learning/cdn/what-is-a-cache-hit-ratio/#:~:text=Cache%20hit%20ratio%20is%20a,a%20high%20cache%20hit%20ratio." rel="noopener noreferrer"&gt;caching hit ratio&lt;/a&gt; remains high.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invalidate a cache below certain usage thresholds.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Distributed systems need to complete many API calls to match a single response payload. Running such calls with a cache drastically reduces the cost of data aggregation. Running such Node.js tasks caching can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Greatly reduce the data query response time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improve the scalability of an application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced server load which greatly increases server performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Caching improves database performance. A cached request doesn't have to hit the server, meaning the data request query doesn't have to access your database layer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Node.js caching tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-implement-caching-in-node-js-using-redis" rel="noopener noreferrer"&gt;Redis Cache&lt;/a&gt;. Redis uses an in-memory database to store the entire data set, reducing the extra cost of a lookup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using caching reverse proxy, such as &lt;a href="https://www.sitepoint.com/how-to-boost-your-server-performance-with-varnish/" rel="noopener noreferrer"&gt;Varnish Cache&lt;/a&gt;. Vanish is an HTTP accelerator tool that allows you to save your server-side requests and responses to reduce the loading times of your Node.js server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using Node.js App server &lt;a href="https://github.com/BackendStack21/http-cache-middleware" rel="noopener noreferrer"&gt;HTTP Cache Middleware&lt;/a&gt;. It allows you to add a Cache Middleware that connects with the Node.js HTTP to reduce API latency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using &lt;a href="https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/#:~:text=Cache%20both%20static%20and%20dynamic,the%20load%20on%20the%20servers." rel="noopener noreferrer"&gt;Nginx for content caching&lt;/a&gt;. Nginx caches content of application servers, both static and dynamic, to streamline the client delivery and reduce server load.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Other practices to power up your Node.js app&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are many practices that you can use and ensure Node.js scales your&lt;br&gt;
application. Other practices and tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Practicing &lt;a href="https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/" rel="noopener noreferrer"&gt;asynchronous executions&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.twilio.com/blog/guide-node-js-logging" rel="noopener noreferrer"&gt;Logging&lt;/a&gt; and &lt;a href="https://blog.risingstack.com/monitoring-nodejs-applications-nodejs-at-scale/" rel="noopener noreferrer"&gt;monitoring&lt;/a&gt; your application performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing light and compact code and ensuring you eliminate lines of codes and unused library components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Practicing &lt;a href="https://redis.io/docs/reference/optimization/memory-optimization/" rel="noopener noreferrer"&gt;memory optimization&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://thriveread.com/nodejs-https-server-with-express-and-createserver/" rel="noopener noreferrer"&gt;Running Node.js using SSL/TLS, HTTPS and HTTP/2&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhancing data handling techniques, for example, &lt;a href="https://hasura.io/learn/graphql/intro-graphql/graphql-vs-rest/" rel="noopener noreferrer"&gt;GraphQL vs. REST&lt;/a&gt; designs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making use of &lt;a href="https://thriveread.com/enabling-nestjs-cors-on-graphql-and-websockets/" rel="noopener noreferrer"&gt;Web Sockets&lt;/a&gt; to improve server communication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the &lt;a href="https://github.com/expressjs/compression" rel="noopener noreferrer"&gt;Node.js Deflate and Gzip compression middleware&lt;/a&gt; to compress server requests and responses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Building an application is the first step to connecting with your users. Your application requires day-to-day maintenance to maintain a steady experience for these users. This guide helped you learn some of the common strategies and enhancement tools that you can use to boost your Node.js apps.&lt;/p&gt;

</description>
      <category>node</category>
      <category>performance</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Commerce platform for Vue Storefront: Use Medusa with Vue Storefront UI</title>
      <dc:creator>Rose Chege</dc:creator>
      <pubDate>Mon, 04 Jul 2022 16:49:50 +0000</pubDate>
      <link>https://forem.com/medusajs/how-to-create-an-ecommerce-store-with-vue-storefront-ui-and-medusa-37jp</link>
      <guid>https://forem.com/medusajs/how-to-create-an-ecommerce-store-with-vue-storefront-ui-and-medusa-37jp</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/medusajs/medusa"&gt;Medusa&lt;/a&gt; is a rising ecommerce platform that fits all businesses. Medusa is an open source composable ecommerce platform with easy customizations and integrations. Medusa comes with a lot of &lt;a href="https://github.com/medusajs/medusa#features"&gt;ecommerce features&lt;/a&gt; that provide flexibility to both merchants and developers.&lt;/p&gt;

&lt;p&gt;Having a headless architecture, Medusa’s frontend and backend are decoupled. This gives developers the freedom to choose what frontend framework or tool they use to build their storefront.&lt;/p&gt;

&lt;p&gt;One option is using the &lt;a href="https://docs.storefrontui.io/?path=/docs/welcome--page"&gt;Vue Storefront UI&lt;/a&gt;. It provides out-of-the-box customizable and performance-oriented components. You can use them in a Nuxt.js project to build stunning modern online stores.&lt;/p&gt;

&lt;p&gt;In this article, you’ll learn how to use Vue Storefront UI to build a storefront for your Medusa server. You can find the full code of the storefront on this &lt;a href="https://github.com/Rose-stack/Vue-js-storefront-with-a-Medusa-Server"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VMy_9qz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz7z0xvyvbgikm0p8az1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VMy_9qz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz7z0xvyvbgikm0p8az1.gif" alt="Storefront Demo" width="640" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To follow along with this guide, it's essential to have &lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; installed on your machine with at least version 14.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Set Up the Medusa Server&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To create the Medusa server, you need the Medusa CLI tool. Run the following command to install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @medusajs/medusa-cli &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, run the following command to create the Medusa server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;medusa new local-medusa-server --seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--seed&lt;/code&gt; command populates an SQLite database with some test data once the setup is done.&lt;/p&gt;

&lt;p&gt;Then, change to the newly created directory and start your medusa server:&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;local-medusa-server &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; medusa develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test if the server is working, open &lt;code&gt;http://localhost:9000/store/products&lt;/code&gt; in your browser. You should get a similar response as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fdoH5OU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpdv5bkonomb40jml3ih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fdoH5OU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpdv5bkonomb40jml3ih.png" alt="Products Response" width="880" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, it’s recommended to install a storage plugin to add products. You can use &lt;a href="https://docs.medusajs.com/add-plugins/minio"&gt;MinIO&lt;/a&gt;, &lt;a href="https://docs.medusajs.com/add-plugins/s3"&gt;S3&lt;/a&gt;, or &lt;a href="https://docs.medusajs.com/add-plugins/spaces"&gt;Spaces&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Medusa Admin
&lt;/h2&gt;

&lt;p&gt;Medusa provides a prebuilt &lt;a href="https://docs.medusajs.com/admin/quickstart"&gt;admin dashboard&lt;/a&gt; that assists you in configuring and managing the products you have in your store. However, this is a complete optionally set up that you can choose to use in this tutorial. &lt;/p&gt;

&lt;p&gt;To install the Medusa admin, open a new directory and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/medusajs/admin medusa-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation process is done, change to the newly created directory &lt;code&gt;medusa-admin&lt;/code&gt; and install the dependencies with NPM:&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;medusa-admin &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure the Medusa server is still running. Then, run the Medusa admin with 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;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now access Medusa admin on &lt;code&gt;http://localhost:7000/&lt;/code&gt;. If you seeded your database with demo data using the &lt;code&gt;--seed&lt;/code&gt; option when you created your Medusa admin, you can log in using the email &lt;code&gt;admin@medusa-test.com&lt;/code&gt; and password &lt;code&gt;supersecret&lt;/code&gt;. Otherwise, you can use the &lt;code&gt;[user&lt;/code&gt; command provided by the Medusa CLI tool](&lt;a href="https://docs.medusajs.com/cli/reference#user"&gt;https://docs.medusajs.com/cli/reference#user&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;After logging in, navigate to the Products menu. You can add a few products from here by clicking on “New Product” at the top right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wrsT2JVW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjpexujwv7n8kksz2ad6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wrsT2JVW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjpexujwv7n8kksz2ad6.jpg" alt="Products Page" width="880" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the form, you can specify many information related to the product such as name, handle, description, weight, and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ugifmsdc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vd0b3behu3wgpdcs3pd2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ugifmsdc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vd0b3behu3wgpdcs3pd2.jpg" alt="Product Form" width="880" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To learn more about the features in the &lt;a href="https://docs.medusajs.com/admin/quickstart/"&gt;&lt;/a&gt;Medusa admin, check out the &lt;a href="https://docs.medusajs.com/admin/quickstart/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Setting up the Nuxt.js Storefront&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a different directory than the previous directories, run the following command to create a Nuxt.js website:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-nuxt-app nuxtjs-storefront
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be asked a few questions. You can answer as instructed in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9rKC8SzU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3seav9b2xuikqudfjc32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9rKC8SzU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3seav9b2xuikqudfjc32.png" alt="Nuxt.js Setup Questions" width="621" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to change the package manager to either NPM or Yarn based on your preference.&lt;/p&gt;

&lt;p&gt;When the installation process is done, proceed to the newly created folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd nuxtjs-storefront
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Connect the Vue Storefront to the Medusa Server&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To start off, you need to install the &lt;a href="https://www.npmjs.com/package/axios"&gt;Axios&lt;/a&gt; package. Axios is an HTTP package for making requests. Axios will process the requests between the Medusa server and the Storefront. &lt;/p&gt;

&lt;p&gt;Run the following command to install it in the &lt;code&gt;nuxtjs-storefront&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-s&lt;/span&gt; axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the installation is done, you need to configure the Nuxt.js storefront to use the &lt;code&gt;8000&lt;/code&gt; port. This is because the Medusa server uses CORS to ensure only defined hosts access the server and the default port expected for the storefront is &lt;code&gt;8000&lt;/code&gt;. You can learn more about it in &lt;a href="https://docs.medusajs.com/usage/configurations#storefront-cors"&gt;Medusa’s documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add the following line after the &lt;code&gt;ssr&lt;/code&gt; key in the &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 jsx"&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="na"&gt;ssr&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="na"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8000&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, you need to add the URL to the Medusa server as an environment variable.&lt;/p&gt;

&lt;p&gt;Start by installing the &lt;code&gt;dotenv&lt;/code&gt; module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @nuxtjs/dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, register the installed &lt;code&gt;dotenv&lt;/code&gt; module in&lt;code&gt;nuxt.config.js&lt;/code&gt; file in the &lt;code&gt;buildModules&lt;/code&gt; array:&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="nx"&gt;buildModules&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;@nuxtjs/dotenv&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;Finally, create a &lt;code&gt;.env&lt;/code&gt; file at the root of your project directory and add your server URL as an environment variable:&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="nv"&gt;baseUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:9000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install Vue Storefront UI
&lt;/h3&gt;

&lt;p&gt;This tutorial uses &lt;a href="https://docs.storefrontui.io/?path=/docs/getting-started-installation--page"&gt;Vue Storefront UI&lt;/a&gt;. This means you don’t have to create components from scratch and can use the ready-made components provided by Vue Storefront UI.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;nuxtjs-storefront&lt;/code&gt; directory, run the following command to install Vue Storefront UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; @storefront-ui/vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Set up components and layout&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Vue app will have the following components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Navbar&lt;/strong&gt;: Used to display the logo and links in the header of the website&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ProductCard&lt;/strong&gt;: Used to display short information about the product.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footer&lt;/strong&gt;: Used to display helpful links to customers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create &lt;strong&gt;the Navbar component&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To create the Navbar component, create a file at &lt;code&gt;components/App/Navbar.vue&lt;/code&gt; with the following content:&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;template&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;SfHeader&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"shopLogo"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"shopName"&lt;/span&gt; &lt;span class="na"&gt;active-icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"account"&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;template&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="na"&gt;navigation&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;SfHeaderNavigationItemv&lt;/span&gt; &lt;span class="na"&gt;v-for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"(category, key) in navbarLinks"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"`sf-header-navigation-item-${key}`"&lt;/span&gt;
        &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"`${category.link}`"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"category.title"&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;template&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;SfHeader&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;template&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="p"&gt;&amp;gt;&lt;/span&gt;
  import &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;SfHeader&lt;/span&gt;
  &lt;span class="si"&gt;}&lt;/span&gt; from "@storefront-ui/vue";
  export default &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;SfHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;data&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="na"&gt;shopName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My Storefront App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;shopLogo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/logo.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;navbarLinks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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;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;script&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 is a basic component that defines the navigation of your page. The Vue Storefront UI provides a &lt;a href="https://docs.storefrontui.io/?path=/docs/components-organisms-header--common"&gt;SfHeader&lt;/a&gt; component. Inside that component, you can add other internal navigation components such as &lt;code&gt;SfHeaderNavigation&lt;/code&gt; and &lt;code&gt;SfHeaderNavigationItem&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;You can also pass the component props to customize it such as the title, logo, or icons in the navigation bar.&lt;/p&gt;

&lt;p&gt;Make sure you add the &lt;code&gt;logo.svg&lt;/code&gt; file to be displayed in the navigation bar. The logo should be added to the &lt;code&gt;static&lt;/code&gt; folder. If your logo has a different name, ensure you change that in the &lt;code&gt;shopLogo&lt;/code&gt; property in the &lt;code&gt;data&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create &lt;strong&gt;the Footer component&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, create the &lt;code&gt;components/App/Footer.vue&lt;/code&gt; file with the following content:&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;template&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;SfFooter&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;SfFooterColumn&lt;/span&gt; &lt;span class="na"&gt;v-for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"(column, key) in footerColumns"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"column.title"&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;SfList&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;SfListItem&lt;/span&gt; &lt;span class="na"&gt;v-for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"(menuItem, index) in column.items"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"index"&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;SfMenuItem&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"menuItem"&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;SfListItem&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;SfList&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;SfFooterColumn&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;SfFooter&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;template&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="p"&gt;&amp;gt;&lt;/span&gt;
  import &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;SfFooter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfMenuItem&lt;/span&gt;
  &lt;span class="si"&gt;}&lt;/span&gt; from "@storefront-ui/vue";
  export default &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;SfFooter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfMenuItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;data&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="na"&gt;footerColumns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;About us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;items&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="s2"&gt;Who we are&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Quality in the details&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Customer Reviews&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Departments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;items&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="s2"&gt;Women fashion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Men fashion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Kidswear&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Help&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;items&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="s2"&gt;Customer service&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Size guide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Contact us&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Payment &amp;amp; delivery&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;items&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="s2"&gt;Purchase terms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Guarantee&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;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;script&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;The Footer component just includes helpful links for your customer. The Vue Storefront UI library provides a predefined UI for footers using the &lt;a href="https://docs.storefrontui.io/?path=/docs/components-organisms-footer--common"&gt;SfFooter&lt;/a&gt; component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create &lt;strong&gt;the ProductCard component&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Create the &lt;code&gt;components/ProductCard.vue&lt;/code&gt; file with the following content:&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;template&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;SfProductCard&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"item.thumbnail"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;imageWidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"216"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;imageHeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"326"&lt;/span&gt; &lt;span class="na"&gt;badgeLabel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;badgeColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"item.title"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"this.url"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;linkTag&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"item.id"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;scoreRating&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"4"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;reviewsCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"7"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;maxRating&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;
    &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;regularPrice&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"this.highestPrice.amount"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;specialPrice&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"this.lowestPrice.amount"&lt;/span&gt; &lt;span class="na"&gt;wishlistIcon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"heart"&lt;/span&gt;
    &lt;span class="na"&gt;isInWishlistIcon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"heart_fill"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;isInWishlist&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="na"&gt;showAddToCartButton&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;isAddedToCart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
    &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;addToCartDisabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"false"&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;template&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;The product card uses the &lt;a href="https://docs.storefrontui.io/?path=/docs/components-organisms-productcard--common"&gt;SfProductCard&lt;/a&gt; component provided by Vue Storefront UI to display a short summary of a product’s information including the title, price, and thumbnail.&lt;/p&gt;

&lt;p&gt;Then, in the same file, add the following at the end of the file:&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="p"&gt;&amp;gt;&lt;/span&gt;
import &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SfProductCard&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt; from "@storefront-ui/vue"; // Import the components
export default &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ProductCard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="nx"&gt;SfProductCard&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&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="nb"&gt;Object&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="nx"&gt;computed&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="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`/products/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="c1"&gt;// Product page&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;lowestPrice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the lowest price from the list of prices.&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lowestPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;curr&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;return&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;lowest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lowest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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="nx"&gt;current&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="nx"&gt;lowest&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="na"&gt;amount&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="c1"&gt;// Format the amount and also add currency&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;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nx"&gt;lowestPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nx"&gt;lowestPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&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="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;currency_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="nx"&gt;highestPrice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the highest price from the list of prices&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;highestPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;curr&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;return&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;highest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;highest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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="nx"&gt;current&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="nx"&gt;highest&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="na"&gt;amount&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="c1"&gt;// Format the amount and also add currency&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;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nx"&gt;highestPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nx"&gt;highestPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&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="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;currency_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="si"&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="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script prepares the data to be displayed by the template. That includes formatting the price and URL of the component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create &lt;strong&gt;the Storefront Layout&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To set up the layout, create the file &lt;code&gt;layouts/default.vue&lt;/code&gt; with the following content:&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;template&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;app&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;navbar&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;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;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"container"&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;Nuxt&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;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;app&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;footer&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;template&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="p"&gt;&amp;gt;&lt;/span&gt;
  import "@storefront-ui/vue/styles.scss"; // vuestorefront UI styles.
  export default &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DefaultLayout&lt;/span&gt;&lt;span class="dl"&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;script&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 will display the page with the &lt;a href="https://docs.storefrontui.io/?path=/docs/layouts-default--default-story"&gt;default Vue Storefront UI layout&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Home Page
&lt;/h2&gt;

&lt;p&gt;Under the &lt;code&gt;pages&lt;/code&gt; directory, edit the &lt;code&gt;index.vue&lt;/code&gt; file to 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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;template&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="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"row"&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;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"col-md-12"&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;SfHero&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hero"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;slider-options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{ autoplay: false }"&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;SfHeroItem&lt;/span&gt;
            &lt;span class="na"&gt;v-for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"(img, index) in heroes"&lt;/span&gt;
            &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;
            &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img.title"&lt;/span&gt;
            &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img.subtitle"&lt;/span&gt;
            &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;button-text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img.buttonText"&lt;/span&gt;
            &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img.background"&lt;/span&gt;
            &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img.className"&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;SfHero&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="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"col-md-12"&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;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-center mt-5 mb-5"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;All Products&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="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="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;v-if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"products.length"&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;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"row"&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;ProductCard&lt;/span&gt; &lt;span class="na"&gt;v-for&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product in products"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product.id"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product"&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="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;template&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="p"&gt;&amp;gt;&lt;/span&gt;
import Axios from 'axios';
import &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SfHero&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt; from "@storefront-ui/vue";
export default &lt;span class="si"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ProductsIndex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;SfHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;data&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="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="na"&gt;heroes&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Colorful T-shirts already in store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JUNE COLLECTION 2022&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;buttonText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn more&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(236, 239, 241)&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Colorful Sweatshirts already in store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JUNE COLLECTION 2022&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;buttonText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn more&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(239, 235, 233)&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Colorful Sweatpants already in store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JUNE COLLECTION 2022&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;buttonText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn more&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(236, 239, 241)&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;span class="p"&gt;},&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="c1"&gt;// Fetching the products from Medusa server&lt;/span&gt;
        &lt;span class="k"&gt;try&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;data&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/store/products`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error occured&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&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;script&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 fetches products from the Medusa server using Axios and displays them using the &lt;code&gt;ProductCard&lt;/code&gt; component you created earlier.&lt;/p&gt;

&lt;p&gt;You also add a carousel using the &lt;a href="https://docs.storefrontui.io/?path=/docs/components-organisms-hero--common"&gt;SfHero&lt;/a&gt; component. It shows an automatic slider with buttons and text. Each slide is defined as a &lt;code&gt;SfHeroItem&lt;/code&gt; component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Home Page
&lt;/h3&gt;

&lt;p&gt;To test out the home page, make sure the Medusa server is running and start the Nuxt.js development server:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then, open &lt;code&gt;http://localhost:8000&lt;/code&gt; in a browser, you should see the home page with a carousel, products, and a footer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rVyIRmW0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr707ehzsj7uxrn1aefu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rVyIRmW0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr707ehzsj7uxrn1aefu.png" alt="Storefront Homepage" width="880" height="955"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Single Product Page
&lt;/h2&gt;

&lt;p&gt;In this section, you’ll create a single product page to display more details of a product.&lt;/p&gt;

&lt;p&gt;To create a single product page, Create the file &lt;code&gt;pages/products/_id.vue&lt;/code&gt; with the following content:&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;template&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;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product"&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;SfBreadcrumbs&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"breadcrumbs desktop-only"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;breadcrumbs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"breadcrumbs"&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;v-if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"$fetchState.pending"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Fetching Data...&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;p&lt;/span&gt; &lt;span class="na"&gt;v-else-if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"$fetchState.error"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;An error occurred :(&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="na"&gt;v-else&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product"&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;SfGallery&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"this.getImages"&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__gallery"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;image-width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"422"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;image-height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"664"&lt;/span&gt;
        &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;thumb-width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"160"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;thumb-height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"160"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;enableZoom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&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;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__info"&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;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__header"&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;SfHeading&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product.title"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sf-heading--no-underline sf-heading--left"&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;SfIcon&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"drag"&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"42px"&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#E0E0E1"&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__drag-icon smartphone-only"&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="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__price-and-rating"&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;SfPrice&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;regular&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"this.lowestPrice.amount"&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="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__description desktop-only"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&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;description&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;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="nc"&gt;SfAddToCart&lt;/span&gt; &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"qty"&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"product__add-to-cart"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"addToCart"&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="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;transition&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"slide"&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;SfNotification&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"notification desktop-only"&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;"success"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"isOpenNotification"&lt;/span&gt;
        &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"`${qty} ${product.title} has been added to CART`"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"isOpenNotification = true"&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;template&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="na"&gt;icon&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;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SfNotification&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;transition&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;template&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 page displays the following components from the Vue Storefront UI library:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.storefrontui.io/?path=/docs/components-atoms-breadcrumbs--common"&gt;SfBreadcrumbs&lt;/a&gt; - Displays the path to the current product.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.storefrontui.io/?path=/docs/components-molecules-gallery--common"&gt;SfGallery&lt;/a&gt; - Arranges product images that users can browse through with zoom-in functionality. Alternatively, you can use &lt;a href="https://docs.storefrontui.io/?path=/docs/components-organisms-carousel--common"&gt;Carousel navigation&lt;/a&gt; to organize your product images.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.storefrontui.io/?path=/docs/components-atoms-heading--common"&gt;SfHeading&lt;/a&gt;  - Displays product titles and can have an optional description.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.storefrontui.io/?path=/docs/components-atoms-price--common"&gt;SfPrice&lt;/a&gt; - Display the product’s price.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.storefrontui.io/?path=/docs/components-molecules-addtocart--common"&gt;SfAddToCart&lt;/a&gt; - Displays Add to Cart button with quantity options.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.storefrontui.io/?path=/docs/components-molecules-notification--common"&gt;SfNotification&lt;/a&gt; - Displays notification at the bottom of the page that indicates the items are added to the cart. This component is only used to simulate adding a product to the cart but this is not covered in this tutorial.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, add the following at the end of the same file:&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="p"&gt;&amp;gt;&lt;/span&gt;
  import &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// UI components&lt;/span&gt;
    &lt;span class="nx"&gt;SfGallery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfHeading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfIcon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfAddToCart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfBreadcrumbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SfNotification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="si"&gt;}&lt;/span&gt; from "@storefront-ui/vue";
  import Axios from "axios";
  export default &lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Product&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;SfGallery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfHeading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfIcon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfAddToCart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfBreadcrumbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;SfNotification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// default data&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;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;selected&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="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
          &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;regular&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="na"&gt;breadcrumbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="na"&gt;isOpenNotification&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="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;getImages&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Format Product images in a way that the component understands.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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="k"&gt;this&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;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&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="o"&gt;=&amp;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="na"&gt;mobile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;url&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="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="na"&gt;desktop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;url&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="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="na"&gt;big&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;url&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="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&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;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&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;title&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="p"&gt;[];&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;lowestPrice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the least price&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lowestPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&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;variants&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
          &lt;span class="k"&gt;this&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;variants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;curr&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;return&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;lowest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lowest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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="nx"&gt;current&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="nx"&gt;lowest&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="na"&gt;amount&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;span class="na"&gt;amount&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="c1"&gt;// Format the amount and append the currency.&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;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lowestPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nx"&gt;lowestPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&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="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="si"&gt;}&lt;/span&gt;,
    methods: &lt;span class="si"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;addToCart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isOpenNotification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// show notification&lt;/span&gt;
        &lt;span class="nx"&gt;setTimeout&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isOpenNotification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// hide notification&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="si"&gt;}&lt;/span&gt;,
    async fetch() &lt;span class="si"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Fetch the product based on the id.&lt;/span&gt;
      &lt;span class="k"&gt;try&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;data&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/store/products/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&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;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="k"&gt;this&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;=&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// eslint-disable-next-line no-console&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The server is not responding&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="si"&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="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This just imports the components used in the template, fetches the product’s information from the Medusa server, and formats the product’s information such as the price or URL before displaying them in the template.&lt;/p&gt;

&lt;p&gt;Finally, add the following styling at the end of the same file:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt; &lt;span class="nt"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"scss"&lt;/span&gt; &lt;span class="nt"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"~@storefront-ui/vue/styles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;#product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;for-desktop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1272px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-sm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;for-desktop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__info&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;for-desktop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;32.625rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;7.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="py"&gt;--heading-title-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--c-link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="py"&gt;--heading-title-font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-weight--bold&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="py"&gt;--heading-title-font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--h3-font-size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="py"&gt;--heading-padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-sm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;for-desktop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="py"&gt;--heading-title-font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-weight--semibold&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__drag-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;moveicon&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__price-and-rating&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-base&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;for-desktop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-lg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;font(&lt;/span&gt;
        &lt;span class="err"&gt;--count-font,&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-weight--normal),&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-size--sm),&lt;/span&gt;
        &lt;span class="err"&gt;1.4,&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-family--secondary)&lt;/span&gt;
        &lt;span class="err"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--c-text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__description&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--c-link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;font(&lt;/span&gt;
        &lt;span class="err"&gt;--product-description-font,&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-weight--light),&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-size--base),&lt;/span&gt;
        &lt;span class="err"&gt;1.6,&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-family--primary)&lt;/span&gt;
        &lt;span class="err"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__add-to-cart&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;for-desktop&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-2xl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__guide&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__compare&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__save&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-xl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__compare&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__property&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="err"&gt;&amp;amp;__button&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="py"&gt;--button-font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-size--base&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__additional-info&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--c-link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="err"&gt;@include&lt;/span&gt; &lt;span class="err"&gt;font(&lt;/span&gt;
        &lt;span class="err"&gt;--additional-info-font,&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-weight--light),&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-size--sm),&lt;/span&gt;
        &lt;span class="err"&gt;1.6,&lt;/span&gt;
        &lt;span class="err"&gt;var(--font-family--primary)&lt;/span&gt;
        &lt;span class="err"&gt;);&lt;/span&gt;
        &lt;span class="err"&gt;&amp;amp;__title&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-weight--normal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-size--base&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-sm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="err"&gt;&amp;amp;:not(:first-child)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="err"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__paragraph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;__gallery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.breadcrumbs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-lg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.notification&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="py"&gt;--notification-border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="py"&gt;--notification-max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="py"&gt;--notification-font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-size--lg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="py"&gt;--notification-font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-family--primary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="py"&gt;--notification-font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-weight--normal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="py"&gt;--notification-padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--spacer-lg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.slide-enter-active&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.slide-leave-active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.slide-enter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.slide-leave-to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-80px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;moveicon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate3d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate3d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate3d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&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="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test Single Product Page
&lt;/h3&gt;

&lt;p&gt;Make sure that both your Medusa server and Nuxt.js development servers are running. Then, go to &lt;code&gt;localhost:8000&lt;/code&gt; and click on a product on the home page. You’ll be redirected to the product’s page with more information about it.&lt;/p&gt;

&lt;p&gt;If you click the Add to Cart button, you’ll see a notification at the bottom of the page indicating you added the product to the cart. As mentioned earlier, this is only used for simulation and does not actually add the product to the cart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rg34NbVV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33a6bpgccofojccee1jf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rg34NbVV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33a6bpgccofojccee1jf.gif" alt="Single Product Page" width="640" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This tutorial only scratches the surface of what you can do with Medusa and Vue Storefront UI.&lt;/p&gt;

&lt;p&gt;With Medusa, you can implement other ecommerce features in your storefront such:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.medusajs.com/guides/carts-in-medusa"&gt;Cart functionalities and features&lt;/a&gt;. You can use &lt;a href="https://docs.storefrontui.io/?path=/docs/components-templates-cart--cart"&gt;Vue Storefront UI’s Cart component&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add Payment integrations with &lt;a href="https://docs.medusajs.com/add-plugins/stripe"&gt;Stripe&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.medusajs.com/advanced/storefront/how-to-implement-checkout-flow"&gt;Checkout flow&lt;/a&gt;. You can use Vue Storefront’s &lt;a href="https://docs.storefrontui.io/?path=/docs/components-pages-checkout--checkout"&gt;Checkout&lt;/a&gt; and &lt;a href="https://docs.storefrontui.io/?path=/docs/components-templates-confirmorder--common"&gt;Order Summary&lt;/a&gt; components.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Should you have any issues or questions related to Medusa, then feel free to reach out to the Medusa team via &lt;a href="https://discord.gg/F87eGuwkTp"&gt;Discord&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
