<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/" >

<channel>
	<title>Vadzim Papko &#8211; SaM Solutions</title>
	<atom:link href="https://sam-solutions.com/author/v-papko/feed/" rel="self" type="application/rss+xml" />
	<link>https://sam-solutions.com</link>
	<description></description>
	<lastBuildDate>Mon, 06 Jul 2026 08:25:09 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>
	<item>
		<title>Sitecore Experience Manager Cloud (XM Cloud) [Complete Guide]</title>
		<link>https://sam-solutions.com/blog/sitecore-xm-cloud/</link>
					<comments>https://sam-solutions.com/blog/sitecore-xm-cloud/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Fri, 04 Nov 2022 14:38:01 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=618</guid>

					<description><![CDATA[(If you prefer video content, please watch the concise video summary of this article below) In July 2022, Sitecore officially entered the cloud era by announcing the launch of the Sitecore Experience Manager Cloud (XM Cloud) . With this new product, the company moved its main CMS solution to a cloud architecture, promising its customers [&#8230;]]]></description>
										<content:encoded><![CDATA[<span id="more-618"></span>
<!--noteaser-->



<iframe style="margin: 0;" width="100%" height="115" scrolling="no" frameborder="no" allow="autoplay" title="Sitecore Experience Manager Cloud (XM Cloud)" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/soundcloud%253Atracks%253A2251339379&#038;color=%23ff5500&#038;auto_play=false&#038;hide_related=false&#038;show_comments=false&#038;show_user=false&#038;show_reposts=false&#038;show_teaser=false" rel="nofollow"></iframe><p style="font-size:14px;"><em>(If you prefer video content, please <a href="#video-content">watch the concise video summary</a> of this article below)</em></p>



<p class="wp-block-paragraph">In July 2022, Sitecore officially entered the cloud era by announcing the launch of the Sitecore Experience Manager Cloud (XM Cloud) . With this new product, the company moved its main CMS solution to a cloud architecture, promising its customers exceptional digital experiences.</p>



<p class="wp-block-paragraph">Let’s take a detailed look at Sitecore XM Cloud and discover the advantages that <a href="/services/portals-wcms/sitecore/">Sitecore</a> clients and users will gain from new features offered by the platform.</p>




 
    
    <div class="editor-list-cta editor-list-cta_style_1 editor-list-cta_index_1">
        
    <div class="editor-list-cta__items">
                                    
                    			    				<style>
    					.editor-list-cta_index_1 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-button {
            				            				
            				            				        							    background: linear-gradient(to right, #a067e8, #527eff);
    							            				    					}
    				</style>
    			    			
    			    			    				<style>
    					.editor-list-cta_index_1 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left {
    					    padding-left: 10px;
    					}
    					
    					.editor-list-cta_index_1 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					    left: 0;
    					    top: 50%;
    					    width: 3px;
    					    content: '';
    					    position: absolute;
    					    margin-left: -10px;
    					    height: calc(100% + 10px);
    					    transform: translateY(-50%);

            				            					    							    background: linear-gradient(45deg, #527eff, #a067e8);
    							            				    					}
    					
    					@media (max-width: 475px) {
    					    .editor-list-cta_index_1 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					        width: 2px;
                                margin-left: -3.5px;
    					    }
    					}
    				</style>
    			                
                    			    			        
    			
                    			
                                
                <div class="editor-list-cta__item editor-list-cta__item_index_1">
                    <div class="editor-list-cta__item-inner">
            		                		                                <div class="editor-list-cta__item-left">
                                                                                                    <div class="editor-list-cta__item-title"><p><strong>With a four-time Sitecore MVP on board,</strong> SaM Solutions guarantees high-quality results of Sitecore development or modernization.</p>
</div>
                                                	        </div>
            	        
            	                    	            <div class="editor-list-cta__item-right">
            	                                    	                                	                                	            <div class="editor-list-cta__item-event">
                    	                <div class="editor-list-cta__item-button button button_style_1">
                                            <a class="button__inner" href="/contacts/?utm_source=blog&#038;utm_medium=post_ID_618&#038;utm_campaign=cta_post_content_4069">                                                <div class="button__name">Let&#8217;s talk</div>
                                            </a>                                        </div>
                                    </div>    
                                                                        
            	            </div>
            	                	        </div>
                </div>
                        </div>
    </div>
    



<h2 class="wp-block-heading">Introduction</h2>



<p class="wp-block-paragraph">Sitecore is a leading global provider of solutions and tools for content creation and management, order and digital asset management, marketing campaigns, personalization etc. Sitecore Digital Experience Platform (DXP), powered by data science, <a href="/services/data-analytics-services/">analytics</a>, digital marketing technologies, and AI/ML capabilities, allows <a href="/services/e-commerce/ecommerce-development-services/">eCommerce</a> businesses to create advanced digital experiences across multiple channels and industries.</p>



<p class="wp-block-paragraph">The important thing about Sitecore as a digital experience provider is that they never stop improving, and develop bleeding-edge solutions for their customers to make them succeed in their niche. Sitecore Experience Manager Cloud (XM Cloud) is among such game-changing products. Let’s answer some questions to understand the essence of this modern solution and compile its comprehensive definition.</p>



<p class="wp-block-paragraph"><b>Sitecore Experience Manager Cloud:</b></p>



<ol class="wp-block-list">
<li><i>What is it?</i> — An advanced CMS.</li>



<li><i>Where is it deployed?</i> — In the cloud.</li>



<li><i>Who can use it?</i> — Developers and marketing specialists.</li>



<li><i>What are the key characteristics?</i> — <a href="/blog/iaas-vs-paas-vs-saas-whats-the-difference/">SaaS</a>, cloud nativeness, agility, the combination of traditional CMS and headless architecture.</li>



<li><i>What can you do with it?</i> — create and manage content, start websites, deliver digital experiences across all channels from a single <a href="/services/software-engineering/cloud-software-development/">cloud platform</a>.</li>
</ol>



<p class="wp-block-paragraph"><b>Definition</b>: Sitecore Experience Manager (XM) Cloud is a next-generation cloud-native Software-as-a-Service CMS that enables double-quick <a href="/">software development</a> and cloud content management across multiple channels and devices due to its headless architecture.</p>



<p class="wp-block-paragraph">Note that Sitecore Experience Manager offers a composable approach, which means you can flexibly use its modules. For example, initially, you decide to use the platform only as a CMS, because your budget is limited. But later, you need to add personalization or eCommerce functions. With Sitecore XM Cloud, you can quickly connect these modules like building blocks.</p>



<h2 class="wp-block-heading">Features of Sitecore Experience Manager Cloud</h2>



<p class="wp-block-paragraph">To get a better understanding of the platform’s capabilities, take a look at the main features it provides.</p>



<p class="wp-block-paragraph"><b>Cloud Portal</b>. This is a single control center for Sitecore XM products and solutions. Team members with the appropriate access rights can control all the products, perform operations with them and create composable experiences all in one place. In the future, Sitecore is planning to provide access to all the DXP products via Cloud Portal, which will be highly convenient. &nbsp; <b>&nbsp;</b></p>



<p class="wp-block-paragraph"><strong>Sitecore Managed Cloud Deployment</strong>. Using the Experience Manager Cloud, you don’t need a <a href="/services/software-engineering/devops-as-a-service/">DevOps engineer</a>, because the deployment is configured automatically during the creation of a new instance in the Cloud Portal.</p>



<p class="wp-block-paragraph"><b>Headless Services</b>. This is a module with software development kits and <a href="/services/software-engineering/api-development-services/">APIs</a> for creating decoupled apps and delivering omnichannel experiences.</p>



<p class="wp-block-paragraph"><b>Headless SXA</b>. Sitecore Experience Accelerator (SXA) is an add-on for Sitecore XM Cloud, allowing developers, designers, and content managers to work on your site simultaneously, thus speeding up development.</p>



<p class="wp-block-paragraph"><b>Sitecore <a href="/services/technologies/next-js-development-services/">Next.js</a> SDK</b>. This is a React-based framework with a set of sample applications enabling headless development.</p>



<p class="wp-block-paragraph"><b>GraphQL</b>. An alternative to REST, GraphQL is the query language for APIs that ensures communication between the server and the client. With GraphQL, you can transfer the necessary data to the application in one request, even if they are located in several sources. This makes GraphQL data extraction technology more convenient and practical.</p>



<p class="wp-block-paragraph"><b>GitOps support</b>. <a href="/blog/what-is-gitops/">GitOps</a> is a modern convenient approach in software engineering for cloud-native applications based on DevOps best practices. Sitecore Experience Manager supports GitOps, ensuring automation, transparency and improved team collaboration.</p>



<p class="wp-block-paragraph"><b>JAMstack support</b>. This frontend architectural approach is based on<a href="/services/technologies/javascript-development-services/">JavaScript</a>, APIs, and Markup and includes the static site generator (SSG) concept. JAMstack makes it possible to work with a variety of modern frameworks and offers exceptional flexibility due to the <a href="/services/software-engineering/maintenance-and-modernization/">support</a> of all deployment scenarios. When deploying a new environment, you can choose <a href="https://vercel.com/" rel="nofollow noopener" target="_blank">Vercel</a> as a host provider that partners with Sitecore and provides SSG.</p>



<p class="wp-block-paragraph"><b>JSS</b>. Sitecore XM supports the JSS framework, which provides JavaScript packages and allows for developing based on Sitecore data.</p>



<p class="wp-block-paragraph"><b>Multi-site management</b>. With the new Sitecore product, marketers can translate and localize content easily, deploy Sitecore pages for multiple global regions much quicker, and manage them from a single place.</p>



<p class="wp-block-paragraph"><b>Pages</b>. A product for visual content editing, which replaces Experience Editor. With Pages, you can manage all your media assets from a single place and distribute various types of content across different channels.</p>



<p class="wp-block-paragraph"><b>Content Explorer</b>. A tool for editing content fields in the editor view. It allows you to work with content items of all websites within your instance, create new items, and even access content that is not available in Pages.</p>



<p class="wp-block-paragraph"><b>Components</b>. It is also known as Frontend as a Service (FaaS), a reusable component editor, which allows you to select and manage data sources for components.</p>



<h2 class="wp-block-heading">Benefits of Sitecore Experience Manager Cloud</h2>



<p class="wp-block-paragraph">Content management with Sitecore XM Cloud has a range of essential benefits for your business.</p>



<p class="wp-block-paragraph"><b>Fast website </b><b>performance</b>. The modern cloud architecture combined with the capabilities of headless CMS improve the loading speed of your website pages and the overall site performance calculated by search engines.&gt;</p>



<p class="wp-block-paragraph"><b>Scalability</b>. The SaaS and composable nature of Sitecore Experience Manager Cloud allows you to easily scale up and down your project depending on business requirements and other factors. You can add modules if your business is growing, or remove some unnecessary tools if you currently don’t use them.</p>



<p class="wp-block-paragraph"><b>Increased speed to market</b>. Sitecore Experience Manager Cloud streamlines the development process due to flexible deployment scenarios, headless services, component reusability, GitOps support, and other modern tools and approaches. As a result, business owners can bring their products to market much faster.</p>



<p class="wp-block-paragraph"><b>Automatic updates</b>. Since Experience Manager Cloud is a SaaS platform, all the updates are performed automatically, so you don’t need to constantly plan the updates and spend extra money on it.</p>



<p class="wp-block-paragraph"><b>Flexible pricing</b>. Sitecore Experience Manager offers flexible payment options, since it uses a composable approach to digital experiences. You don’t pay for the entire system, only for modules you actually use for your business needs.</p>



<h2 class="wp-block-heading">What Is the Key Difference between Managed Cloud and Experience Manager Cloud?</h2>



<p class="wp-block-paragraph">The main difference between Sitecore Managed Cloud and Sitecore Experience Manager lies in their cloud infrastructure delivery models. Managed Cloud is a PaaS (platform as a service) offering, while XM Cloud is a complete SaaS solution. There are also some other distinctive features:</p>



<ul class="wp-block-list">
<li>Sitecore XM is all about composability, which means it offers cloud headless and API-based solutions.</li>



<li>Sitecore XM does not have CD environments, so the MVC renderings are no longer supported.</li>



<li>Sitecore XM provides SPE and SXA modules out of the box.</li>
</ul>



<h2 class="wp-block-heading">What Can You Get Through Using Sitecore Experience Manager Cloud?</h2>



<p class="wp-block-paragraph">Experience Manager Cloud gives advantages to all groups of people who are in touch with it:</p>



<ul class="wp-block-list">
<li><b>Developers</b> gain exceptional freedom in terms of software development. They can choose from a range of frameworks, DevOps tools, APIs, deployment options and third-party integrations.</li>
</ul>



<ul class="wp-block-list">
<li><b>Marketers and content editors</b> enjoy intuitive visual tools, the headless architecture and the WYSIWYG authoring experience. They can build amazing web pages and deliver content across multiple channels with no effort. Creating a digital content strategy has become easier than ever before.</li>



<li><b>Customers</b> get even more relevant content and personalized experiences.</li>



<li><b>Business owners</b> benefit from all the above-mentioned points: a streamlined development process brings the product quicker to the market; well-prepared marketing strategies achieve their goals; the number of loyal customers grows. It all results in additional revenues and profits for the business.</li>
</ul>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">The Sitecore Experience Manager Cloud is a true next-generation CMS, offering you a wide range of capabilities for creating powerful SaaS products. With this agile, no compromise platform, you can easily improve your content experience and commerce management, rising it to the next level.</p>



<div id="video-content" class="wp-block-group"><div class="wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained">
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Sitecore Experience Manager Cloud (XM Cloud)" width="500" height="281" class="lazyload" referrerpolicy="strict-origin-when-cross-origin" data-src="https://www.youtube.com/embed/7e3MzyhdEW8?feature=oembed"  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope;  web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
</div></div>




 
    
    <div class="editor-faq editor-faq_style_1 editor-faq_index_2">
        


    <div class="editor-faq__title">
        <h2 class="h2">FAQ</h2>
    </div>
    
    <div class="editor-faq__items">
                                
                            
                <div class="editor-faq__item editor-faq__item_active">
					<div class="editor-faq__item-title">
					    <h3 class="h5">How fast can Sitecore XM Cloud deploy? </h3>
					</div>
					
					<div class="editor-faq__item-descr"><p>It may take less than 30 minutes for Sitecore Experience Manager to deploy a Sitecore instance, but it depends on the configurations and templates you use.</p>
</div>
				</div>   
			                                
                            
                <div class="editor-faq__item">
					<div class="editor-faq__item-title">
					    <h3 class="h5">How fast does Sitecore XM Cloud respond when an incident occurs?</h3>
					</div>
					
					<div class="editor-faq__item-descr" style="display: none;"><p>The incident response time of Sitecore Experience Manager Cloud ranges from 15 to 60 minutes.</p>
</div>
				</div>   
			                                
                            
                <div class="editor-faq__item">
					<div class="editor-faq__item-title">
					    <h3 class="h5">Is there down-time with Sitecore XM Cloud? </h3>
					</div>
					
					<div class="editor-faq__item-descr" style="display: none;"><p>The downtime in Sitecore Experience Manager Cloud is minimized to 0.1% (99.9% availability), as the provider offers 24/7 support all year round.</p>
</div>
				</div>   
			                                
                            
                <div class="editor-faq__item">
					<div class="editor-faq__item-title">
					    <h3 class="h5">What are some benefits of making the switch to a Software as a Service (SaaS) model?</h3>
					</div>
					
					<div class="editor-faq__item-descr" style="display: none;"><p>A SaaS model eliminates expenses on infrastructure, installation, and maintenance. It also provides limitless scalability and flexible payment options.</p>
</div>
				</div>   
			                                
                            
                <div class="editor-faq__item">
					<div class="editor-faq__item-title">
					    <h3 class="h5">What about Search in XM Cloud? </h3>
					</div>
					
					<div class="editor-faq__item-descr" style="display: none;"><p>In Sitecore XM Cloud, you can use Solr only for internal search. In other cases, developers should implement the search functionality by integrating alternative solutions, e.g., Sitecore Search.</p>
</div>
				</div>   
			            </div>
    
            <div class="editor-faq__orgld">
            <script type="application/ld+json">
            {
              "@context": "https://schema.org",
              "@type": "FAQPage",
              "mainEntity": [{"@type":"Question","name":"How fast can Sitecore XM Cloud deploy?","acceptedAnswer":{"@type":"Answer","text":"It may take less than 30 minutes for Sitecore Experience Manager to deploy a Sitecore instance, but it depends on the configurations and templates you use."}},{"@type":"Question","name":"How fast does Sitecore XM Cloud respond when an incident occurs?","acceptedAnswer":{"@type":"Answer","text":"The incident response time of Sitecore Experience Manager Cloud ranges from 15 to 60 minutes."}},{"@type":"Question","name":"Is there down-time with Sitecore XM Cloud?","acceptedAnswer":{"@type":"Answer","text":"The downtime in Sitecore Experience Manager Cloud is minimized to 0.1% (99.9% availability), as the provider offers 24\/7 support all year round."}},{"@type":"Question","name":"What are some benefits of making the switch to a Software as a Service (SaaS) model?","acceptedAnswer":{"@type":"Answer","text":"A SaaS model eliminates expenses on infrastructure, installation, and maintenance. It also provides limitless scalability and flexible payment options."}},{"@type":"Question","name":"What about Search in XM Cloud?","acceptedAnswer":{"@type":"Answer","text":"In Sitecore XM Cloud, you can use Solr only for internal search. In other cases, developers should implement the search functionality by integrating alternative solutions, e.g., Sitecore Search."}}]            }
            </script>
        </div>
        
    </div>
    
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/sitecore-xm-cloud/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<media:content url="https://www.youtube.com/watch?v=7e3MzyhdEW8" medium="video">
			<media:player url="https://www.youtube.com/watch?v=7e3MzyhdEW8" />
			<media:title type="plain">Sitecore Experience Manager Cloud (XM Cloud)</media:title>
			<media:description type="html"><![CDATA[Sitecore Experience Manager (XM) Cloud is a next-generation, cloud-native SaaS CMS offering headless architecture for agile, omnichannel content delivery. It features a central Cloud Portal, headless services, GitOps support, and tools like Pages and Components. Benefits include faster deployment, automatic updates, scalability, and a composable, pay-as-you-go model for developers and marketers.]]></media:description>
			<media:thumbnail url="https://i.ytimg.com/vi/7e3MzyhdEW8/maxresdefault.jpg" />
			<media:rating scheme="urn:simple">adult</media:rating>
		</media:content>
	</item>
		<item>
		<title>Why You Should Upgrade to Sitecore 10 [including the Sitecore 9 vs. 10 comparison]</title>
		<link>https://sam-solutions.com/blog/why-you-should-upgrade-to-sitecore-10/</link>
					<comments>https://sam-solutions.com/blog/why-you-should-upgrade-to-sitecore-10/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Tue, 27 Sep 2022 13:25:40 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=686</guid>

					<description><![CDATA[Upgrading to the latest versions of software products is the best practice for businesses that want to keep up with technological advancements and provide their customers with a seamless digital experience. Sitecore is an actively growing platform for developing content management systems (CMSs) and offering personalized digital customer experience. For numerous companies that have their [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Upgrading to the latest versions of software products is the best practice for businesses that want to keep up with technological advancements and provide their customers with a seamless digital experience.</p>



<p class="wp-block-paragraph">Sitecore is an actively growing platform for developing content management systems (CMSs) and offering personalized digital customer experience. For numerous companies that have their projects based on Sitecore 9.x, the time has come to consider upgrading to Sitecore 10.x. Why and how should you do this? What’s the difference between Sitecore 9 and 10? Read the article to learn the details.</p>



<span id="more-686"></span>




 
    
    <div class="editor-list-cta editor-list-cta_style_1 editor-list-cta_index_3">
        
    <div class="editor-list-cta__items">
                                    
                    			    				<style>
    					.editor-list-cta_index_3 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-button {
            				            				
            				            				        							    background: linear-gradient(to right, #a067e8, #527eff);
    							            				    					}
    				</style>
    			    			
    			    			    				<style>
    					.editor-list-cta_index_3 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left {
    					    padding-left: 10px;
    					}
    					
    					.editor-list-cta_index_3 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					    left: 0;
    					    top: 50%;
    					    width: 3px;
    					    content: '';
    					    position: absolute;
    					    margin-left: -10px;
    					    height: calc(100% + 10px);
    					    transform: translateY(-50%);

            				            					    							    background: linear-gradient(45deg, #527eff, #a067e8);
    							            				    					}
    					
    					@media (max-width: 475px) {
    					    .editor-list-cta_index_3 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					        width: 2px;
                                margin-left: -3.5px;
    					    }
    					}
    				</style>
    			                
                    			    			        
    			
                    			
                                
                <div class="editor-list-cta__item editor-list-cta__item_index_1">
                    <div class="editor-list-cta__item-inner">
            		                		                                <div class="editor-list-cta__item-left">
                                                                                                    <div class="editor-list-cta__item-title"><p><strong>With a four-time Sitecore MVP on board,</strong> SaM Solutions guarantees high-quality results of Sitecore development or modernization.</p>
</div>
                                                	        </div>
            	        
            	                    	            <div class="editor-list-cta__item-right">
            	                                    	                                	                                	            <div class="editor-list-cta__item-event">
                    	                <div class="editor-list-cta__item-button button button_style_1">
                                            <a class="button__inner" href="/contacts/?utm_source=blog&#038;utm_medium=post_ID_686&#038;utm_campaign=cta_post_content_4069">                                                <div class="button__name">Let&#8217;s talk</div>
                                            </a>                                        </div>
                                    </div>    
                                                                        
            	            </div>
            	                	        </div>
                </div>
                        </div>
    </div>
    



<h2 class="wp-block-heading">The End of Sitecore 9</h2>



<p class="wp-block-paragraph">The lifecycle of each <a href="/services/portals-wcms/sitecore/">Sitecore</a> product has its end date, which means the provider will no longer <a href="/services/software-engineering/maintenance-and-modernization/">support service</a> packs and updates after this predefined date. It should be noted that there are three phases of customer support for each product version:</p>



<ul class="wp-block-list">
<li><b>Mainstream support</b> lasts for three years from the initial release</li>



<li><b>Extended support </b>lasts for six years from the initial release</li>



<li><b>Sustaining support</b> lasts for eight years from the initial release</li>
</ul>



<p class="wp-block-paragraph">This way, the mainstream support for Sitecore 9.0 and 9.1 has already ended, and it will end for Sitecore 9.2 and 9.3 on December 31, 2022.</p>



<p class="has-text-align-center wp-block-paragraph"><b>Support phases for Sitecore 9.x </b></p>



<figure class="wp-block-table"><table><tbody><tr><td>
<p style="text-align: center"><b>Product</b></p>
</td><td>
<p style="text-align: center"><b>Initial Release Date</b></p>
</td><td>
<p style="text-align: center"><b>Mainstream Support End Date</b></p>
</td><td>
<p style="text-align: center"><b>Extended Support End Date</b></p>
</td><td>
<p style="text-align: center"><b>Sustaining Support End Date</b></p>
</td></tr><tr><td><b>Sitecore 9.3</b></td><td>Nov 2019</td><td>31-Dec-2022</td><td>31-Dec-2025</td><td>31-Dec-2027</td></tr><tr><td><b>Sitecore 9.2</b></td><td>Jul 2019</td><td>31-Dec-2022</td><td>31-Dec-2025</td><td>31-Dec-2027</td></tr><tr><td><b>Sitecore 9.1</b></td><td>Nov 2018</td><td>31-Dec-2021</td><td>31-Dec-2024</td><td>31-Dec-2026</td></tr><tr><td><b>Sitecore 9.0</b></td><td>Oct 2017</td><td>31-Dec-2020</td><td>31-Dec-2023</td><td>31-Dec-2025</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Businesses that have purchased the extended and sustaining support versions, will be maintained for the next few years. However, they may already think about upgrading to Sitecore 10.x versions to benefit from new features they offer.</p>



<h2 class="wp-block-heading">Sitecore 10: New Features, Benefits, and Upgrades</h2>



<p class="wp-block-paragraph">In August 2020, the release of <a href="/blog/sitecore-10-new-features-overview/">Sitecore 10</a> was announced, bringing a wide range of improvements and new features to the benefit of both developers and customers. Let’s look at them.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="1211" height="1061" src="https://sam-solutions.com/wp-content/uploads/Sitecore-10-new-features.png" alt="Why upgrade to Sitecore 10" class="wp-image-3363"/></figure>
</div>


<h3 class="wp-block-heading">Out-of-the-Box Containerization</h3>



<p class="wp-block-paragraph">As you know, Sitecore 9.x provided the support for containers, but only with the release of Sitecore 10, this became an out-of-the-box feature. Starting with this version, Sitecore developers can deploy containers using Docker Compose and Azure Kubernetes Service (AKS).</p>



<p class="wp-block-paragraph">Why is this feature fundamentally important? Because the support for containers ensures:</p>



<ul class="wp-block-list">
<li>a simplified installation process</li>



<li>flexible and rapid <a href="/">software development</a> and deployment</li>



<li>a continuous delivery approach</li>



<li>the reduced consumption of system resources.</li>
</ul>



<h3 class="wp-block-heading">Headless Services</h3>



<p class="wp-block-paragraph">In Sitecore 9, developers could create headless <a href="/services/technologies/javascript-development-services/">JavaScript applications</a> due to the integration of JSS and SXA. Starting with version 10, the Sitecore digital experience platform introduced a software development kit for headless services based on <a href="/services/technologies/dot_net/">.NET</a> Core.</p>



<p class="wp-block-paragraph">The <a href="/blog/headless-cms-vs-traditional-cms/">headless</a> approach to developing eCommerce solutions is common among businesses nowadays, since it ensures an omnichannel experience, flexibility, scalability and time-efficiency, in addition to creating and managing content. Sitecore 10 allows you to develop powerful eCommerce solutions for multiple channels within a shorter span of time.</p>



<h3 class="wp-block-heading">Extended Horizon Editor</h3>



<p class="wp-block-paragraph">Content managers opened new horizons with the Sitecore editor named Horizon. It was released in Sitecore 9.3, but a full set of functions became available only in Sitecore 10. Being a next-generation tool, Horizon brings together the best features of Experience Editor and Content Editor, while adding new capabilities:</p>



<ul class="wp-block-list">
<li>A more intuitive and user-friendly interface</li>



<li>Improved searching</li>



<li>More editing options due to the extended SXA support</li>



<li>Multilingual and multi-site support</li>



<li>Integration with Content Hub, which allows managers to use AI and ML technologies for providing advanced personalization</li>
</ul>



<h3 class="wp-block-heading">Serialization with CLI</h3>



<p class="wp-block-paragraph">With the Sitecore 10 upgrade, working with instances has become easier thanks to the Command Line Interface (CLI). It offers the simplified approach to publishing and serializing content items, and any changes are applied automatically to all content touchpoints.</p>



<h3 class="wp-block-heading">Solr Search Alternative</h3>



<p class="wp-block-paragraph">In Sitecore 9, Azure Search was used as a search engine, and <a href="/services/dedicated-development-team/">development teams</a> faced certain issues working with it. That’s why, Sitecore 10 replaced Azure Search with Solr.</p>



<h3 class="wp-block-heading">Personalization for Email Experience Manager</h3>



<p class="wp-block-paragraph">The capabilities of Email Experience Manager were extended in Sitecore 10, thus making email marketing more efficient. Now, you can quickly create emails by choosing from a variety of ready-to-use templates, and organize campaigns based on new rules associated with customer birthdays. This way, you can engage more people and convert them into your clients.</p>



<h3 class="wp-block-heading">Improved Experience Analytics</h3>



<p class="wp-block-paragraph">Since <a href="/services/data-analytics-services/">analytics</a> is one of the key tools for marketers, Sitecore improved it in the 10th version. Specifically, they added the new Audience Filtering capability based on the segmentation rules. Now, you can quickly categorize your audience by segments. Moreover, detailed reports on each segment allow you to clearly see customer demands and develop better marketing campaigns.</p>



<h2 class="wp-block-heading">Sitecore 10.2</h2>



<p class="wp-block-paragraph">At the moment of writing the article, the latest version is Sitecore 10.2. Let’s briefly look at the Sitecore upgrades and new features coming with this release.</p>



<h3 class="wp-block-heading">Experience Platform and Experience Manager</h3>



<p class="wp-block-paragraph">Among the new features are:</p>



<ul class="wp-block-list">
<li><b>xConnect DevEx CLI plugin estimate tool,</b> allowing you to apply filters to contacts and interactions you are going to process.</li>



<li><b>Extended xConnect logging,</b> providing you with more information on xConnect functioning.</li>



<li><b>List Manager </b>for customizing lists of contacts.</li>
</ul>



<p class="wp-block-paragraph">Improvements were made for:</p>



<ul class="wp-block-list">
<li><b>Plugin purging tool </b>— you can free up database space from unused data.</li>



<li><b>Forms</b> — content from the form fields can be exported with the respected structure.</li>



<li><b>Robot detection</b> — it can now be disabled.</li>
</ul>



<h3 class="wp-block-heading">JavaScript Rendering SDKs (JSS) and Headless Services</h3>



<p class="wp-block-paragraph">New features:</p>



<ul class="wp-block-list">
<li><strong>Rendering MVC applications to HTML</strong> and converting MVC apps to JSS are possible due to Headless Services and JSS <a href="/services/technologies/next-js-development-services/">Next.js</a>.</li>



<li>JSS Next.js apps <strong>compatibility with Horizon</strong>.</li>



<li>JSS Next.js apps can be created <strong>without boilerplate content</strong>.</li>



<li><strong>JSS React, Angular, or Vue.js apps can be created</strong> based on JSS applications samples, by using the JSS CLI command jss create.</li>
</ul>



<p class="wp-block-paragraph">Improvements:</p>



<ul class="wp-block-list">
<li><strong>dataApi is replaced</strong> by JSS REST Layout <a href="/services/software-engineering/api-development-services/">API</a> and JSS REST Dictionary API when developing JSS apps based on React, Angular, and Vue.js.</li>



<li><strong>URL rewriting can now be configured</strong> during the integration of a rendering host with Experience Editor or Horizon.</li>
</ul>



<h3 class="wp-block-heading">Developer Tools</h3>



<p class="wp-block-paragraph">New features:</p>



<ul class="wp-block-list">
<li><b>Items and resource package plugin</b> allows you to extend the possible sources for Sitecore items.</li>



<li><b>Indexing plugin</b> automates indexing operations, streamlining the configuration of development environments or production deployments.</li>



<li><b>Role serialization</b> allows developers and <a href="/services/software-engineering/devops-as-a-service/">DevOps</a> engineers to manage roles in their solution by synchronizing them with other developers on the same project and promoting changes to source-controlled roles across Sitecore environments.</li>
</ul>



<p class="wp-block-paragraph">Improvements:</p>



<ul class="wp-block-list">
<li>You can now <strong>specify what target database</strong> you want to publish Sitecore Items to through the DevEx CLI.</li>



<li>You can now <strong>exclude fields</strong> from comparison and serialization.</li>
</ul>



<h3 class="wp-block-heading">Email Experience Manager</h3>



<p class="wp-block-paragraph">Improvement:</p>



<ul class="wp-block-list">
<li>You can now <strong>configure the number of campaigns</strong> loaded for lists and searches, and the default sorting of columns for each List page.</li>
</ul>



<h3 class="wp-block-heading">Sitecore Experience Accelerator</h3>



<p class="wp-block-paragraph">New feature:</p>



<ul class="wp-block-list">
<li>The <strong>Bootstrap</strong> 5 grid</li>
</ul>



<p class="wp-block-paragraph">Improvements:</p>



<ul class="wp-block-list">
<li><strong>Adding closed captions</strong> for YouTube videos and linking directly to public Vimeo videos.</li>



<li><strong>Using the SXA CLI</strong> for upload tasks.</li>



<li><strong>Using an image selector</strong> for some SXA components and configuring complex data sources in the Horizon editor.</li>



<li><strong>Direct access to field item properties</strong> for your i_item in the Scriban template.</li>
</ul>



<h3 class="wp-block-heading">Horizon</h3>



<p class="wp-block-paragraph">New feature:</p>



<ul class="wp-block-list">
<li><b>Content Explorer</b> for finding and organizing content items instead of the content tree.</li>
</ul>



<p class="wp-block-paragraph">Improvements:</p>



<ul class="wp-block-list">
<li><strong>Navigating up</strong> through the page structure hierarchy.</li>



<li><strong>Thematic grouping</strong> of components.</li>
</ul>



<h3 class="wp-block-heading">Analysis and Reporting</h3>



<p class="wp-block-paragraph">New features:</p>



<ul class="wp-block-list">
<li><b>Experience Optimization</b> allows you to see the results of personalization on individual goal conversions.</li>



<li><b>Experience Analytics</b> allows you to export CSV files with data from any list report.</li>
</ul>



<p class="wp-block-paragraph">Improvements:</p>



<ul class="wp-block-list">
<li><strong>The Segment column</strong> has been added to list reports.</li>



<li><strong>Sorting of reports</strong> by the most relevant metric.</li>
</ul>



<h3 class="wp-block-heading">Sitecore Experience Commerce</h3>



<p class="wp-block-paragraph">Improvements:</p>



<ul class="wp-block-list">
<li><strong>Default commerce items as resources files</strong>, which improve the upgrade experience by storing default content items outside the database.</li>



<li><strong>Container deployment</strong> improvements</li>



<li>Merchandisers can use the <strong>Business Tools interface</strong> to change the order in which to display product images, and have those changes reflected in the Storefront.</li>



<li>The Commerce Engine and Commerce Engine Connect now support <strong>Redis Cluster configuration</strong>.</li>



<li><strong>New caching API samples</strong> in Postman let you clear Redis cache stores.</li>
</ul>



<h2 class="wp-block-heading">Sitecore 9 vs. Sitecore 10</h2>



<figure class="wp-block-table"><table><tbody><tr><td><b>Sitecore 9</b></td><td><b>Sitecore 10</b></td></tr><tr><td>Support for containers</td><td>Out-of-the-box containerization</td></tr><tr><td>
<p style="text-align: center">Headless JavaScript apps</p>
<p style="text-align: center">JSS + SXA</p>
</td><td>Headless services based on .NET Core</td></tr><tr><td>
<p style="text-align: center">Horizon Editor (Sitecore 9.3)</p>
<p style="text-align: center">limited functionality</p>
</td><td>
<p style="text-align: center">Horizon Editor</p>
<p style="text-align: center">extended functionality</p>
</td></tr><tr><td>Serialization with the Rainbow library</td><td>Serialization with Command Line Interface (CLI)</td></tr><tr><td>Azure Search engine</td><td>Solr search platform</td></tr><tr><td>No personalization rules in the Email Experience Manager</td><td>Personalization rules in the Email Experience Manager</td></tr><tr><td>No segmentation for analytics reports</td><td>Segmentation filter for analytics reports</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Reasons Why You Should Upgrade to Sitecore 10</h2>



<p class="wp-block-paragraph">Taking into account the above-described features and capabilities of Sitecore 10.x, we can distinguish four general reasons why you should make the decision to upgrade.</p>



<ol class="wp-block-list">
<li>Retain the <b>technical support</b> of Sitecore for all of their products you use.</li>



<li>Provide your <b>developers </b>with improved tools and new tech capabilities, including .NET Core, containerization, and Kubernetes, to streamline the development process.</li>



<li>Empower your <b>marketing team</b> with more efficient tools that will help you increase conversions.</li>



<li>Deliver amazing omnichannel experiences to your <b>customers </b>by grasping a better understanding of their needs.</li>
</ol>



<h2 class="wp-block-heading">The Migration Algorithm</h2>



<p class="wp-block-paragraph">When you’ve come up to the decision to upgrade from Sitecore 9.x to Sitecore 10.x, you should prepare for the process. The following is a brief algorithm of what steps should be taken.</p>



<ul class="wp-block-list">
<li>First, check the <strong>compatibility of your hardware and software</strong> with the new Sitecore XP version.</li>



<li>Starting with the version Sitecore XP 9.3.0, <strong>certificates for the Secure Sockets Layer (SSL)</strong> are required because communication with the Content Management server occurs over HTTPS. If you don’t have them yet, you should obtain and set up these certificates before upgrading.</li>



<li>During the upgrading process, <strong>it’s important not to break any customizations</strong> you’ve done in your system. Therefore, before starting, you should move your custom DLLs and configuration files out of the Sitecore\bin and \app_config folders. You’ll be able to adapt them later according to breaking changes and return to the folders.</li>



<li>In addition, <strong>check that the default config files have not been edited</strong>. In case they have some changes, extract them to a custom configuration file and back it up, otherwise you’ll lose them.</li>



<li><strong>Sitecore Update Center</strong> is the tool using which you download, install and manage all the necessary upgrades. This is where you should find the Sitecore 10 upgrade package, download and install it.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1165" height="770" src="https://sam-solutions.com/wp-content/uploads/Sitecore-update-center-min.png" alt="Why upgrade to Sitecore 10" class="wp-image-3365"/></figure>
</div>


<ul class="wp-block-list">
<li>It can also be required to <strong>upgrade your existing databases</strong>, depending on the Sitecore version you are using now.</li>
</ul>



<p class="wp-block-paragraph"><b>Note!</b> If you want to avoid issues with custom elements while upgrading the production system, you should first test the process on a developer or testing system.</p>



<h2 class="wp-block-heading">Closing Thoughts</h2>



<p class="wp-block-paragraph">Sitecore 10.x is a fully-functional platform that can address all the challenges of modern marketing. Both developers and marketers get innovative tools, which they can use to accelerate processes and achieve better results. Both business owners and digital consumers benefit from the new features offered by the platform.</p>



<p class="wp-block-paragraph">If you still have doubts regarding the Sitecore upgrading process, get in touch with the experienced Sitecore developers at SaM Solutions for discussion.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/why-you-should-upgrade-to-sitecore-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Sitecore SXA Optimized Assets with Empty Timestamp: How to Fix the Issue?</title>
		<link>https://sam-solutions.com/blog/sitecore-sxa-optimized-assets-empty-timestamp-fix-the-issue/</link>
					<comments>https://sam-solutions.com/blog/sitecore-sxa-optimized-assets-empty-timestamp-fix-the-issue/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Tue, 13 Sep 2022 14:39:37 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=614</guid>

					<description><![CDATA[This article is dedicated to Sitecore SXA Asset Optimizer. Precisely, I want to share with you how to resolve the issue with an empty timestamp parameter, which is responsible for assets versioning. Overview The Sitecore Experience Accelerator has a built-in Asset Optimizer module that is used for optimizing CSS styles and JS scripts. If you [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">This article is dedicated to Sitecore SXA Asset Optimizer. Precisely, I want to share with you how to resolve the issue with an empty timestamp parameter, which is responsible for assets versioning.</p>



<span id="more-614"></span>



<h2 class="wp-block-heading">Overview</h2>



<p class="wp-block-paragraph">The Sitecore Experience Accelerator has a built-in Asset Optimizer module that is used for optimizing CSS styles and JS scripts. If you want to improve your site performance, you should enable this module in your production environment, and it will cut down the volume of data that needs to be transmitted.</p>



<p class="wp-block-paragraph">As a Sitecore administrator, you have two options of <a href="https://doc.sitecore.com/xp/en/developers/sxa/102/sitecore-experience-accelerator/enable-and-configure-the-asset-optimizer.html" target="_blank" rel="noreferrer noopener nofollow">enabling Asset Optimizer</a>:</p>



<ul class="wp-block-list">
<li>Global enablement for the entire Sitecore instance</li>



<li>Local enablement for selected sites</li>
</ul>



<p class="wp-block-paragraph">According to the best practice, both CSS styles and JS scripts are loaded on the client side with a version prefix to avoid a cache issue when a new delivery occurs. And SXA is not an exception: it applies a timestamp for the optimized assets, as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
&lt;script src=&quot;/sitecore/shell/-/media/Base-Themes/SearchTheme/Scripts/optimized-min.js?t=20160908T094830Z&quot;&gt;&lt;/script&gt; 
</pre></div>


<h2 class="wp-block-heading">Problem</h2>



<p class="wp-block-paragraph">In one project I was involved in, we observed the following issue — the timestamp was not generated for localized sites. All optimized assets contained the empty timestamp parameter, as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
&lt;script src=&quot;/sitecore/shell/-/media/Base-Themes/SearchTheme/Scripts/optimized-min.js?t=&quot;&gt;&lt;/script&gt;
</pre></div>


<p class="wp-block-paragraph">This results in the situation when the client browser doesn’t update the cached version of CSS styles and JS scripts after another deployment, since the<i> t </i>parameter is a versioning element.</p>



<p class="wp-block-paragraph">So, let’s investigate this case.</p>



<h2 class="wp-block-heading">Solution</h2>



<p class="wp-block-paragraph">The first thing we need to do is to figure out how and where the timestamp is generated. A great idea is to start from the default SXA layout razor page. It’s called SxaLayout.cshtml.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="817" height="596" src="https://sam-solutions.com/wp-content/uploads/Sxa-Layout-min.png" alt="Sxa-Layout" class="wp-image-3369"/></figure>
</div>


<p class="wp-block-paragraph">As we can see, to get an asset link, it executes the static <b>GenerateLinks</b> method of the AssetLinksGenerator type</p>



<p class="wp-block-paragraph">(full name: Sitecore.XA.Foundation.Theming.Bundler.AssetLinksGenerator)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="2180" height="699" src="https://sam-solutions.com/wp-content/uploads/AssetLinkGenerator-class-min.png" alt="AssetLinkGenerator-class" class="wp-image-3371"/></figure>
</div>


<p class="wp-block-paragraph">Going deeper, we can find the <b>GetOptimizedItemLink </b>method, which is responsible for the asset link generation. It looks as shown below:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1505" height="381" src="https://sam-solutions.com/wp-content/uploads/GetOptimizedItemLinkMethod-min.png" alt="GetOptimizedItemLinkMethod" class="wp-image-3374"/></figure>
</div>


<p class="wp-block-paragraph">In the return expression, if an optimized script item is both not null and empty, the BuildAssetPath() extension method is executed.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1088" height="307" src="https://sam-solutions.com/wp-content/uploads/BuildAssetPath-min.png" alt="BuildAssetPath" class="wp-image-3376"/></figure>
</div>


<p class="wp-block-paragraph">All right, we’ve discovered the place where the timestamp is added. Interesting, it goes from the system’s __Updated template field. Hm, what could be the issue with that? Let’s check this field.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="788" height="555" src="https://sam-solutions.com/wp-content/uploads/Updated-Field-min.png" alt="Updated-Field" class="wp-image-3378"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="973" height="527" src="https://sam-solutions.com/wp-content/uploads/Updated-Field-1-min.png" alt="Updated-Field-1" class="wp-image-3380"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="548" height="626" src="https://sam-solutions.com/wp-content/uploads/Updated-Field-Not-Shared-min.png" alt="Updated-Field-Not-Shared" class="wp-image-3382"/></figure>
</div>


<p class="wp-block-paragraph">Ok, the __Updated field belongs to the Statistics template that is a part of the Standard Sitecore template. The key thing here is that this field is not shared. It means that if we have a site with no default localization, the optimized assets also should have this language version that is a bit strange — do we really need to have localized assets (CSS and JS)? I am not sure. So, we need to apply a fix to resolve this issue for localized sites.</p>



<ul class="wp-block-list">
<li>First, we need to create our own BuildAssetPath extension method (the same code as above) with one additional line of code inside the if statement:</li>
</ul>



<p class="wp-block-paragraph">Item item1 = item.EnsureFallbackVersionIfExist();</p>



<p class="wp-block-paragraph">This extension method (assembly Sitecore.XA.Foundation.SitecoreExtensions.dll, ItemExtensions.cs) returns an item for a default language (usually English) if there are no language versions. That is what we need for optimized scripts.</p>



<ul class="wp-block-list">
<li>Second, we need to create a new type (inherited from AssetLinksGenerator.cs) with the overridden GetOptimizedItemLink method and a new static GenerateLinks method to hide the base one.</li>



<li>Third, replace OOTB AssetLinkGenerator by the created one in the SXA layout:</li>
</ul>



<p class="wp-block-paragraph">That is it! Now, your localized Sitecore SXA sites have optimized assets with the generated timestamp parameter! Happy coding Sitecorians!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/sitecore-sxa-optimized-assets-empty-timestamp-fix-the-issue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Configure Second-Level Retry Messaging in Sitecore Message Bus</title>
		<link>https://sam-solutions.com/blog/configure-second-level-retry-messaging-in-sitecore-message-bus/</link>
					<comments>https://sam-solutions.com/blog/configure-second-level-retry-messaging-in-sitecore-message-bus/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Wed, 29 Dec 2021 14:19:37 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=446</guid>

					<description><![CDATA[In this article, I want to share my practical experience implementing a second-level handler in Sitecore Message Bus. Problem While working on one of our projects, we needed a mechanism for handling messages between different applications. Sitecore implements this mechanism via the Sitecore Messaging Framework on Azure Service Bus. In this regard, the article by [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In this article, I want to share my practical experience implementing a second-level handler in Sitecore Message Bus.</p>



<span id="more-446"></span>



<h2 class="wp-block-heading">Problem</h2>



<p class="wp-block-paragraph">While working on one of our projects, we needed a mechanism for handling messages between different applications. Sitecore implements this mechanism via the Sitecore Messaging Framework on <a href="https://doc.sitecore.com/xp/en/developers/91/platform-administration-and-architecture/message-bus.html" target="_blank" rel="noreferrer noopener nofollow">Azure Service Bus</a>. In this regard, the <a href="https://medium.com/@mitya_1988/sitecore-messaging-framework-on-azure-service-bus-queue-step-by-step-tutorial-4ee6a74e6326" target="_blank" rel="noreferrer noopener nofollow">article by Árvai Mihály</a> helped us a lot.</p>




 
    
    <div class="editor-list-cta editor-list-cta_style_1 editor-list-cta_index_4">
        
    <div class="editor-list-cta__items">
                                    
                    			    				<style>
    					.editor-list-cta_index_4 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-button {
            				            				
            				            				        							    background: linear-gradient(to right, #a067e8, #527eff);
    							            				    					}
    				</style>
    			    			
    			    			    				<style>
    					.editor-list-cta_index_4 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left {
    					    padding-left: 10px;
    					}
    					
    					.editor-list-cta_index_4 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					    left: 0;
    					    top: 50%;
    					    width: 3px;
    					    content: '';
    					    position: absolute;
    					    margin-left: -10px;
    					    height: calc(100% + 10px);
    					    transform: translateY(-50%);

            				            					    							    background: linear-gradient(45deg, #527eff, #a067e8);
    							            				    					}
    					
    					@media (max-width: 475px) {
    					    .editor-list-cta_index_4 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					        width: 2px;
                                margin-left: -3.5px;
    					    }
    					}
    				</style>
    			                
                    			    			        
    			
                    			
                                
                <div class="editor-list-cta__item editor-list-cta__item_index_1">
                    <div class="editor-list-cta__item-inner">
            		                		                                <div class="editor-list-cta__item-left">
                                                                                                    <div class="editor-list-cta__item-title"><p><strong>With a four-time Sitecore MVP on board,</strong> SaM Solutions guarantees high-quality results of Sitecore development or modernization.</p>
</div>
                                                	        </div>
            	        
            	                    	            <div class="editor-list-cta__item-right">
            	                                    	                                	                                	            <div class="editor-list-cta__item-event">
                    	                <div class="editor-list-cta__item-button button button_style_1">
                                            <a class="button__inner" href="/contacts/?utm_source=blog&#038;utm_medium=post_ID_446&#038;utm_campaign=cta_post_content_4069">                                                <div class="button__name">Let&#8217;s talk</div>
                                            </a>                                        </div>
                                    </div>    
                                                                        
            	            </div>
            	                	        </div>
                </div>
                        </div>
    </div>
    



<p class="wp-block-paragraph">However, we needed to implement a second-level handler. As it turned out, the method is quite simple but not obvious.</p>



<p class="wp-block-paragraph">Let’s see how you can do this.</p>



<h2 class="wp-block-heading">Solution</h2>



<p class="wp-block-paragraph">First of all, you need to create a configuration file.</p>



<p class="wp-block-paragraph">Here you have to pay attention to the <b>Options section</b>:</p>



<ul class="wp-block-list">
<li><b>&lt;ErrorQueueAddress&gt;Error&lt;/ErrorQueueAddress&gt;</b> — defines the queue to which the message will be sent if its processing fails.</li>



<li><b>&lt;MaxDeliveryAttempts&gt;3&lt;/MaxDeliveryAttempts&gt;</b> — defines the number of attempts to receive messages by the first-level handler.</li>



<li><b>&lt;SecondLevelRetriesEnabled&gt;true&lt;/SecondLevelRetriesEnabled&gt;</b> — allows the use of a second-level handler.</li>
</ul>



<p class="wp-block-paragraph">In our case, the second-level handler will be called after three unsuccessful attempts to receive a message by the first-level handler.</p>



<p class="wp-block-paragraph">Now, you should create a contract for messages.</p>



<p class="wp-block-paragraph">Then, you should create an empty class that will be used by the Rebus library.</p>



<p class="wp-block-paragraph">The next step is to initialize our ExampleMessageBus with the help of Sitecore Initialize Pipeline.</p>



<p class="wp-block-paragraph">To receive messages, you should create a handler and register it. You’ll need the Rebus library to do this.</p>



<p class="wp-block-paragraph">In the handler, we inherit <b>IMessageHandler &lt;ExampleMessage&gt;</b> and <b>IMessageHandler &lt;IFailed &lt;ExampleMessage&gt;&gt;</b>. The second interface allows us to process messages when the message processing at the first level was unsuccessful. Here you can set a <i>Defer</i> for messages or send a notification that an error has occurred at the first level, or something else.</p>



<p class="wp-block-paragraph">You should also register <b>IMessageHandler&lt;IFailed&lt;ExampleMessage&gt;&gt;</b>&nbsp;in the configurator.</p>



<p class="wp-block-paragraph">So it’s done. Now you are able to use the second-level messaging in the Sitecore Service Bus.</p>



<p class="wp-block-paragraph">P.S. Many thanks to a colleague of mine <a href="https://github.com/MikhailShishlyannikov" target="_blank" rel="noreferrer noopener nofollow">Mikhail Shishlyannikov</a> who helped me with investigating this topic.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/configure-second-level-retry-messaging-in-sitecore-message-bus/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>What Is GitOps?</title>
		<link>https://sam-solutions.com/blog/what-is-gitops/</link>
					<comments>https://sam-solutions.com/blog/what-is-gitops/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Thu, 14 Oct 2021 13:29:20 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=675</guid>

					<description><![CDATA[The CI/CD pipeline has become a popular practice among software developers as it automates the creation, testing and integration of applications. Infrastructure engineers were long in need of a similar practice for infrastructure automation, taking into account the growing complexity of IT systems at various enterprises. This is why the GitOps approach came into being. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">The CI/CD pipeline has become a popular practice among software developers as it automates the creation, testing and integration of applications. Infrastructure engineers were long in need of a similar practice for infrastructure automation, taking into account the growing complexity of IT systems at various enterprises. This is why the GitOps approach came into being.</p>



<p class="wp-block-paragraph">In this article, I’ll explain to you the principles of GitOps, its connection to DevOps, the benefits of managing infrastructure using this approach, and how to put it into practice.</p>



<span id="more-675"></span>




 
    
    <div class="editor-list-cta editor-list-cta_style_1 editor-list-cta_index_5">
        
    <div class="editor-list-cta__items">
                                    
                    			    				<style>
    					.editor-list-cta_index_5 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-button {
            				            				
            				    					}
    				</style>
    			    			
    			    			    				<style>
    					.editor-list-cta_index_5 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left {
    					    padding-left: 10px;
    					}
    					
    					.editor-list-cta_index_5 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					    left: 0;
    					    top: 50%;
    					    width: 3px;
    					    content: '';
    					    position: absolute;
    					    margin-left: -10px;
    					    height: calc(100% + 10px);
    					    transform: translateY(-50%);

            				            					    							    background: #ffffff;
    							            				    					}
    					
    					@media (max-width: 475px) {
    					    .editor-list-cta_index_5 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-left:before {
    					        width: 2px;
                                margin-left: -3.5px;
    					    }
    					}
    				</style>
    			                
                    			    			        			        <style>
        					.editor-list-cta_index_5 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-inner {
        					            						    background: linear-gradient(45deg, #e6abff, #6dc7ff);
        						        					}
        				</style>
    			        
    			
                    			    				<style>
    					.editor-list-cta_index_5 .editor-list-cta__item.editor-list-cta__item_index_1 .editor-list-cta__item-inner {
    					    color: #000000;
    					}
    				</style>
    			
                                
                <div class="editor-list-cta__item editor-list-cta__item_index_1">
                    <div class="editor-list-cta__item-inner">
            		                		                                <div class="editor-list-cta__item-left">
                                                                                                    <div class="editor-list-cta__item-title"><p><strong>Request SaM Solutions&#8217; DevOps services to automate</strong> and speed up your software&#8217;s deployment.</p>
</div>
                                                	        </div>
            	        
            	                    	            <div class="editor-list-cta__item-right">
            	                                    	                                	                                	            <div class="editor-list-cta__item-event">
                    	                <div class="editor-list-cta__item-button button button_style_1">
                                            <a class="button__inner" href="/services/software-engineering/devops-as-a-service/?utm_source=blog&#038;utm_medium=post_ID_675&#038;utm_campaign=cta_post_content_4052">                                                <div class="button__name">Our services</div>
                                            </a>                                        </div>
                                    </div>    
                                                                        
            	            </div>
            	                	        </div>
                </div>
                        </div>
    </div>
    



<h2 class="wp-block-heading">What Is GitOps?</h2>



<p class="wp-block-paragraph">GitOps is a relatively young approach in <a href="/services/software-engineering/">software engineering</a>. It has emerged on the basis of DevOps best practices, such as continuous integration, continuous deployment, version control, collaboration, etc. The ultimate goal is to automate infrastructure updates, make the process traceable and avoid human error.</p>



<p class="wp-block-paragraph"><b>Definition:</b> GitOps is a set of practices/an approach to a modern implementation of continuous deployment for cloud-native applications. When we talk about GitOps, we mean not only the deployment of the application source code, but also the deployment of infrastructure using tools that are popular among developers — Git, IaC (Infrastructure as Сode), continuous integration.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><b>The essence:</b> you describe the infrastructure you need for the target environment in a declarative manner and store the descriptions in a special Git repository; the process of making the environment match the described state is automated.</p>
</blockquote>



<p class="wp-block-paragraph">In a nutshell, developers are empowered to perform tasks that were traditionally performed by the Ops. If they want to deploy a new application or update an existing one, they only need to update the repository, and an automated process handles everything else.</p>



<p class="wp-block-paragraph">The most popular declarative <a href="/services/software-engineering/cloud-software-development/">cloud</a> infrastructure today is <a href="/blog/what-is-kubernetes/">Kubernetes</a>. GitOps is a perfect operating model for the Kubernetes-based infrastructure and applications development and delivery, as it combines Git with the Kubernetes convergence properties.</p>



<h3 class="wp-block-heading">It All Starts with Infrastructure as Code (IaC)</h3>



<p class="wp-block-paragraph">For a better understanding of GitOps, we should first explain the Infrastructure as Code (IaC) concept.</p>



<p class="wp-block-paragraph">Previously, operations engineers had to create infrastructure manually using PowerShell and kubectl scripts. In recent years, the practice of <b>defining infrastructure</b> (as well as configuration, network, security and other components) <b>in code</b> is gaining traction.</p>



<p class="wp-block-paragraph">Instead of creating a Kubernetes cluster with multiple nodes, you describe everything you need in files, using tools such as Terraform, Ansible, YAML Kubernetes manifest files, etc. This allows you to simplify the reproduction and replication of infrastructure and its components.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1211" height="981" src="https://sam-solutions.com/wp-content/uploads/Infrastructure-as-Code.png" alt="IaC Infrastructure as Code" class="wp-image-5759"/></figure>
</div>


<p class="wp-block-paragraph">There are two options for making it work:</p>



<ol class="wp-block-list">
<li>A <a href="/services/software-engineering/devops-as-a-service/">DevOps</a> engineer creates, tests, executes and stores all files <b>locally </b>on the computer.</li>



<li>A DevOps engineer creates a Git repository for IaC and stores all these files <b>on Git.</b> This is the preferable option because you get <b>version control</b> for your files, and other team members have <b>access</b> to the code.</li>
</ol>



<p class="wp-block-paragraph">However, this second method has serious disadvantages:</p>



<ul class="wp-block-list">
<li><b>No </b><b>pull requests</b><b>.</b> If you or your team members change the code, it is directly committed to the main branch.</li>



<li><b>No code review. </b>Consequently, nobody can collaborate on the changes and review the code.</li>



<li><b>No automated testing.</b> If you’ve committed files with errors, you’ll only find out once you applied them to the environment, because no automated tests are running to check the changes.</li>



<li><b>No traceability.</b> Each team member tests their changes manually in the development environment and then applies the changes manually in the staging and production environment. They access the Kubernetes cluster or cloud-platform infrastructure from the local computer and execute Terraform or Ansible commands. Hence, it’s hard to trace the history of changes and find out who applied a particular feature, which is critical if errors are found.</li>
</ul>



<p class="wp-block-paragraph">As you can see, IaC is a convenient method of infrastructure management, though it still needs improvements. This is where <b>the GitOps concept </b>comes into play. It aims to ensure the treatment of Infrastructure as Code in the same way as the application code, i.e. by combining a Git repository with a full DevOps pipeline (CI/CD).</p>



<h2 class="wp-block-heading">How Is GitOps Different from DevOps?</h2>



<p class="wp-block-paragraph">Looking at their names, it’s obvious that the two are interconnected. The definition from <a href="https://en.wikipedia.org/wiki/DevOps" target="_blank" rel="noreferrer noopener nofollow">Wikipedia</a> says that DevOps is a set of practices that combines software development (Dev) and IT operations (Ops) with the aim to shorten the systems development life cycle and provide continuous delivery with high software quality.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">GitOps is a logical continuation of the ideas that were incorporated in DevOps. In particular, GitOps is the evolution of the Infrastructure as Code concept, which itself originated in the DevOps environment.</p>
</blockquote>



<p class="wp-block-paragraph">GitOps has bridged the gap between existing DevOps practices, which were designed to address system administration challenges, and the specific needs of distributed cloud-hosted applications.</p>



<p class="wp-block-paragraph">As a separate practice, GitOps may be included in a set of DevOps practices; precisely, it aims at closer interaction with developers. Since Git is already being used for <a href="/">software development</a>, engaging Git in operations not only involves DevOps techniques but also harnesses the power of version control.</p>



<h2 class="wp-block-heading">How GitOps Works</h2>



<p class="wp-block-paragraph">As mentioned, the workflow of GitOps is based on the integration of the IaC system and the CI/CD pipeline. Let’s look at the GitOps operating mechanism.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1211" height="711" src="https://sam-solutions.com/wp-content/uploads/GitOps-workflow.png" alt="How GitOps works" class="wp-image-5762"/></figure>
</div>


<p class="wp-block-paragraph">1. First, a separate <b>Git repository</b> for the IaC project is created.</p>



<p class="wp-block-paragraph">2. If you need to make changes to the code, you <b>create a pull request</b>.</p>



<p class="wp-block-paragraph">3. A <b>CI pipeline</b> ensures the validation of config files and runs <a href="/services/qa-services/test-automation-services/">automated tests</a>.</p>



<p class="wp-block-paragraph">4. After automated testing, any team member can <b>review</b> commits and <b>approve</b> the pull request.</p>



<p class="wp-block-paragraph">5. Finally, approved updates are merged into the main branch through a <b>CD pipeline</b> and are then deployed to the Kubernetes environment. In other words, this is where new versioned artifacts of the infrastructure are prepared.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Thus, infrastructure code changes go through the same stages as application code changes. As a result, all changes are reviewed and tested before being applied in any environment, which significantly reduces the risk of breaking something.</p>
</blockquote>



<p class="wp-block-paragraph">6. The <b>convergence mechanism</b> ensures that updates made in the repository are applied to the Kubernetes cluster: the Kubernetes orchestrator compares properties of the cluster with updates in Git and applies them to the cluster until the observed state is identical to the configuration files in the repository. This mechanism is applicable to any Kubernetes resource.</p>



<h2 class="wp-block-heading">GitOps Principles</h2>



<p class="wp-block-paragraph"><b>1. Declarative description of systems.</b> The definition and configuration of systems are described as source code (e.g., YAML Kubernetes manifests). The code is stored and automatically versioned in a Git repository, which serves as the only source of truth. This approach makes it easy to roll out and roll back system changes.</p>



<p class="wp-block-paragraph"><b>2. Setting and versioning of the system’s </b><b>desired state</b><b> and configuration in Git.</b> By storing and versioning the desired state of systems in Git, you have the ability to easily roll out and roll back changes in systems and applications. You can also use Git&#8217;s security mechanisms to control ownership of the code and verify its authenticity.</p>



<p class="wp-block-paragraph"><b>3. Automatic application of approved changes. </b>Using Git pull requests, you can easily control how changes are applied to configurations in the repository. For example, you can give them to other team members for verification or run through CI tests, etc. To commit configuration changes, users only need the appropriate permissions in the Git repository where these configurations are stored.</p>



<p class="wp-block-paragraph"><b>4. Eliminating the problem of uncontrolled drift of configurations.</b> When the desired state of the system is stored in the Git repository, you only need to add software that would control that the current state of the system corresponds to its desired state. If there are inconsistencies, the software should either fix them or warn about the drift of configurations.</p>



<h2 class="wp-block-heading">How Is GitOps Put into Practice?</h2>



<p class="wp-block-paragraph">In systems working with GitOps, there is usually:</p>



<ul class="wp-block-list">
<li>a separate Git repository for infrastructure</li>



<li>a separate Git repository for the application code</li>



<li>the CI/CD pipeline.</li>
</ul>



<p class="wp-block-paragraph"><b>The infrastructure repository </b>is the only place in the system where the infrastructure configuration code is stored. This code manages configuration, creation, updating, and possibly deletion. This repository is the heart of IaC and the source of truth about what the infrastructure should be and what should work in it. When they want to make updates, developers upload files with code that acts as deployment instructions to this repository.</p>



<p class="wp-block-paragraph">If the state of the infrastructure differs from the state described in the repository, GitOps, as a tool, must bring the target state of the system to the state described in the repository.</p>



<p class="wp-block-paragraph"><b>The application code repository</b> is the basic project code.</p>



<p class="wp-block-paragraph">The third component of the system, the <b>CI/CD pipeline</b>, should be somehow connected with repositories to know when to run tests and deploy.</p>



<p class="wp-block-paragraph">For this purpose, there are two deployment strategies in GitOps.</p>



<h3 class="wp-block-heading">1. Push-Based Deployments</h3>



<p class="wp-block-paragraph">A push-based deployment strategy is essentially a classic CI/CD implementation using tools such as <b>Azure DevOps</b>,<b> GitHub Actions</b>,<b> Jenkins</b>,<b> GitLab</b>, and so on.</p>



<p class="wp-block-paragraph">We can see how it works by looking at Sitecore as an example. We have the source code of our Sitecore instance in the Git repository. In the same repository, we also store Kubernetes YAML files (infrastructure) necessary for deploying the application. As soon as the application code changes (Git Push), a pipeline build is triggered. It builds the container images, pushes these images to the Container Registry and deploys updated Kubernetes infrastructure manifests.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1211" height="711" src="https://sam-solutions.com/wp-content/uploads/Push-based-deployment1.png" alt="push-based deployment in GitOps" class="wp-image-5764"/></figure>
</div>


<p class="wp-block-paragraph"><b>Note:</b> There is a certain practice whereby the infrastructure code (YAMLs) is placed in a separate environment repository (see the scheme below). This approach is a little more complicated since it’s necessary to implement the update of the environment repository during the build of the pipeline.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1211" height="641" src="https://sam-solutions.com/wp-content/uploads/Push-based-deployment.png" alt="GitOps push-based deployment" class="wp-image-5766"/></figure>
</div>


<p class="wp-block-paragraph">Using the Push approach has some pros and cons.</p>



<p class="wp-block-paragraph"><b>Pros</b></p>



<ul class="wp-block-list">
<li>The Git repository and assembly pipeline define security.</li>



<li>Secret management is easier because secrets can be used in pipelines and stored in Git using encryption.</li>



<li>You’re not tied to a specific tool — you can use any type.</li>



<li>Container version updates can be initiated by the assembly pipeline.</li>
</ul>



<p class="wp-block-paragraph"><b>Cons</b></p>



<ul class="wp-block-list">
<li>Data for accessing the cluster is stored in the assembly system.</li>



<li>Updating the deployment containers is still easier in the pull process.</li>



<li>High dependency on the CD system (pipelines are written for a specific tool, and if the team decides to use another tool, they will have to migrate numerous pipelines).</li>



<li>The degree of security is still lower than in the pull process.</li>



<li>More monitoring is required.</li>
</ul>



<h3 class="wp-block-heading">2. Pull-Based Deployments</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1211" height="641" src="https://sam-solutions.com/wp-content/uploads/Pull-based-deployment.png" alt="GitOps pull-based deployment" class="wp-image-5768"/></figure>
</div>


<p class="wp-block-paragraph">With a pull-based approach, the same concepts are used as with the push-based approach. The difference is that an operator is added to perform the role of a pipeline.</p>



<p class="wp-block-paragraph">An operator (agent) is installed in the environment (e.g., Kubernetes cluster) and pulls changes from the repository itself. The operator regularly checks the state of the infrastructure code in the repository, comparing it to the current state in the environment. If a difference in the repository is detected, the agent pulls and applies changes in the environment to get it from the actual to the desired state. Moreover, it monitors the image registry for any new versions of images.</p>



<p class="wp-block-paragraph">Unlike a push-based process that updates the environment only when the repository is updated, a pull-based deployment can find changes even if they aren’t described in the repository. An operator will send you a notification if it can’t apply the requested changes to the environment. This means there is a greater degree of transparency.</p>



<p class="wp-block-paragraph">Tools working with the pull-based model are <b>Flux and Argo</b>. They run inside the Kubernetes cluster and transfer updates from the repository to the cluster. The Kubernetes <a href="/services/software-engineering/api-development-services/">API</a> server accepts declarative descriptions of updates and manipulates the objects in the cluster (e.g., namespaces, pods, events, ConfigMaps) in order to achieve the desired state as described in the Git.</p>



<p class="wp-block-paragraph"><b>Pros</b></p>



<ul class="wp-block-list">
<li>Nobody can change the cluster from the outside.</li>



<li>You can scan Docker Registry for new versions and, if found, update the repository and deployment.</li>



<li>Pull tools can be distributed across various namespaces with different Git repositories and access rights. This makes it possible to use a multi-tenant model.</li>



<li>Secrets can be stored encrypted in Git and extracted inside the cluster.</li>



<li>There is no dependency on the CD pipeline because deployments take place inside the cluster.</li>
</ul>



<p class="wp-block-paragraph"><b>Cons&nbsp;</b></p>



<ul class="wp-block-list">
<li>It’s more difficult to manage deployment secrets from Helm charts.</li>



<li>You are tied to pull operating tools, which limits configuration opportunities in the cluster.</li>
</ul>



<h2 class="wp-block-heading">Benefits of Using GitOps</h2>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1211" height="1361" src="https://sam-solutions.com/wp-content/uploads/GitOps-benefits.png" alt="Benefits of using GitOps" class="wp-image-5770"/></figure>
</div>


<ul class="wp-block-list">
<li><b>Automation</b> — when configuring infrastructure, manual tasks are eliminated, saving a lot of time.</li>



<li><b>Transparency</b> — the process allows you to easily trace all the changes made to the code due to time stamps, commit IDs and all the information about committers.</li>



<li><b>Collaboration</b> — since everyone in the team can collaborate on the code and review updates, the result is always of high quality.</li>



<li><b>Fast and frequent deliveries</b> — teams can deliver updates faster and more frequently due to the automation process; it may take from several hours to several minutes.</li>



<li><b>Easy rollback</b> — due to version control, you can easily roll back your environment to any previous state; this is highly important if applied changes break something and the cluster doesn’t work.</li>



<li><b>Security</b> — the code review opportunity, automated testing and version control make deployment more secure.</li>



<li><b>Self-documenting deployment</b> — there is no need for architects or tech leads to keep the infrastructure documentation separately: everything is stored in Git, so there is always an up-to-date version. In addition, this approach enables fast onboarding of new developers to the project.</li>
</ul>



<h2 class="wp-block-heading">GitOps Challenges</h2>



<p class="wp-block-paragraph">The greatest challenge is the initial configuration of the process. As soon as everything is set up, the system will run like clockwork.</p>



<p class="wp-block-paragraph">You may face another issue — the engagement of all team members in this process. Working with GitOps may seem boring and time-consuming to those developers who are used to making quick changes manually. That’s why you should take time to explain GitOps benefits and convince your teammates to follow the new process and write down every change diligently.</p>



<h2 class="wp-block-heading">GitOps Example</h2>



<p class="wp-block-paragraph">The following is an example of using GitOps from my practical experience.</p>



<p class="wp-block-paragraph">In one Sitecore project, the client identified a performance issue in the live site (content delivery, using Sitecore terminology). The Dev team looked into the GitOps repository that held infrastructure configuration and figured out all major Sitecore deployments (CM, CD, Identity) configured (via <b>nodeSelector </b>settings) to run pods on the same Kubernetes Node at a time when the cluster had another empty Node.</p>



<p class="wp-block-paragraph">The Dev team decided to rebalance the pods to run CD separately from CM and Identity.</p>



<ul class="wp-block-list">
<li>A developer opened up a new pull request to apply appropriate <b>nodeSelector </b>settings to the CD YAML configuration.</li>



<li>That pull request was reviewed and approved by the Dev team and merged into the repository.</li>



<li>The merge kicked off a GitOps pipeline, which triggered the GitOps operator (Pull strategy).</li>



<li>The operator detected that the CD configuration had changed. It confirmed with the systems orchestration tool that this did not match what was live on the cluster.</li>



<li>The operator alerted the orchestration system to update the CD configuration.</li>



<li>The orchestrator handled the rest and automatically deployed the newly configured CD.</li>



<li>The Dev team confirmed that the CD pod was running on another Node and the performance issue was gone.</li>
</ul>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">GitOps is an incredibly powerful automated operating model for managing modern cloud-native solutions and infrastructure. Unlike the IaC concept that deals with disintegrated local machines, GitOps ensures centralized storage of files on a remote server backed up by DevOps best practices.</p>



<p class="wp-block-paragraph">Though initially focused on Kubernetes cluster management, GitOps can be applicable to other non-Kubernetes systems, bringing numerous benefits to them. If you need to improve the communication in your team, ensure the transparency and reliability of the system, I highly recommend you consider GitOps for infrastructure management.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/what-is-gitops/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Mount a Sitecore License File in Kubernetes via Azure File Persistent Volume</title>
		<link>https://sam-solutions.com/blog/mount-sitecore-license-file-in-kubernetes/</link>
					<comments>https://sam-solutions.com/blog/mount-sitecore-license-file-in-kubernetes/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Thu, 16 Sep 2021 13:10:38 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=561</guid>

					<description><![CDATA[In this blog post, I will describe how to resolve the issue when your encoded Sitecore License is too big to be placed into the Azure DevOps variable to be consumed by Kubernetes as a secret value. In two words, we will use the Kubernetes persistent volume as an Azure File share. As we know, [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In this blog post, I will describe how to resolve the issue when your encoded Sitecore License is too big to be placed into the Azure DevOps variable to be consumed by Kubernetes as a secret value. In two words, we will use the Kubernetes persistent volume as an Azure File share.</p>



<span id="more-561"></span>



<p class="wp-block-paragraph">As we know, the <a href="/services/portals-wcms/sitecore/">Sitecore</a> license file is passed to the container as an environment variable (called <b>Sitecore_License</b>) in the encoded string form. In Kubernetes, we usually put this encoded value into a secret file; for instance:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="569" height="174" src="https://sam-solutions.com/wp-content/uploads/Sitecore-Secret-License-min.png" alt="Sitecore-license-file-in-kubernetes" class="wp-image-5825"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1131" height="196" src="https://sam-solutions.com/wp-content/uploads/Sitecore-k8s-License-Secret-min.png" alt="Mount-Sitecore-License-File-in-Kubernetes " class="wp-image-5827"/></figure>
</div>


<p class="wp-block-paragraph">We store and manage all Sitecore K8S specifications in source control, and the secrets are no exception. For security reasons, keeping secrets in source control is bad practice. In a project I was involved in, we used the Azure DevOps variable group to define all secrets.</p>



<p class="wp-block-paragraph">Unfortunately, the Sitecore License secret is too big to be kept as an Azure DevOps variable. It says: “Length of variable `SITECORE_LICENSE` is invalid. It must be between 0 and 4096 characters.”</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1558" height="230" src="https://sam-solutions.com/wp-content/uploads/Azure-DevOps-Issue-min.png" alt="Sitecore-license-Azure-persistnt-volume" class="wp-image-5829"/></figure>
</div>


<p class="wp-block-paragraph">One solution is to store the license secret in the Azure key-vault. But I would like to introduce another solution — <b>Kubernetes Persistent Volumes</b> (volumes defined and created as part of the pod lifecycle only exist until you delete the pod).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="398" height="299" src="https://sam-solutions.com/wp-content/uploads/aks-storage-options-min.png" alt="Sitecore-license-in-Azure-Kubernetes" class="wp-image-5832"/></figure>
</div>


<p class="wp-block-paragraph"><i>Source: </i><a href="https://docs.microsoft.com/en-us/azure/aks/concepts-storage#persistent-volumes" target="_blank" rel="noreferrer noopener nofollow"><i>Microsoft</i></a><i>  </i></p>



<p class="wp-block-paragraph">Kubernetes supports different types of volumes and one of them is <a href="https://kubernetes.io/docs/concepts/storage/volumes/#azurefile" target="_blank" rel="noreferrer noopener nofollow">Azure File persistent volume</a>. This means we can create the Azure File Share, put the Sitecore license file into and mount it as a Kubernetes volume. The following algorithm shows how to do that:</p>



<h3 class="wp-block-heading"><b>Step 1. </b>Create a resource group (<b>sugbelarus1</b> in my sample).</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="710" height="524" src="https://sam-solutions.com/wp-content/uploads/File-Share-1-min.png" alt="Step 1" class="wp-image-5834"/></figure>
</div>


<h3 class="wp-block-heading"><b>Step 2.</b> Create a storage account (<b>sugbelarus</b> in my sample).</h3>



<h3 class="wp-block-heading"><b>Step 3.</b> Create the Azure File Share (license in my sample).</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="758" height="503" src="https://sam-solutions.com/wp-content/uploads/File-Share-2-min.png" alt="Step 3" class="wp-image-5836"/></figure>
</div>


<h3 class="wp-block-heading"><b>Step 4.</b> Get the storage account key.</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="573" height="735" src="https://sam-solutions.com/wp-content/uploads/File-Share-Key-min.png" alt="Step 4" class="wp-image-5838"/></figure>
</div>


<p class="wp-block-paragraph">All these steps could be completed via Azure CLI.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
# Change these four parameters as needed for your own environment
AKS_PERS_STORAGE_ACCOUNT_NAME=sugbelarus
AKS_PERS_RESOURCE_GROUP=sugbelarus1
AKS_PERS_LOCATION=eastus
AKS_PERS_SHARE_NAME=license

# Create a resource group
az group create --name $AKS_PERS_RESOURCE_GROUP --location $AKS_PERS_LOCATION&amp;amp;amp;nbsp;

# Create a storage account
az storage account create -n $AKS_PERS_STORAGE_ACCOUNT_NAME -g $AKS_PERS_RESOURCE_GROUP -l $AKS_PERS_LOCATION --sku Standard_LRS&amp;amp;amp;nbsp;

# Export the connection string as an environment variable, this is used when creating the Azure file share
export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string -n $AKS_PERS_STORAGE_ACCOUNT_NAME -g $AKS_PERS_RESOURCE_GROUP -o tsv)&amp;amp;amp;nbsp;

# Create the file share
az storage share create -n $AKS_PERS_SHARE_NAME --connection-string $AZURE_STORAGE_CONNECTION_STRING&amp;amp;amp;nbsp;

# Get storage account key
STORAGE_KEY=$(az storage account keys list --resource-group $AKS_PERS_RESOURCE_GROUP --account-name $AKS_PERS_STORAGE_ACCOUNT_NAME --query &quot;&#x5B;0].value&quot; -o tsv)&amp;amp;amp;nbsp;

# Echo storage account name and key
echo Storage account name: $AKS_PERS_STORAGE_ACCOUNT_NAME
echo Storage account key: $STORAGE_KEY
</pre></div>


<h3 class="wp-block-heading"><b>Step 5. </b>Upload the Sitecore license file.</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="646" height="311" src="https://sam-solutions.com/wp-content/uploads/File-Share-3-min-1.png" alt="Step 5" class="wp-image-5840"/></figure>
</div>


<h3 class="wp-block-heading"><b>Step 6.</b> Create a Kubernetes secret.</h3>



<p class="wp-block-paragraph">Kubernetes needs credentials to access the file share created in the previous steps:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
kubectl create secret generic azure-secret
--from-literal=azurestorageaccountname=$AKS_PERS_STORAGE_ACCOUNT_NAME
--from-literal=azurestorageaccountkey=$STORAGE_KEY
</pre></div>


<p class="wp-block-paragraph">Run the kubectl get secrets command to validate if a new secret was created.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1260" height="194" src="https://sam-solutions.com/wp-content/uploads/Validate-Secret-min.png" alt="Step 6" class="wp-image-5842"/></figure>
</div>


<p class="wp-block-paragraph">You can also validate via Visual Studio Code using the Kubernetes extension.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1309" height="664" src="https://sam-solutions.com/wp-content/uploads/Validate-Secret-VS-Code-min.png" alt="Step 6-1" class="wp-image-5844"/></figure>
</div>


<h3 class="wp-block-heading"><b>Step 7. </b>Configure the volume in the container specification; for instance, cm.yaml file.</h3>



<ul class="wp-block-list">
<li>Define the volumeMounts section:</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="441" height="543" src="https://sam-solutions.com/wp-content/uploads/VolumeMounts-min.png" alt="Step 7" class="wp-image-5846"/></figure>
</div>


<ul class="wp-block-list">
<li>Define the Volume section.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="332" height="160" src="https://sam-solutions.com/wp-content/uploads/Volume-min.png" alt="Step 7-1" class="wp-image-5848"/></figure>
</div>


<ul class="wp-block-list">
<li>Define the SITECORE_LICENSE_LOCATION environment variable (from Sitecore 9.X you can use this variable to configure the license location).</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="557" height="765" src="https://sam-solutions.com/wp-content/uploads/Sitecore_LICENSE_LOCATION-min.png" alt="Step 7-2" class="wp-image-5850"/></figure>
</div>


<h3 class="wp-block-heading"><b>Step 8.</b> Deploy updated specification (kubectl apply command) and exec the updated pod.</h3>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
kubectl exec --stdin --tty cm-854986576d-l2cls
</pre></div>


<p class="wp-block-paragraph">Where cm-797498f98d-lj6bz – pod name (run kubectl get pods command to get the name)</p>



<p class="wp-block-paragraph">Make sure you can find the license file where you mounted it.</p>



<p class="wp-block-paragraph">That’s it for today! Happy voluming, everyone!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/mount-sitecore-license-file-in-kubernetes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Switch SolrCloud Indexes During Sitecore PaaS Blue-Green Deployment</title>
		<link>https://sam-solutions.com/blog/switch-solr-indexes-in-sitecore/</link>
					<comments>https://sam-solutions.com/blog/switch-solr-indexes-in-sitecore/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 14:03:00 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=631</guid>

					<description><![CDATA[Sitecore has a great feature — Switch On Rebuild — that supports search index swapping once the rebuilding of the index completes. In this article, I want to share my experience of implementing this feature in practice. Problem I was involved in one project based on Sitecore 9.3 Managed Cloud and SolrCloud, where we built [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Sitecore has a great feature — Switch On Rebuild — that supports search index swapping once the rebuilding of the index completes.</p>



<p class="wp-block-paragraph">In this article, I want to share my experience of implementing this feature in practice.</p>



<span id="more-631"></span>



<h2 class="wp-block-heading">Problem</h2>



<p class="wp-block-paragraph">I was involved in one project based on Sitecore 9.3 Managed Cloud and SolrCloud, where we built a custom search index to crawl products every 12 hours. That was a huge one (with more than 3 million products at the time of this writing) and the entire rebuild took 8–10 hours.</p>



<p class="wp-block-paragraph">In Sitecore, there is a mechanism for <a href="https://doc.sitecore.com/developers/93/platform-administration-and-architecture/en/switch-solr-indexes.html#switch-solrcloud-indexes_body" target="_blank" rel="nofollow noopener">switching between active and rebuild indexes</a> in order to avoid downtime in search functionality on the website. We, therefore, configured the Switch On Rebuild feature for this custom index so that the rebuilding process doesn’t affect the active index used on the live site.</p>



<p class="wp-block-paragraph">As for continuous delivery, we used the <a href="https://docs.microsoft.com/en-us/azure/app-service/deploy-staging-slots" target="_blank" rel="nofollow noopener">blue-green deployment</a> approach so as to have zero production downtime.</p>



<p class="wp-block-paragraph">After each deployment, we triggered a full rebuild of our custom index and occasionally faced the problem of having the active index running instead of the rebuilt one.</p>



<p class="wp-block-paragraph">For instance, before deployment, we have the following alias statuses in SOLR cloud:</p>



<ul class="wp-block-list">
<li><b>active collection</b> — product_index_rebuild (in SolrCloud it maps through aliases)</li>



<li><b>rebuild collection</b> — product_index (in SolrCloud it maps through aliases)</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1261" height="571" src="https://sam-solutions.com/wp-content/uploads/SolrCloud_Aliases-min.png" alt="Switch On Rebuild Sitecore " class="wp-image-6092"/></figure>
</div>


<p class="wp-block-paragraph"><i>Main alias (active index) — </i><b><i>product_index_rebuild</i></b><i> collection (In SolrCloud, search core is called collection)</i></p>



<p class="wp-block-paragraph">This means that the next time we trigger the index, it should be <i>product_index</i>. But we see quite the opposite in practice: the active index is running, the live site is broken, and data search is unavailable.</p>



<h3 class="wp-block-heading">What Is the Cause of the Problem?</h3>



<p class="wp-block-paragraph"><a href="/services/portals-wcms/sitecore/">Sitecore</a> has a property store where it stores some major facts about search indexes, such as when the index was last updated. And if the index has the <b>Switch on Rebuild</b> functionality, it stores information on which collection is <i>Active</i> and which is <i>Rebuild</i>. It happens inside the <b>SwapAfterRebuild</b> method (Class: <b>SwitchOnRebuildSolrCloudSearchIndex</b>, Assembly:  <b>Sitecore.ContentSearch.SolrProvider</b>) where the <b>PreserveAliasesCollections</b> is called.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1027" height="465" src="https://sam-solutions.com/wp-content/uploads/Swap-After-Rebuild-min.png" alt="Switch On Rebuild in Sitecore" class="wp-image-6095"/></figure>
</div>


<p class="wp-block-paragraph">All the data is located in the <b>Properties </b>table (<b>core</b> database):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="256" height="94" src="https://sam-solutions.com/wp-content/uploads/Properties-Table.png" alt="Switch On Rebuild in Sitecore and SolrCloud" class="wp-image-6097"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="457" height="161" src="https://sam-solutions.com/wp-content/uploads/SQL-Script.png" alt="Switch On Rebuild feature in Sitecore" class="wp-image-6099"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1416" height="164" src="https://sam-solutions.com/wp-content/uploads/Active-Rebuild-SQL.png" alt="Switch On Rebuild Sitecore search index" class="wp-image-6101"/></figure>
</div>


<p class="wp-block-paragraph">As you can see, this table has three columns. <b>Key </b>and <b>Value</b> columns are of main interest to us.</p>



<p class="wp-block-paragraph">The Key column comprises the following parts:</p>



<ul class="wp-block-list">
<li><strong>CORE</strong> — just the core prefix (core aka collection in SolrCloud)</li>



<li><strong>PRODUCT_INDEX</strong> — the name of the index</li>



<li><strong>RD50***B1F27</strong> — server Machine Name. The machine where the CM instance is hosted as PaaS</li>



<li><strong>MC-EDD***501-CM__6554 &#8211; WEBSITE_IIS_SITE_NAME</strong></li>



<li><strong>SOLR_ACTIVE_COLLECTION</strong> — the active collection in SOLR</li>



<li><strong>REBUILD_COLLECTION</strong> — the collection that will be rebuilt next</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="711" height="713" src="https://sam-solutions.com/wp-content/uploads/IIndexPropertyStore-min.png" alt="Switch On Rebuild to swap indexes in Sitecore" class="wp-image-6103"/></figure>
</div>


<p class="wp-block-paragraph">The <b>IndexDatabasePropertyStore (Assembly: Sitecore.ContentSearch) </b>type implements this interface. Below you can see the implementation of the <b>Set </b>method with its dependencies:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="986" height="740" src="https://sam-solutions.com/wp-content/uploads/Set-Method-min.png" alt="Switch On Rebuild Blue-Green Deployment" class="wp-image-6105"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="947" height="480" src="https://sam-solutions.com/wp-content/uploads/InstanceName-min.png" alt="Switch On Rebuild " class="wp-image-6107"/></figure>
</div>


<p class="wp-block-paragraph">In the <b>Property </b>table, you can find more than one pair because Azure can change the Machine Name for any reason.</p>



<p class="wp-block-paragraph">How do you validate the current <b>Machine Name</b> and <b>WEBSITE_IIS_SITE_NAME</b>? In the Azure portal, navigate to CM AppService and run Advanced Tools (aka KUDU):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="744" height="290" src="https://sam-solutions.com/wp-content/uploads/Advanced-Tools-min.png" alt="Switch On Rebuild Sitecore SolrCloud" class="wp-image-6109"/></figure>
</div>


<p class="wp-block-paragraph">Click the Environment tab where you can observe all major metadata about this App Service. For instance, you can find the <b>Machine Name</b>, <b>WEBSITE_IIS_SITE_NAME</b>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="543" height="526" src="https://sam-solutions.com/wp-content/uploads/Machine-Name-min.png" alt="Switch On Rebuild feature in Sitecore" class="wp-image-6111"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="752" height="247" src="https://sam-solutions.com/wp-content/uploads/Website-Name-min.png" alt="Switch On Rebuild to swap search indexes in Sitecore" class="wp-image-6113"/></figure>
</div>


<p class="wp-block-paragraph">And what happens when we run the blue-green deployment?</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="953" height="319" src="https://sam-solutions.com/wp-content/uploads/Deployment-Slots-min.png" alt="Sitecore Switch On Rebuild " class="wp-image-6115"/></figure>
</div>


<p class="wp-block-paragraph">When the deployment completes, a new deployment slot becomes available. This slot is another App Service that has its own <b>Machine Name</b> and <b>WEBSITE_IIS_SITE_NAME</b>; for instance:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1273" height="132" src="https://sam-solutions.com/wp-content/uploads/After-Blue-Green.png" alt="Switch On Rebuild during blue-green deployment" class="wp-image-6117"/></figure>
</div>


<p class="wp-block-paragraph">In the scope of Active/Rebuild collections stored in the Property table, Sitecore does not synchronize slots between each other. What does that mean for us? It means we could end up with a situation in which the status of both active/rebuilt collections is different.</p>



<h3 class="wp-block-heading">Example</h3>



<p class="wp-block-paragraph">Let’s assume the current Machine Name is <b>A</b>. But we also have machine <b>B</b> that will be swapped when the blue-green deployment occurs. Machine <b>B</b> has Active Collection — product_index_rebuild, Rebuild Collection — product_index. When we trigger the deployment, machine <b>A</b> looks like this:</p>



<ul class="wp-block-list">
<li>Active Collection — product_index</li>



<li>Rebuild Collection — product_index_rebuild</li>
</ul>



<p class="wp-block-paragraph">Consequently, on the live site, the product_index is active. After the deployment, machine <strong>B</strong> is active, and when we trigger the index, the product_index is run; this is an issue because another index needs to be run.</p>



<h2 class="wp-block-heading">Solution</h2>



<p class="wp-block-paragraph"><b>This issue can be resolved as follows:</b></p>



<ol class="wp-block-list">
<li>After the blue-green deployment, run SQL script to compare Active/Rebuild collections between deployment slots:</li>



<li>If #1 <strong>re</strong>synchronized, update records for the active deployment slot (machine). It’s also possible to delete these two records.</li>
</ol>



<p class="wp-block-paragraph">You can automate these steps by writing a script and executing it in the scope of the Content Delivery pipeline.</p>



<p class="wp-block-paragraph"><b>Note: </b>the ContentSearch.Solr.<b>EnforceAliasCreation</b> setting (part of the <i>SwitchOnRebuildSolrCloudSearchIndex class</i>) should be <i>False</i>. If this setting is True, Sitecore creates aliases every time the CM instance is reset.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1251" height="238" src="https://sam-solutions.com/wp-content/uploads/Enforce.png" alt="Switch On Rebuid Sitecore blue-green deployment" class="wp-image-6119"/></figure>
</div>


<p class="wp-block-paragraph">I hope you will find my experience useful. That’s it for today.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/switch-solr-indexes-in-sitecore/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[TechSpeak] Sitecore Search: How SOLR Timeout Exception Affects Index Optimization</title>
		<link>https://sam-solutions.com/blog/sitecore-search-solr-timeout-exception-and-index-optimization/</link>
					<comments>https://sam-solutions.com/blog/sitecore-search-solr-timeout-exception-and-index-optimization/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Fri, 26 Feb 2021 14:40:21 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=612</guid>

					<description><![CDATA[If you have a custom SOLR index in your Sitecore-based project and it becomes too big (more than 1 million documents), you may face a problem when the rebuild process times out because of the SOLR connection timeout exception. Today, I’ll tell you how we dealt with this issue. Problem In our Sitecore project, we [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If you have a custom SOLR index in your Sitecore-based project and it becomes too big (more than 1 million documents), you may face a problem when the rebuild process times out because of the SOLR connection timeout exception. Today, I’ll tell you how we dealt with this issue.</p>



<span id="more-612"></span>



<h2 class="wp-block-heading">Problem</h2>



<p class="wp-block-paragraph">In our Sitecore project, we built a custom product index containing more than two million documents. This index has a custom crawler with complex logic, which includes reading thousands of JSON files and calling different <a href="/services/software-engineering/api-development-services/">APIs</a> (e.g product ingestion, third-party data storage).</p>



<p class="wp-block-paragraph">To implement the search functionality, we used the SOLR Cloud topology (from the SearchStax vendor) with the Switch On Rebuild feature (Zero downtime rebuild).</p>



<p class="wp-block-paragraph">There is a custom automation process that triggers the index every night out of work hours. It takes about six hours, give or take, to process two million documents.</p>



<p class="wp-block-paragraph">Once, when the index contained 500,000–600,000 documents, we got the following SOLR timeout connection exception:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
Exception: SolrNet.Exceptions.SolrConnectionException
Message: The operation has timed out
Source: SolrNet
   at SolrNet.Impl.SolrConnection.PostStream(String relativeUrl, String contentType, Stream content, IEnumerable`1 parameters)
   at SolrNet.Impl.SolrConnection.Post(String relativeUrl, String s)
   at SolrNet.Impl.LowLevelSolrServer.SendAndParseHeader(ISolrCommand cmd)
   at Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex.PerformRebuild(Boolean resetIndex, Boolean optimizeOnComplete, IndexingOptions indexingOptions, CancellationToken cancellationToken)
   at Sitecore.ContentSearch.SolrProvider.SolrSearchIndex.Rebuild(Boolean resetIndex, Boolean optimizeOnComplete)
</pre></div>


<p class="wp-block-paragraph">This happened when the rebuild process had been completed and <a href="/services/portals-wcms/sitecore/">Sitecore</a> sent a request to SOLR to optimize the index.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1326" height="86" src="https://sam-solutions.com/wp-content/uploads/Sitecore-Switch-On-Rebuild-Solr-Cloud-Search-Index.png" alt="Sitecore Switch On Rebuild Solr Cloud Search Index" class="wp-image-6282"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1271" height="168" src="https://sam-solutions.com/wp-content/uploads/Perform-Rebuild.png" alt="Perform Rebuild" class="wp-image-6284"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1141" height="600" src="https://sam-solutions.com/wp-content/uploads/OptimizeOnComplete-min.png" alt="Optimize On Complete" class="wp-image-6286"/></figure>
</div>


<p class="wp-block-paragraph"><i>Source: Sitecore.ContentSearch.SolrProvider.</i><b><i>SwitchOnRebuildSolrSearchIndex</i></b><i>.PerformRebuild(Boolean resetIndex, Boolean </i><b><i>optimizeOnComplete</i></b><i>, IndexingOptions indexingOptions, CancellationToken cancellationToken)</i></p>



<p class="wp-block-paragraph">Sitecore enthusiasts have already <a href="https://codeandlearnspot.wordpress.com/2019/05/30/solr-timeout-exception-sitecore-master-web-index-rebuild-fail/" target="_blank" rel="noreferrer noopener nofollow">discussed this issue</a>.</p>



<h2 class="wp-block-heading">Solution</h2>



<p class="wp-block-paragraph">To resolve this issue, we had to increase the <b>ConnectionTimeout </b>value. We changed it to 60,000, equalling 10 minutes. And it worked!</p>



<p class="wp-block-paragraph">But our index was growing fast, and when it exceeded 2 million documents, we got the SOLR timeout issue again.</p>



<p class="wp-block-paragraph">We increased that parameter to 120,000 (20 minutes), then to 360,000 (1 hour), but that didn’t help. We had to discover the source of the problem and resolve it.</p>



<p class="wp-block-paragraph">Let’s take a look at how the official <a href="https://solr.apache.org/guide/7_5/index-replication.html" target="_blank" rel="noreferrer noopener nofollow">SOLR documentation</a> describes optimization:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1140" height="387" src="https://sam-solutions.com/wp-content/uploads/Optimization-Official-Doc.png" alt="Optimization Official Doc" class="wp-image-6289"/></figure>
</div>


<p class="wp-block-paragraph">As you can see, optimization may improve the query performance when the index has become fragmented by many updates.</p>



<p class="wp-block-paragraph">In our case, we had a daily full rebuild process, which means that we had a fresh index every day. And, as noted in the SOLR documentation, we <b>did not need to optimize it</b>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><i>Optimizing is </i><b><i>not recommended</i></b><i> unless it can be performed regularly as it may lead to a significantly larger portion of the index consisting of deleted documents than would normally be the case.</i></p>
</blockquote>



<p class="wp-block-paragraph">To avoid <b>the optimization process</b>, you can develop your own type of index inherited from the one you used before.</p>



<p class="wp-block-paragraph">In our case, it was the <b>SwitchOnRebuildSolrCloudSearchIndex </b>(we used index swapping due to the zero downtime).</p>



<p class="wp-block-paragraph">Then, you need to override the <b>Rebuild()</b> method: call the base method by setting the <b>false </b>value for the <b>optimizeOnComplete</b> parameter. This means that Sitecore <b>will not trigger</b> the Optimize command to SOLR:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="931" height="190" src="https://sam-solutions.com/wp-content/uploads/Rebuild-Method.png" alt="Rebuild Method" class="wp-image-6291"/></figure>
</div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
public class NotOptimizedSwitchOnRebuildSolrCloudSearchIndex :
        SwitchOnRebuildSolrCloudSearchIndex,
        ISolrCloudIndex,
        ISearchIndex,
        IDisposable
    {
        public NotOptimizedSwitchOnRebuildSolrCloudSearchIndex(
            string name,
            string mainalias,
            string rebuildalias,
            string activecollection,
            string rebuildcollection,
            ISolrOperationsFactory solrOperationsFactory,
            IIndexPropertyStore propertyStore) : base(
            name,
            mainalias,
            rebuildalias,
            activecollection,
            rebuildcollection,
            solrOperationsFactory,
            propertyStore)
        {
        }

        public NotOptimizedSwitchOnRebuildSolrCloudSearchIndex(
            string name,
            string mainalias,
            string rebuildalias,
            string activecollection,
            string rebuildcollection,
            IIndexPropertyStore propertyStore) : base(
            name,
            mainalias,
            rebuildalias,
            activecollection,
            rebuildcollection,
            propertyStore)
        {
        }

        public NotOptimizedSwitchOnRebuildSolrCloudSearchIndex(
            string name,
            string mainalias,
            string rebuildalias,
            string activecollection,
            string rebuildcollection,
            IIndexPropertyStore propertyStore,
            ISolrProviderContextFactory providerContextFactory,
            string @group) : base(
            name,
            mainalias,
            rebuildalias,
            activecollection,
            rebuildcollection,
            propertyStore,
            providerContextFactory,
            @group)
        {
        }

        public override void Rebuild()
        {
            Rebuild(true, false);
        }
    }
</pre></div>


<p class="wp-block-paragraph">Then, insert the created type into the index config:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1337" height="406" src="https://sam-solutions.com/wp-content/uploads/Not-Optimized-Switch-On-Rebuild-Config.png" alt="Not Optimized Switch On Rebuild Config" class="wp-image-6293"/></figure>
</div>


<p class="wp-block-paragraph">And that should do the trick! Happy coding, dear Sitecorian. See you next time.</p>



<p class="wp-block-paragraph">P.S. Thanks to my colleague Vadim Birkos for brainstorming this issue.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/sitecore-search-solr-timeout-exception-and-index-optimization/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[TechSpeak] Sitecore JSS SXA: How to Build Custom Snippet</title>
		<link>https://sam-solutions.com/blog/sitecore-jss-sxa-how-to-build-custom-snippet/</link>
					<comments>https://sam-solutions.com/blog/sitecore-jss-sxa-how-to-build-custom-snippet/#respond</comments>
		
		<dc:creator><![CDATA[Vadzim Papko]]></dc:creator>
		<pubDate>Sat, 28 Nov 2020 14:41:20 +0000</pubDate>
				<guid isPermaLink="false">https://sam-solutions.de/?post_type=article&#038;p=611</guid>

					<description><![CDATA[In this blog post, I will tell you how we built a custom Sitecore JSS Snippet component in a project based on Sitecore 9.2 SXA + JSS and explain how it helped solve a client&#8217;s requirement. The Problem Our client needed a possibility to create reusable macrocomponents from a bunch of microcomponents and use them [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In this blog post, I will tell you how we built a custom Sitecore JSS Snippet component in a project based on Sitecore 9.2 SXA + JSS and explain how it helped solve a client&#8217;s requirement.</p>



<span id="more-611"></span>



<h2 class="wp-block-heading">The Problem</h2>



<p class="wp-block-paragraph">Our client needed a possibility to create reusable macrocomponents from a bunch of microcomponents and use them across pages and sites included in one JSS tenant.</p>



<p class="wp-block-paragraph">Let’s assume we have the following list of JSS components (microcomponents):</p>



<ul class="wp-block-list">
<li>Section — a root component</li>



<li>Grid Component</li>



<li>Rich Text Component</li>



<li>Image Component.</li>
</ul>



<p class="wp-block-paragraph">And we want to build a macrocomponet using these microcomponents as follows:</p>



<ul class="wp-block-list">
<li>Put a Grid with two columns in a Section placeholder.</li>



<li>Put an Image Component in the Left Column.</li>



<li>Put a Rich Text Component in the Right Column.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1525" height="507" src="https://sam-solutions.com/wp-content/uploads/Macrocomponent-Sample-min.png" alt="Macrocomponent Sample" class="wp-image-6443"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="265" height="190" src="https://sam-solutions.com/wp-content/uploads/Sitecore-JSS-Components-min.png" alt="Sitecore JSS Components" class="wp-image-6445"/></figure>
</div>


<p class="wp-block-paragraph">In Sitecore SXA, there is an out-of-the-box <a href="https://doc.sitecore.com/users/sxa/19/sitecore-experience-accelerator/en/add,-reuse,-and-edit-a-snippet.html" target="_blank" rel="nofollow noopener noreferrer">Snippet component</a> to cover such cases.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="219" height="211" src="https://sam-solutions.com/wp-content/uploads/SXA-snippet-min.png" alt="SXA snippet" class="wp-image-6447"/></figure>
</div>


<p class="wp-block-paragraph">Since our project was a combination of Sitecore SXA and JSS, we couldn’t use the SXA’s Snippet component. We had to develop a custom one.</p>



<h2 class="wp-block-heading">Solution</h2>



<p class="wp-block-paragraph">The following idea came up to my mind.</p>



<ol class="wp-block-list">
<li>Create a simple JSS Component (aka Snippet) with a <b>snippet-content</b> placeholder inside.</li>



<li>Create a new JSS Layout specifically to build a Snippet component structure separately.</li>



<li>Put the Snippet Component (built in step 1) on the main JSS Layout (used for content pages). Select the Snippet Item created separately using the JSS Layout in step 2 as a data source.</li>



<li>At runtime during the rendering process, check if the rendered item contains a Snippet Component somewhere. If YES — get a Snippet DataSouce, render it and put the rendered result in the snippet-content placeholder.</li>
</ol>



<h2 class="wp-block-heading">Implementation</h2>



<ol class="wp-block-list">
<li>The first step is quite simple. In our project, we used the Sitecore First approach mode to build JSS components.</li>
</ol>



<p class="wp-block-paragraph">In <a href="/services/portals-wcms/sitecore/">Sitecore</a>, create a Snippet JSON Rendering:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1088" height="311" src="https://sam-solutions.com/wp-content/uploads/Snippet-Rendering-min.png" alt="Snippet Rendering" class="wp-image-6450"/></figure>
</div>


<p class="wp-block-paragraph">As for the DataSource, create a <b>Snippet Item template</b> inherited from:</p>



<p class="wp-block-paragraph">* <b>Base App Route</b> template (Path: /sitecore/templates/Foundation/JSS Experience Accelerator/Multisite/Base App Route)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="885" height="104" src="https://sam-solutions.com/wp-content/uploads/Base-App-Route-Template-min.png" alt="Base App Route Template" class="wp-image-6452"/></figure>
</div>


<p class="wp-block-paragraph">* <b>Global Datasource Behavior</b> template (Path: /sitecore/templates/Foundation/Experience Accelerator/Local Datasources/Global Datasource Behavior)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="955" height="109" src="https://sam-solutions.com/wp-content/uploads/Global-DS-Template-min.png" alt="Global DS Template" class="wp-image-6454"/></figure>
</div>


<p class="wp-block-paragraph">In the created Snippet rendering, put a data source link referenced to the <b>Snippet Item template.</b></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1112" height="291" src="https://sam-solutions.com/wp-content/uploads/Snippet-DS-Locations-1-min.png" alt="Snippet DS Locations-1" class="wp-image-6456"/></figure>
</div>


<p class="wp-block-paragraph">Then, create a Snippet JSS Component with a placeholder:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
import React from &#039;react&#039;;
import { isExperienceEditorActive, Placeholder, Image } from &#039;@sitecore-jss/sitecore-jss-react&#039;;

const SnippetComponent = (props) =&gt; {

  if (!props.fields) {

      return &lt;h1 className=&quot;alarm&quot;&gt;Datasource isn&#039;t set.&lt;h1&gt;;
    }
    return (
      &lt;h1 className=&quot;alarm&quot;&gt;
        Data is not provided. Contact administrators, please.
      &lt;/h1&gt;
    );
  }

 return(
     &lt;&gt;
        &lt;Placeholder name=&quot;snippet-content&quot; rendering={props.rendering} /&gt;
      &lt;/&gt;
);
}
export default SnippetComponent;
</pre></div>


<p class="wp-block-paragraph">2. Create an additional Layout that will allow you to configure the Snippet data source separately.</p>



<p class="wp-block-paragraph">In Sitecore, create a new JSS Snippet Layout (just a copy of the existing one) with only one placeholder (in my case <b>snippet-content</b>):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1337" height="379" src="https://sam-solutions.com/wp-content/uploads/Snippet-Layout-min.png" alt="Snippet Layout" class="wp-image-6458"/></figure>
</div>


<p class="wp-block-paragraph">In JSS, add the following piece of code to the Layout.js file:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
import React from &#039;react&#039;;
import { Placeholder, VisitorIdentification,withSitecoreContext } from &#039;@sitecore-jss/sitecore-jss-react&#039;;
import Helmet from &#039;react-helmet&#039;;

import &#039;./assets/app.css&#039;;

const Layout = ({ route, context }) =&gt; {

return (&lt;React.Fragment&gt;
&lt;Helmet&gt;
&lt;title&gt;
{(route.fields route.fields&#x5B;&quot;Page Title&quot;] route.fields&#x5B;&quot;Page Title&quot;].value) || route.displayName }
&lt;/title&gt;
&lt;/Helmet&gt;

&lt;VisitorIdentification /&gt;

&lt;Placeholder name=&quot;jss-top&quot; rendering={route} /&gt;
&lt;section className=&quot;site-wrapper&quot;&gt;
&lt;Placeholder name=&quot;jss-main&quot; rendering={route} /&gt;
&lt;/section&gt;
&lt;Placeholder name=&quot;jss-footer&quot; rendering={route} /&gt;

{context.pageEditing &lt;Placeholder name=&quot;snippet-content&quot; rendering={route} /&gt;}

&lt;/React.Fragment&gt;
)};

export default Layout;
</pre></div>


<p class="wp-block-paragraph">In step 1, we created the <b>Snippet Item</b> inherited from the Base App Route JSS Experience Accelerator template. It means we can use this item as a content page. Make sure the <b>Snippet Item</b> is referenced now to the <b>Snippet Layout</b> we created above.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="569" height="213" src="https://sam-solutions.com/wp-content/uploads/Snippet-Layout-Reference-min.png" alt="Snippet Layout Reference" class="wp-image-6460"/></figure>
</div>


<p class="wp-block-paragraph">3. Find the demonstration below in the <b>How To Use</b> section.</p>



<p class="wp-block-paragraph">4. After some investigations, I found out that the main entry point where it is possible to inject our custom code is the Render virtual method in LayoutService class (implementation of the ILayoutService Interface, <i>Sitecore.LayoutService.dll</i>).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="755" height="618" src="https://sam-solutions.com/wp-content/uploads/Sitecore-Layout-Service-min.png" alt="Sitecore Layout Service" class="wp-image-6462"/></figure>
</div>


<p class="wp-block-paragraph">So, to achieve our goal, we need to develop a custom Layout Service inherited from default Sitecore LayoutService and override the <b>Render</b> method to add a logic to find and render Snippets with its data source added on a page:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
public class CustomLayoutService : LayoutService
{
public CustomLayoutService(
IPlaceholderRenderingService placeholderService,
ILayoutServiceContext serviceContext) : base(placeholderService, serviceContext)
{
}

public override RenderedItem Render(
Item item,
IRenderingConfiguration renderingConfiguration,
RenderOptions renderOptions = null)
{
return CustomRenderedItem(item, renderingConfiguration, renderOptions: renderOptions);
}
</pre></div>


<p class="wp-block-paragraph">You can find the <strong>CustomRenderedItem</strong> method implementation <a href="https://github.com/VadzimPapko/Sitecore.Extensions.JSS.Snippet/blob/main/JssSnippet/Services/CustomLayoutService.cs" target="_blank" rel="nofollow noopener noreferrer">here</a>.<br>To inject the <strong>CustomLayoutService</strong> instead of the default one, we need to register the following dependencies:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
public class RegisterDependencies : IServicesConfigurator
{
public void Configure(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton &lt;IConfiguration, Configuration&gt;();
serviceCollection.AddSingleton &lt;IFieldRenderer, FieldRenderer&gt;();
serviceCollection.AddSingleton &lt;ISerializerService, SerializerService&gt;();
serviceCollection.AddSingleton &lt;IRenderJsonRenderingPipeline, RenderJsonRenderingPipeline&gt;();
serviceCollection.AddSingleton &lt;IGetFieldSerializerPipeline, GetFieldSerializerPipeline&gt;();
serviceCollection.AddSingleton &lt;IPlaceholderRenderingService, PlaceholderRenderingService&gt;();
serviceCollection.AddSingleton &lt;ILayoutServiceContext, PipelineLayoutServiceContext&gt;();
serviceCollection.AddSingleton &lt;IGetLayoutServiceContextPipeline, GetLayoutServiceContextPipeline&gt;();
serviceCollection.AddSingleton &lt;ILayoutService, CustomLayoutService&gt;();
}
}
</pre></div>


<p class="wp-block-paragraph">and apply the following patch:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
&lt;configuration xmlns:patch=&quot;http://www.sitecore.net/xmlconfig/&quot; xmlns:role=&quot;http://www.sitecore.net/xmlconfig/role/&quot;&gt;
        &lt;sitecore&gt;
                &lt;services&gt;
                        &lt;configurator type=&quot;Sitecore.LayoutService.RegisterDependencies, Sitecore.LayoutService&quot;&gt;
                                &lt;patch:attribute name=&quot;type&quot;&gt;JssSnippet.Configurators.RegisterDependencies, JssSnippet&lt;/patch:attribute&gt;
                        &lt;/configurator&gt;
                &lt;/services&gt;
        &lt;/sitecore&gt;
&lt;/configuration&gt;
</pre></div>


<h2 class="wp-block-heading">How To Use</h2>



<ol class="wp-block-list">
<li>Create a Snippet item under Data folder of your SXA JSS Site (<b><i>/sitecore/content/[JSS Tenant]/[JSS Site]/Data/Snippets/Demo/Snippet</i></b>):</li>
</ol>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="198" height="84" src="https://sam-solutions.com/wp-content/uploads/Snippet-Item-min.png" alt="Snippet Item" class="wp-image-6464"/></figure>
</div>


<p class="wp-block-paragraph">2. Open created Snippet Item in Experience Editor to add microcomponents there:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="856" height="283" src="https://sam-solutions.com/wp-content/uploads/Empty-Snippet-Exp-Editor-min.png" alt="Empty Snippet Exp Editor" class="wp-image-6466"/></figure>
</div>


<p class="wp-block-paragraph">3. Add JSS Components you would like to use as a snippet then. For instance, in my case, I am going to add the Section component, then Grid component, then Column component (2), then Image component (left column), then RTE component (right column):</p>



<p class="wp-block-paragraph">Section:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1004" height="365" src="https://sam-solutions.com/wp-content/uploads/Section-min.png" alt="Section" class="wp-image-6468"/></figure>
</div>


<p class="wp-block-paragraph">Grid with two Columns:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1001" height="385" src="https://sam-solutions.com/wp-content/uploads/Grid-min.png" alt="Grid" class="wp-image-6470"/></figure>
</div>


<p class="wp-block-paragraph">The image in the Left Column:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="997" height="488" src="https://sam-solutions.com/wp-content/uploads/Image-min.png" alt="Snippet-2" class="wp-image-6472"/></figure>
</div>


<p class="wp-block-paragraph">Rich Text in the Right Column:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1075" height="487" src="https://sam-solutions.com/wp-content/uploads/Rich-Text-min.png" alt="Sitecore Containers" class="wp-image-6474"/></figure>
</div>


<p class="wp-block-paragraph">Ok, now we have our Snippet data source with components inside:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="343" height="268" src="https://sam-solutions.com/wp-content/uploads/Snippet-Item-Full-min.png" alt="Snippet Item Full" class="wp-image-6476"/></figure>
</div>


<p class="wp-block-paragraph">4. Now, it is time to add the Snippet to a site page. Open a content page in Experience Editor and add the Snippet Component in any placeholder you need:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="880" height="709" src="https://sam-solutions.com/wp-content/uploads/Add-Snippet-min.png" alt="Add Snippet" class="wp-image-6478"/></figure>
</div>


<p class="wp-block-paragraph">And here is the result — we’ve got a Snippet component with Microcomponents inside.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1178" height="828" src="https://sam-solutions.com/wp-content/uploads/Snippet-On-Psge-min.png" alt="Snippet On Page" class="wp-image-6480"/></figure>
</div>


<p class="wp-block-paragraph">5. Let’s put the same snippet on the Top placeholder on the same page.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1034" height="735" src="https://sam-solutions.com/wp-content/uploads/Snippet-on-top-placeholder-min.png" alt="Snippet on top placeholder" class="wp-image-6482"/></figure>
</div>


<p class="wp-block-paragraph">And now we have a reusable feature — two Snippets on the page.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1170" height="808" src="https://sam-solutions.com/wp-content/uploads/Two-Snippets-min.png" alt="Two Snippets" class="wp-image-6484"/></figure>
</div>


<p class="wp-block-paragraph">Let’s check the presentation details for this page.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1271" height="929" src="https://sam-solutions.com/wp-content/uploads/Presentation-Details-min.png" alt="Presentation Details" class="wp-image-6486"/></figure>
</div>


<p class="wp-block-paragraph">6. There is also one feature in the SXA’s Snippet, such as <a href="https://doc.sitecore.com/users/sxa/19/sitecore-experience-accelerator/en/configure-a-snippet.html" target="_blank" rel="nofollow noopener noreferrer">Global Data Source Behavior</a>. Our custom Snippet item also has this approach (inherited from the SXA template — /sitecore/templates/Foundation/Experience Accelerator/Local Datasources/<b>Global Datasource Behavior</b>)</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="1366" height="275" src="https://sam-solutions.com/wp-content/uploads/DataSource-Behavior-min.png" alt="DataSource Behavior" class="wp-image-6488"/></figure>
</div>


<p class="wp-block-paragraph">7. Probably, you have the following questions:<br>* Is it possible to Edit components that are inside the snippet directly on a content page? — Yes, it is.<br>* Is it possible to Put another snippet to an already created one? — Yes, it is. As of now, there is only one restriction — you are not able to put the same Snippet inside.<br>* Do the Sitecore Personalization Rules work with Snippets? — Yes, they do.<br>* Can I contribute to it? — Sure, just make a fork and help me improve it.</p>



<p class="wp-block-paragraph">That’s all for today. You can <a href="https://github.com/VadzimPapko/Sitecore.Extensions.JSS.Snippet" target="_blank" rel="nofollow noopener noreferrer">find the implementation in my GitHub.</a></p>



<p class="wp-block-paragraph">Feel free to contribute.</p>



<p class="wp-block-paragraph">Happy coding, Sitecorians!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sam-solutions.com/blog/sitecore-jss-sxa-how-to-build-custom-snippet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
