<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Brian McKeiver</title>
    <description>The latest articles on Forem by Brian McKeiver (@mcbeev).</description>
    <link>https://forem.com/mcbeev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F328905%2F2db3f3da-8f7c-4e10-b3b2-a813c09140bd.png</url>
      <title>Forem: Brian McKeiver</title>
      <link>https://forem.com/mcbeev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mcbeev"/>
    <language>en</language>
    <item>
      <title>How to Migrate from .NET MVC 5 to .NET Core for Kentico Xperience</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sun, 29 Aug 2021 19:21:58 +0000</pubDate>
      <link>https://forem.com/bizstream/how-to-migrate-from-net-mvc-5-to-net-core-for-kentico-xperience-506d</link>
      <guid>https://forem.com/bizstream/how-to-migrate-from-net-mvc-5-to-net-core-for-kentico-xperience-506d</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;.NET Core and .NET 5 have been available for some time now and .NET 6 will be released any month now. However, the majority of existing Kentico MVC sites previous to version 13 were created in .NET MVC 5. This situation is especially true for Kentico 11 and Kentico 12 MVC versions as those previous versions weren't yet ready for and basically incompatible with .NET Core.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Leverage .NET 5 (and .NET 6)
&lt;/h3&gt;

&lt;p&gt;ASP.NET MVC Core along with .NET 5 presents a compelling case for almost every .NET based application today. It could be perceived as a small jump in version numbers from 4.x to 5 if one is not familiar with the situation Microsoft has put us in, but .NET 5 is a major (and I do truly mean &lt;strong&gt;major&lt;/strong&gt;) leap from the .NET 4.x framework that &lt;a href="http://xperience.io/"&gt;Kentico Xperience&lt;/a&gt; had traditionally run on. .NET 5 is a continuation of completely rebuilt and all-new framework that started with .NET Core 1.0 (released back in 2016) through .NET Core 3.1 and is now the future for all .NET development. Let me say this again, the .NET 4.7 or .NET 4.8 framework that developers were very familiar with no longer is even used in .NET 5 (and future versions).&lt;/p&gt;

&lt;p&gt;I'm using .NET 5 and .NET 6 pretty interchangeably here because .NET 5 is current production ready target framework at time of writing this article. However, .NET 6 is set to release November 9th, 2021, which is almost around the corner. As soon as November 10th hits you would want to target .NET 6.&lt;/p&gt;

&lt;p&gt;May key benefits of migrating to .NET 5 / .NET 6 for Kentico Xperience (and all .NET apps):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Built for performance, and getting faster with every release&lt;/li&gt;
&lt;li&gt;  Hot reload capability that is coming in .NET 6 (think enhanced developer productivity)&lt;/li&gt;
&lt;li&gt;  It is the current framework that is being actively developed with regular performance, feature, and security updates&lt;/li&gt;
&lt;li&gt;  Using the current framework will mean that future upgrades to .NET 6, 7, and onward will be much easier as far as upgrades go (think simple Nuget package update)&lt;/li&gt;
&lt;li&gt;  Build and run cross-platform (yes, you no longer absolutely need a windows PC and Visual Studio to work with Kentico Xperience)&lt;/li&gt;
&lt;li&gt;  Blazor updates / improved capabilities (Blazor let's you build interactive web UIs using C# instead of JavaScript)&lt;/li&gt;
&lt;li&gt;  Optimized project files for faster load and build times&lt;/li&gt;
&lt;li&gt;  Cloud-ready (of course we are talking Azure PaaS here as the best practice)&lt;/li&gt;
&lt;li&gt;  Open source on GitHub&lt;/li&gt;
&lt;li&gt;  Support for minimal APIs&lt;/li&gt;
&lt;li&gt;  Command Line Interface (CLI) for general use and scripting tasks&lt;/li&gt;
&lt;li&gt;  Attract and retain developers who want to work with the latest technologies&lt;/li&gt;
&lt;li&gt;  Additional years of LTS (long term support) when using .NET 6&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on the size of your application, or complexity of your Kentico installation, this may be a larger undertaking. I'm here to tell you that the benefits far out way the effort. The greater potential for performance improvements than any prior .NET Framework upgrade combined with the fact that all future versions of Kentico will only support .NET 5 / 6, and you have your answer why I feel this way.&lt;/p&gt;

&lt;p&gt;Luckily my team and I at &lt;a href="http://www.bizstream.com"&gt;BizStream&lt;/a&gt; have worked through a few different real world client projects to make this migration a reality this year. As a result, I'd like to share the general way we have went about migrating Kentico MVC 5 to Kentico .NET Core / .NET 5.&lt;/p&gt;

&lt;p&gt;Every project has its own unique customizations and dependencies, so your migration process may be slightly different and require additional steps, but the general process for .NET 5 / .NET 6 migrations follow these steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Kentico Xperience Upgrade
&lt;/h3&gt;

&lt;p&gt;As I mentioned above, the only version of Kentico Xperience that supports .NET Core / .NET 5 / .NET 6 is &lt;a href="http://xperience.io/"&gt;Kentico Xperience 13&lt;/a&gt;. I've talked multiple times about &lt;a href="https://dev.to/why-a-kentico-mvc-upgrade-should-not-be-one-hour-of-work"&gt;Kentico upgrades&lt;/a&gt; before, so I am going to skip the details for this post. It is assumed that you have completed the upgrade to 13 with your Kentico admin tool, or you are starting out at Kentico 13.&lt;/p&gt;

&lt;p&gt;I will say it again to be clear, you MUST be on Kentico Xperience 13 or higher to continue on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: MVC Live Site Migration from MVC 5 to .NET 5 / 6
&lt;/h3&gt;

&lt;p&gt;The real meat of your migration is here. All of the steps below are related to your MVC Live site project and NOT the Kentico CMSApp project. Kentico's official documentation does have very helpful steps for how to handle the very specific Kentico Xperience parts of the &lt;a href="https://docs.xperience.io/developing-websites/developing-xperience-applications-using-asp-net-core/starting-with-asp-net-core-development/migrating-asp-net-mvc-5-projects-to-asp-net-core"&gt;migration of Xperience from MVC 5 to .NET 5&lt;/a&gt;, but I don't feel that it has enough "big picture" to the process (hence my motivation to write this post). &lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Check Out .NET Portability Analyzer
&lt;/h4&gt;

&lt;p&gt;The offical Microsoft documentation says the first step in the migration is to analyze your current application to determine the amount of effort to expect when migrating to .NET 5. The &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/analyzers/portability-analyzer"&gt;.NET Portability Analyzer&lt;/a&gt; is a free tool that will analyze your assemblies and provide you with a report of APIs in your current application that are no longer supported. Sometimes there is a path forward for code that uses APIs that are no longer supported, but other changes require additional effort and a new approach. &lt;/p&gt;

&lt;p&gt;Grab the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ConnieYau.NETPortabilityAnalyzer"&gt;Visual Studio extension to get started with the .NET Portability Analyzer&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Inspect Project Dependencies
&lt;/h4&gt;

&lt;p&gt;Evaluate dependencies between projects and determine whether to upgrade library classes to .NET Standard or .NET 5. If all projects are being upgraded to .NET 5, then all projects can target .NET 5. In the Kentico Xperience world, that option should boil down to .NET Standard 2.0. Really in all cases where you need to leave a project in .NET Framework, and that project needs to reference an upgraded class project, you will need to target .NET Standard 2.0 instead of .NET 5. Think of the CMSApp project that represents the Kentico Admin tool (it is in .NET framework 4.x and you will most likely need to share code between those projects for thinks like custom external media storage modules). If you are not sure, you can also lookup the &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support"&gt;.NET Standard implementation support&lt;/a&gt; page to determine what versions of .NET and .NET Standard are compatible with each other.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Convert Class Libraries
&lt;/h4&gt;

&lt;p&gt;Class libraries (your helpers, extensions, custom scheduled tasks, reusable components, etc. etc.) are typically the easiest project types to convert.  If they do not have any compatibility warnings in Step 1, it is very likely that you will be able to simply migrate all of the existing code to the new project structure. Before you start converting projects, ensure that you have the desired version of the &lt;a href="https://dotnet.microsoft.com/download"&gt;.NET SDK&lt;/a&gt; installed on your local machine.&lt;/p&gt;

&lt;p&gt;When you are ready to migrate your projects, you can start with the &lt;a href="https://github.com/dotnet/try-convert"&gt;Try Convert&lt;/a&gt; tool to see if your entire solution or individual projects can be migrated automatically. If that does not succeed (and it most likely will not), or if you want to convert them manually to have more control over the process, you can take the following approach. I do recommend the manual process. Common steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create a new Class Library project in either the same folder (with a new project name) a parallel folder (with the same project name) using either Visual Studio (Add &amp;gt; New Project &amp;gt; Class Library), or with the CLI command &lt;strong&gt;&lt;code&gt;dotnet new classlib -o &amp;lt;ProjectName&amp;gt;&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; If using the same project name, replace the old csproj class file with the new csproj file that was just created&lt;/li&gt;
&lt;li&gt; Manage Nuget packages for the new project and add any missing packages that your code requires. You can also right-click on the packages.config file in Visual Studio and select “Migrate packages.config to PackageReference.”&lt;/li&gt;
&lt;li&gt; Delete files and folders that may no longer be needed such as the Properties folder and the packages.config file (now that your Nuget packages are now managed in the csproj file)&lt;/li&gt;
&lt;li&gt; Build the project and resolve any missing references or errors&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 4: Convert ASP.NET Projects (The Hardest Part)
&lt;/h4&gt;

&lt;p&gt;There have been a lot of changes to how .NET Core and .NET 5 initialize and run ASP.NET MVC projects, this step tends to be more involved than migrating class libraries.&lt;/p&gt;

&lt;p&gt;In theory just like Step 3, you may be able to automatically convert your entire solution or the ASP.NET projects with the &lt;a href="https://github.com/dotnet/try-convert"&gt;Try Convert&lt;/a&gt; tool. In my experience, it will not succeed on a complex project like a traditional Kentico Xperience project. You will most likely have to perform the conversion manually, you can follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create a new ASP.NET Core Web App or an ASP.NET Core Empty project (&lt;a href="https://stackoverflow.com/questions/4264320/difference-between-asp-net-web-app-and-asp-net-mvc-3-empty-web-app"&gt;differences of the .NET templates here&lt;/a&gt;). Select “.NET 5” for your Target Framework.&lt;/li&gt;
&lt;li&gt; Review your original project's startup code in Global.asax.cs. Any custom logic will need to be migrated to the new Startup.cs class in .NET 5.&lt;/li&gt;
&lt;li&gt; Add in / update the the Kentico Xperience libraries to 13 (follow &lt;a href="https://docs.xperience.io/developing-websites/developing-xperience-applications-using-asp-net-core"&gt;Developing Kentico Xperience projects with .NET Core&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt; Add in your custom Nuget packages from your previous site and resolve any Nuget or reference errors. You will likely need to adjust your &lt;code&gt;using&lt;/code&gt; statements to account for changed namespaces in .NET 5.&lt;/li&gt;
&lt;li&gt; Copy or move all of your existing controllers and classes into the new project structure&lt;/li&gt;
&lt;li&gt; Update existing controller classes to derive from Microsoft.AspNetCore.Mvc.ControllerBase. You will want to create your own ControllerBase class that derives from ControllerBase and is decorated with the [Controller] attribute. Controllers that need to provide MVC View support can derive from Microsoft.AspNetCore.Mvc.Controller.&lt;/li&gt;
&lt;li&gt; This is where the official steps come in handy from &lt;a href="https://docs.xperience.io/developing-websites/developing-xperience-applications-using-asp-net-core/starting-with-asp-net-core-development/migrating-asp-net-mvc-5-projects-to-asp-net-core"&gt;Kentico documentation on migration to MVC Core&lt;/a&gt;. Some or all of those steps apply here.&lt;/li&gt;
&lt;li&gt; Migrate any custom (non Kentico) Handlers to use .NET Middleware instead&lt;/li&gt;
&lt;li&gt; Migrate web.config settings to appsettings.json (not every one of them!)&lt;/li&gt;
&lt;li&gt;  Again, make sure to follow the docs from Kentico on &lt;a href="https://docs.xperience.io/developing-websites/developing-xperience-applications-using-asp-net-core"&gt;Developing Kentico Xperience projects with .NET Core&lt;/a&gt; and heavily review the &lt;a href="https://docs.xperience.io/developing-websites/developing-xperience-applications-using-asp-net-core/starting-with-asp-net-core-development/migrating-asp-net-mvc-5-projects-to-asp-net-core"&gt;Kentico docs on migration to MVC Core&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 5: Review Dependency Injection
&lt;/h4&gt;

&lt;p&gt;If you are already using Dependency Injection, you can likely continue to use the same DI framework. If you are not using DI at all, the migration to .NET 5 provides the perfect opportunity to start using the built-in &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection"&gt;Dependency Injection framework&lt;/a&gt;. Even if you are using a different DI framework, it may be worth considering making the switch to .NET Dependency Injection because of its &lt;a href="https://github.com/danielpalme/IocPerformance"&gt;excellent performance&lt;/a&gt;, and since it is a first-class citizen in .NET, it is very easy to adopt and use. I'm a big fan of using the built in DI framework in .NET Core.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 6: Migrate to System.Text.Json (optional)
&lt;/h4&gt;

&lt;p&gt;Similar to DI, the migration to System.Text.Json for serialization and deserialization is an optional migration. If you are using Newtonsoft.Json currently, there won’t be complete feature parity in System.Text.Json, so it is worth &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to?pivots=dotnet-5-0"&gt;reviewing the differences outlined here&lt;/a&gt;. But if System.Text.Json does provide all of the features you need, it is likely that you will see performance improvements by making the switch.&lt;/p&gt;

&lt;p&gt;Also important, do not perform this step on the Kentico CMSApp project. Newtonsoft is still required there. Here are typical steps for migrating to System.Text.Json:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Remove Nuget references to Newtonsoft.Json in your project(s)&lt;/li&gt;
&lt;li&gt; Build your solution and you should get build errors for everything that was using Newtonsoft&lt;/li&gt;
&lt;li&gt; Update using statements, typically removing Newtonsoft.Json and replacing with System.Text.Json&lt;/li&gt;
&lt;li&gt; Update serialization/deserialization syntax: SerializeObject() becomes JsonSerializer.Serialize() and DeserializeObject() becomes JsonSerializer.Deserialize()&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 7: Migrate Forms to the new Form Builder (optional)
&lt;/h4&gt;

&lt;p&gt;You may or may not have to do this step. But if you had older Forms (built in Kentico 12 or earlier), you will need to change to the way that Kentico Xperience 13 handles forms. The best place to start is the documentation here on &lt;a href="https://docs.xperience.io/developing-websites/form-builder-development"&gt;Form builder development&lt;/a&gt;. You may have run into issues with the upgrade from 12 to 13 around this area. I know we sure did. We actually had to delete the forms out of the system to make the upgrade work. At a high level, you will most likely need to rebuild your forms in 13. There are some crazy workarounds possible, but that would be a whole different blog post to tell that story. If your forms are built in Xperience 13 using Form builder from the start you can ignore this step.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 8: Treat it like an Upgrade (optional)
&lt;/h4&gt;

&lt;p&gt;This is an optional step as well, but you most likely will want to review / rebuild / re-test anything and everything that is on the MVC live site from a Kentico standpoint. That means, heavily inspect your event log as you browse through the site to watch for errors, rebuild your search indexes, clean / restart your web farm servers, and ensure that files are being delivered correctly when adding a new image in the Kentico media library. &lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Making the move from .NET Framework 4.x to the latest .NET platform can be a large effort, but it certainly has its benefits. Along with the immediate performance gains, you will once again be on the current .NET platform that will continue to improve over time. I know not everyone wants to go through a large upgrade to effort, especially since you may also need to go through a Kentico Portal Engine to Kentico MVC conversion as well, but it's 2021 people, which means .NET Core / .NET 5 / .NET 6 have been out for over 5 years now. There's no reason not to use it.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>aspdotnet</category>
      <category>dotnetcore</category>
      <category>kenticoxperience</category>
    </item>
    <item>
      <title>Making Azure Cognitive Search Work Better with Kentico Xperience</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Mon, 31 May 2021 19:48:07 +0000</pubDate>
      <link>https://forem.com/bizstream/making-azure-cognitive-search-work-better-with-kentico-xperience-1763</link>
      <guid>https://forem.com/bizstream/making-azure-cognitive-search-work-better-with-kentico-xperience-1763</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Almost nothing is more frustrating than when a developer or marketer receives feedback that their website search experience is broken. Hearing the words “When I search for this term, the wrong results are returned, or [worse yet] no results are returned at all”. I know it sure pains me to hear this.&lt;/p&gt;

&lt;p&gt;Ultimately there are lots of possibilities that could cause a faulty search. Some issues tend to be more severe, but some issues also tend to be just small nuances. It can come down to how content is written, how content is indexed, and/or how calling the search service is performed through code.&lt;/p&gt;

&lt;p&gt;This article contains a few tips and tricks to make the native integration between Kentico Xperience and Azure Cognitive Search work better than the out of the box configuration. Following one or more them may finally help you hear “Wow, search is working great on the site”.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Setup
&lt;/h3&gt;

&lt;p&gt;I am going to assume that your &lt;a href="https://xperience.io/"&gt;&lt;strong&gt;Kentico Xperience&lt;/strong&gt;&lt;/a&gt; instance is setup correctly to use Smart Search with the Azure indexes as a baseline for this post. If you don’t already have that setup, you can check out the Xperience documentation for &lt;a href="https://docs.xperience.io/configuring-xperience/setting-up-search-on-your-website/using-azure-cognitive-search"&gt;Using Azure Cognitive Search&lt;/a&gt; to configure your Smart Search indexes. Again, this post is for making the experience better for your end users as well as a few quick tips for working with the indexes themselves as a Kentico developer.&lt;/p&gt;

&lt;p&gt;Also, if you are not sure about using Azure Cognitive Search with Kentico, did you know that you can easily try it out without spending any money? AND without having to write any code? Yes, you read that correct. There is basically no barrier to giving it a shot. To get started for free, you can use any subscription that you have with Azure, or you can &lt;a href="https://docs.microsoft.com/en-us/azure/cost-management-billing/manage/create-subscription"&gt;create yourself a new Azure subscription&lt;/a&gt; in a matter of minutes. Simply log into that subscription and &lt;a href="https://docs.microsoft.com/en-us/azure/search/search-create-service-portal"&gt;create a Azure Cognitive Search service resource&lt;/a&gt; using the free tier. That's right everything from the Kentico side will work with that free tier from a prototype standpoint. Once you have that resource created, you can also generate a complete working UI for performing a search on your CMS data (I will show that in a second later on in this post).&lt;/p&gt;

&lt;p&gt;Let's start tackling a few items that we tend to run into when using Azure Cognitive Search with Kentico Xperience. The following items are meant to be quick tips that make working with Azure Search better in Kentico Xperience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Are there So Many Fields in my Azure Search Index by Default?
&lt;/h3&gt;

&lt;p&gt;This was one of the very first things I noticed when starting my learning journey with Kentico and Azure Search. Even with only one Page Type configured to be searchable by the Azure Search index, I had what seemed like hundreds of fields added into my index by default. The default result looks like this in JSON:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZgjX7NbZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/23b381e6-e72c-4c58-8c04-204ee8ca456e/Azure-Cognitive-Search-Index-Fields-Kentico-JSON.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZgjX7NbZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/23b381e6-e72c-4c58-8c04-204ee8ca456e/Azure-Cognitive-Search-Index-Fields-Kentico-JSON.png" alt="Azure Cognitive Search Kentico Xperience Index JSON" title="Azure Cognitive Search Kentico Xperience Index JSON"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My immediate thought was well, that seems like overkill. I also happen to know that Azure Cognitive Search (and almost every other search service out there) has a limit on the number of fields per index. If you need to have a whole ton of content searched, chances are you have multiple Page Types with multiple fields that you want to include in that search. One quick way to make sure you don't hit that limit on the number of fields per index is to control what fields are searchable and which fields are not. Luckily Kentico Xperience has a great automatic way of doing this. The only problem is that it is not really straightforward on how to eliminate the "base" fields of the index that are not part of your custom Page Type.&lt;/p&gt;

&lt;p&gt;The key here is to understand that everything in Xperience at the end of the day is a Document / TreeNode when it comes to Pages. That means that the base class or ClassDefinition in the database, if you want to get technical, includes all of the base fields of the CMS. Even if you only have these few fields available to you in your Search configuration of the Page Type. Below is such an example of my Article Page Type for Mcbeev.com. It doesn't really have that many fields.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MXJ6llov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/8b4f9aa9-66f4-41e1-8dbc-17783847c7c9/Kentico-Xperience-Page-Type-Search-Fields.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MXJ6llov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/8b4f9aa9-66f4-41e1-8dbc-17783847c7c9/Kentico-Xperience-Page-Type-Search-Fields.png" alt="Kentico Xperience Page Type Search Fields" title="Kentico Xperience Page Type Search Fields"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means that the default fields have to come from somewhere else right? They do. The quick tip here is that you can configure the Search fields of the base Document object in the Modules application. Navigate to the following place:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Navigate to &lt;strong&gt;Modules&lt;/strong&gt; in the menu -&amp;gt; click edit on the &lt;strong&gt;Pages&lt;/strong&gt; module -&amp;gt; click &lt;strong&gt;Classes&lt;/strong&gt; vertical tab-&amp;gt; click edit on the &lt;strong&gt;Pages class&lt;/strong&gt; -&amp;gt; click on &lt;strong&gt;Search&lt;/strong&gt; vertical tab.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--op1-kU3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/bcdcdff1-54bb-40c6-86a3-f484423fde74/Kentico-Xperience-Page-Type-Search-Fields-Default.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--op1-kU3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/bcdcdff1-54bb-40c6-86a3-f484423fde74/Kentico-Xperience-Page-Type-Search-Fields-Default.png" alt="Kentico Xperience Page Type Search Fields Default" title="Kentico Xperience Page Type Search Fields Default"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see above that many of the fields, in fact all of them that you most likely see in your JSON results are marked as &lt;strong&gt;Retrievable or Content&lt;/strong&gt;. This is the reason they are included in the indexing process and in the Search Results document. The fix here is to simply uncheck them (yes, you do have to click the customize button first on this class). This is a safe operation, and it will cut down on the fields that are passed into the index. It will also most likely speed up the indexing process itself as well. The unchecked version looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A8xWDx7n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/679616f6-b753-4b08-ab0c-a8420f409b95/Kentico-Xperience-Page-Type-Search-Fields-UnChecked.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A8xWDx7n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/679616f6-b753-4b08-ab0c-a8420f409b95/Kentico-Xperience-Page-Type-Search-Fields-UnChecked.png" alt="Kentico Xperience Page Type Search Fields UnChecked" title="Kentico Xperience Page Type Search Fields UnChecked"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go ahead and rebuild your index all the way, and you won't see these fields as part of the index nor will they be in the results muddying up your Search Documents JSON. It will also save you on the index size and keep you from hitting that field limit of the index.&lt;/p&gt;

&lt;h3&gt;
  
  
  When I Search for Part of a Word Instead of the Whole Word Nothing is Returned?
&lt;/h3&gt;

&lt;p&gt;This is a fun one. And really this question was the inspiration for this blog post. As it turns out most people expect to receive results from a search engine when typing in part of a word or phrase. Logically that makes sense to us all, as we have all been using Google, Amazon, Bing, and Yahoo for years now. Partial word matching is just something that these popular search engines do. People expect it to "just" work like that. Well you have some options here.&lt;/p&gt;

&lt;p&gt;By default when you perform a search through Kentico Xperience's implementation of the Azure Search SDK you are using a &lt;strong&gt;SearchServiceClient&lt;/strong&gt; instance and passing in a &lt;strong&gt;SearchString&lt;/strong&gt; (the query term the user is using itself) and the &lt;strong&gt;SearchParameters&lt;/strong&gt; object like so:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;var result = await searchIndexClient.Documents.SearchAsync(searchString, searchParams);&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The thing to try is of course the wildcard character in this simple mode of searching. By appending a '*' character you can get more of a wildcard behavior to work, but it is often too aggressive and does not work in all scenarios (especially if you are trying to search just one specific field or in combinations with Filters and Facets. I'll come back to the wildcard character at the end of this section (bear with me).&lt;/p&gt;

&lt;p&gt;As we go deeper to solve the problem, all of the documentation focuses on setting the Facets, FilterText, or Highlights fields on that object, which is well and good, but they don't mention the &lt;strong&gt;queryType&lt;/strong&gt; that much. The queryType parameter defaults to &lt;strong&gt;simple&lt;/strong&gt; (which is good for general full text search). However, that is not good for when you want to do partial matching or fuzzy matching on the user's search term. Let's run through some examples that illustrate my point. &lt;/p&gt;

&lt;p&gt;If you do not specify queryType and only perform a normal search with just a searchString value, that is the same thing as calling the direct REST endpoint for your Azure Search service. If you are searching for a whole word it works great by default. It looks like this when I search for the term "blazor" across all of my blog post content here on mcbeev.com:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Je7nR-S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/f8a91591-17c2-4572-b94c-3eb101e05fb6/Azure-Cognitive-Search-SearchText.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Je7nR-S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/f8a91591-17c2-4572-b94c-3eb101e05fb6/Azure-Cognitive-Search-SearchText.png" alt="Azure Cognitive Search with SearchText" title="Azure Cognitive Search with SearchText"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since I am specifying the count property set to true, we can see that 7 results come back for the term "blazor" with a queryType of simple. But things fall apart if I change the term to "blaz" or "blazo". 0 results are returned, which is not exactly what we really want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--22sB8W4n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/1e50374f-ed0d-4ba8-880a-c4aaab646b72/Azure-Cognitive-Search-SearchText-Partial-No-Match.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--22sB8W4n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/1e50374f-ed0d-4ba8-880a-c4aaab646b72/Azure-Cognitive-Search-SearchText-Partial-No-Match.png" alt="Azure Cognitive Search SearchText Partial No Match" title="Azure Cognitive Search SearchText Partial No Match"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The way you can get results to return for partial matches in Azure Cognitive Search is to &lt;strong&gt;change the queryType parameter to full&lt;/strong&gt; as the value. This enables you to use the entire &lt;a href="https://docs.microsoft.com/en-us/azure/search/search-query-lucene-examples"&gt;full Lucene query search syntax&lt;/a&gt;. When full mode is turned on you can use &lt;a href="https://docs.microsoft.com/en-us/azure/search/search-query-fuzzy"&gt;Fuzzy search&lt;/a&gt; matching as another option in your search toolbox. Fuzzy search matching is meant to compensate for typos and misspelled terms in the input string. This can be helpful in some scenarios where you are worried about misspelling terms like "blazr" instead of the correct "blazor" spelling. However, Fuzzy search is slower to perform so you want to be a little careful with it. To enable Fuzzy search mode in the Kentico Xperience call, the C# would look like this (basically you just add the '~' character at the end of the string and set the queryType to full:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;var result = await searchIndexClient.Documents.SearchAsync(searchString + "~", new SearchParameters(){ QueryType="full"});&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That C# code again gets translated by the SDK and ends up with this REST call which now returns multiple results for the misspelling of "blazor" and partial matching looks like it is starting to work:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kWnJM144--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/714c9df3-1790-4819-b2cc-a12f53200b24/Azure-Cognitive-Search-SearchText-Partial-Fuzzy-Match.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kWnJM144--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/714c9df3-1790-4819-b2cc-a12f53200b24/Azure-Cognitive-Search-SearchText-Partial-Fuzzy-Match.png" alt="Azure Cognitive Search SearchText Partial Fuzzy Match" title="Azure Cognitive Search SearchText Partial Fuzzy Match"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But hold on, now I actually have 34 matches / results. I know I like Blazor, but I also know I have not written that much about it. I'm getting too many matches now. That's because basically the Fuzzy match is too Fuzzy for my needs. There are too many other words that match to be useful. That's why we don't normally end up using Fuzzy.&lt;/p&gt;

&lt;p&gt;The best method to is to actually use a contains syntax in Lucene with full queryType mode. This is a tad bit more complex, but not too bad. You just have to use Regular Expression search matching with Lucene syntax in mind. Which I know sounds very dangerous (unless you are &lt;a href="https://www.bizstream.com/about/team/mark-schmidt"&gt;Mark Schmidt&lt;/a&gt;, who absolutely loves Regular Expressions).  &lt;/p&gt;

&lt;p&gt;To do a Regular Expression search that matches something that contains a partial word we recommend this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;var result = await searchIndexClient.Documents.SearchAsync("/.*" + searchString + "*./", new SearchParameters(){ QueryType="full"});&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This gets me my partial match to "blazo" for anything with a real word of "blazor" in the content. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7MQx0e7i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/7898a6e1-14c1-4206-8ab2-7a559fdab256/Azure-Cognitive-Search-SearchText-Partial-Regex-Match.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7MQx0e7i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/7898a6e1-14c1-4206-8ab2-7a559fdab256/Azure-Cognitive-Search-SearchText-Partial-Regex-Match.png" alt="Azure Cognitive Search SearchText Partial Regex Match" title="Azure Cognitive Search SearchText Partial Regex Match"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With great power comes great responsibility though. This is a slower operation for sure. If you have a very large index you need to be a bit careful when and where you use this, but it does work well in our usage. There are a few other higher end options, but they require moving up to a different analyzer type which is more complex for sure. The important thing here is that you can use this either generally across the entire set of index fields with the searchText property, as well as you can use it on specific fields like values of tags (which could come in handy with dealing with trying to match a category or tag name that a user is searching for). For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MKPjCaF5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/b722a0cf-9b62-4fa7-9a3c-358150609f8b/Azure-Cognitive-Search-SearchText-Partial-Regex-Match-by-field.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MKPjCaF5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/b722a0cf-9b62-4fa7-9a3c-358150609f8b/Azure-Cognitive-Search-SearchText-Partial-Regex-Match-by-field.png" alt="Azure Cognitive Search SearchText Partial Regex Match by field" title="Azure Cognitive Search SearchText Partial Regex Match by field"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Remember the simple wildcard possibility that I started with? If we had just used that, no results would have come back for the above scenario. That's why it doesn't always "just" work. Example of it NOT working:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Si08PVNn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/da9115f1-8631-42ab-b86b-5e9c31b24593/Azure-Cognitive-Search-SearchText-Wildcard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Si08PVNn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/da9115f1-8631-42ab-b86b-5e9c31b24593/Azure-Cognitive-Search-SearchText-Wildcard.png" alt="Azure Cognitive Search Wildcard NOT working" title="Azure Cognitive Search Wildcard NOT working"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the Search Service Away From Your Code
&lt;/h3&gt;

&lt;p&gt;Azure Cognitive Search has one of the best debugging tools available built right into the Azure Portal, the &lt;a href="https://docs.microsoft.com/en-us/azure/search/search-explorer"&gt;&lt;strong&gt;Search Explorer&lt;/strong&gt;&lt;/a&gt;. In fact, that's what I have been using above to do some quick searching and show the examples. If you are ever having an issue with your Kentico site not showing search results for content that you think it should, start with the Search Explorer. We always use this to isolate if the problem has to do with our code on the MVC Core live site, or with the document not even being present in the index itself. I can't recomend the Search Explorer more. There is also a side benefit of using it. It will teach you how to use the REST syntax for querying when it comes to using &amp;amp;$count=true, &amp;amp;$select=, &amp;amp;$filter=, and more. &lt;/p&gt;

&lt;h3&gt;
  
  
  Generate an Automatic UI for the Azure Search Service
&lt;/h3&gt;

&lt;p&gt;Want your own playground to work with results a bit more than what Search Explorer provides? Well you will be a fan of another newer feature from Cognitive services. The automatic scaffolding UI that creates a demo app for you to use on your very own index. Clicking the Create Demo App button inside of the Azure portal generates a React based SPA client that downloads as a ready to go HTML file that has code already hooked up to your service. The Create Demo App process even lets you map which fields should show up as search results in your UI. I was blown away at how easy this was to get things working. Start by clicking the Create Demo App button when viewing one of your indexe details (at the top of the portal). It opens this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BEB1Vs9v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/42700b81-7212-4eaa-b6fb-50a9310adbad/Azure-Cognitive-Search-CreateDemoApp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BEB1Vs9v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/42700b81-7212-4eaa-b6fb-50a9310adbad/Azure-Cognitive-Search-CreateDemoApp.png" alt="Azure Cognitive Search CreateDemoApp" title="Azure Cognitive Search CreateDemoApp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that I've mapped the three preview fields to the right fields of my content in the index. Finishing this gives you a few more options, but ultimately downloads the html file that is your demo. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MW5_d7WG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/80bc3316-9dd7-4878-8cf5-bebb4894507f/Azure-Cognitive-Search-DemoApp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MW5_d7WG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/80bc3316-9dd7-4878-8cf5-bebb4894507f/Azure-Cognitive-Search-DemoApp.png" alt="Azure Cognitive Search DemoApp" title="Azure Cognitive Search DemoApp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By the way to get my thumbnail images to work, I did have to slightly tweak the code sample that downloads to replace the correct image path. If anyone is interested in that just let me know and I'll post it. &lt;/p&gt;

&lt;h3&gt;
  
  
  When Out-of-the-box Fails, Build a Custom Azure Index
&lt;/h3&gt;

&lt;p&gt;One of my fellow Kentico Xperience MVPs, &lt;a href="https://twitter.com/seangwright"&gt;Sean G. Wright&lt;/a&gt; says often that one of his favorite parts of working with Xperience and Azure Search is building custom indexes. I agree with him, this is a place that Kentico Xperience shines with customization. You can create a custom module class in a class library and register it in the CMSApp project to customize what happens with the indexing process of your content. Inside of this custom class you can do things like combine child nodes in the Tree to a parent node and consider them as one single SearchDocument. This is useful when dealing with complex content models that drive large product detail pages. That in itself would be it's own blog post idea, but Im out of time for today. If you are considering this know that it is the most powerful way to craft an index in Kentico. You can check out how to do that via the documentation at &lt;a href="https://docs.xperience.io/configuring-xperience/setting-up-search-on-your-website/using-azure-cognitive-search/customizing-azure-search"&gt;customizing Azure Search for Kentico Xperience websites&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Take It to the Next Level with Semantic Search
&lt;/h3&gt;

&lt;p&gt;Azure Cognitive Search also recently added the abiltiy to perform &lt;a href="https://docs.microsoft.com/en-us/azure/search/semantic-search-overview"&gt;semantic search&lt;/a&gt;, or the ability of the search engine to consider the intent and contextual meaning of search phrases. Semantic is different than the standard way of just analyzing the exact phrasing of a search term. Without semantic search ACS (and local Smart Search) would consider the search phrase "past episodes of Kentico Rocks" as 4 different words [of would be ignored most likely], and present matches that match any of the 4 words indivdually. But with semantic search the search engine has a good chance of returning the results of the Kentico Rocks podcast based on reverse chronological order.&lt;/p&gt;

&lt;p&gt;Now, the out-of-the-box integration with Kentico Xperience can't quite utilize this new feature yet. The queryType of semantic is not yet supported by the Xperience nuget packages, However, you could roll your own queries to your search service if you had this feature available to you. And maybe just maybe the Kentico Xperience product team would consider adding this new feature into a future Refresh of Kentico Xperience, just like they improved the Azure Search integration recently in &lt;a href="https://www.kentico.com/articles/kentico-xperience-13-refresh-1-is-here-delivering-the-future-of-dxp-today"&gt;Refresh 1 of Kentico Xperience&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;As you can see, there is a lot you can do with Azure Cognitive Search and Kentico Xperience. Hopefully this post helps you to no longer here those cringeworthy words of "Our Search doesn't work on our website". If you are using Azure Search with your Kentico site let me know on Twitter at &lt;a href="https://twitter.com/mcbeev"&gt;@mcbeev&lt;/a&gt;. I'd love to hear of some more real world scenarios of where this technique is deployed and how.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>azurecognitivesearch</category>
      <category>kenticoxperience</category>
      <category>cms</category>
    </item>
    <item>
      <title>How to Use Collections in Kontent</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sat, 24 Apr 2021 13:27:10 +0000</pubDate>
      <link>https://forem.com/bizstream/how-to-use-collections-in-kontent-2bh3</link>
      <guid>https://forem.com/bizstream/how-to-use-collections-in-kontent-2bh3</guid>
      <description>&lt;p&gt;&lt;a href="https://kontent.ai/?utm_source=mcbeev&amp;amp;utm_medium=mcbeevcom&amp;amp;utm_campaign=extended_trial"&gt;Kentico Kontent&lt;/a&gt; includes a fantastic feature for organizing and producing a content model / content inventory. This feature is called &lt;strong&gt;&lt;a href="https://docs.kontent.ai/tutorials/manage-kontent/projects/set-up-collections"&gt;Collections&lt;/a&gt;&lt;/strong&gt; in Kontent. It allows departments and teams to manage their content in logical groups, campaigns, global regions, enterprise business units, or any other way you can think of. Let's take a look at how to use Collections in Kontent and I'll explain why I think it adds value to any large content operation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L46Yk1EA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/5640cbb9-6507-4d4c-ab9e-60118533131c/Kontent-Collections-The-Issue.png%3Fwidth%3D760%26height%3D427" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L46Yk1EA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/5640cbb9-6507-4d4c-ab9e-60118533131c/Kontent-Collections-The-Issue.png%3Fwidth%3D760%26height%3D427" alt="Large Content Operations in Kontent"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Issue Collections in Kontent Solves
&lt;/h3&gt;

&lt;p&gt;When it comes to organizing large content operations that have global regions or multiple product catalogs across many different websites, most content management systems have the ability to categorize content in a hierarchical way. That means a region or major product grouping can be setup as folders inside of folders to divide out say North American vs. European content items or Automotive vs Healthcare industry targeted products. This approach can work fine, but it starts to get more complicated the larger your solution becomes, and it starts tying your content tightly into that one project or instance of the website you may be building. &lt;/p&gt;

&lt;p&gt;This means that different content teams or editors that are based per location or business unit may need to all access the same "content tree" to be able to add, edit, or manage the content that they need. This starts to become interesting when you need different levels of permissions, or content approval workflow based on the different regions or product groupings. What if the North American team needs to have add and edit permissions but can't publish the content because the European team has the ultimate last say in what gets to the live website channel?  On top of that does that mean you have one project or installation of the CMS in the EU? Would be slow for the NA team to access it? These are all issues that a great headless cms like Kontent attacks with its Collections feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Setup of Collections
&lt;/h3&gt;

&lt;p&gt;Getting started with Collections in Kontent it is pretty easy. As long as you have the feature available to your project (which is based on your &lt;a href="https://kontent.ai/pricing?utm_source=mcbeev&amp;amp;utm_medium=mcbeevcom&amp;amp;utm_campaign=extended_trial"&gt;Kontent subscription&lt;/a&gt;). For the rest of this post I am assuming that you have access to Collections in your subscription. You begin by &lt;strong&gt;logging into Kontent&lt;/strong&gt;, then &lt;strong&gt;choose the project&lt;/strong&gt; you are working on, and select the &lt;strong&gt;Project Settings&lt;/strong&gt; main navigation menu item in the app. Once inside of Project Settings you click on the &lt;strong&gt;Collections&lt;/strong&gt;. One optional step is to check which &lt;strong&gt;Environment&lt;/strong&gt; you are using in your Kontent Project. It's best to create this first in a non production environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aN1mHWW7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/2102c7d4-54c4-47fb-b128-bdbaf43a72e8/Kontent-Project-Settings-Collections.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aN1mHWW7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/2102c7d4-54c4-47fb-b128-bdbaf43a72e8/Kontent-Project-Settings-Collections.png" alt="Kontent Project Settings for Collections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will notice that by default, there is already one Collection in your project. The system does this at the time of the initial project creation. It's what all newly created Content Types and Content Items will be assigned to, and you must have at least on Collection in your project marked as the Default Collection at all times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5P2-lsNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/002b61fa-14f6-47b6-9711-76191d72e354/Kontent-Default-Collection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5P2-lsNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/002b61fa-14f6-47b6-9711-76191d72e354/Kontent-Default-Collection.png" alt="Kontent Default Collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create your first new Collection by clicking the very obvious &lt;strong&gt;Create New Collection&lt;/strong&gt; button. Simply give it a new name and click save. You are now on your way, seriously that is all it takes to start using the feature. In my example, I want to actually model a large enterprise organization that sells products in different regions around the world. So I have created multiple Collections in my Kontent project that represent my organization's global regions that are broken out as my organization is shaped. I have set the North American (NA) collection to the Default collection by simply renaming the original "Default" Collection to "North America (NA)" as it's new name. The results of my Collections are show below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ldtcTIcf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/cedc3ad8-c69d-40ae-96cc-6d1dab6bbecc/Kontent-Collections-695.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ldtcTIcf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/cedc3ad8-c69d-40ae-96cc-6d1dab6bbecc/Kontent-Collections-695.png" alt="Kontent Collections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are not sure on how name or setup your collections, the Kontent docs have a few more examples of &lt;a href="https://docs.kontent.ai/tutorials/set-up-kontent/set-up-your-project/collections#a-how-collections-make-your-work-easier"&gt;how to divide up your project in Kontent&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Collections from an Editor's Standpoint
&lt;/h3&gt;

&lt;p&gt;Now that you have setup some Collections, let's talk about using them. From an Editor's standpoint you pretty much are always working in one Collection. With Collections enabled the main Content Inventory screen will show you your content items with a new column of Collection. This allows editors to see at all times which Collection the content is stored within.&lt;/p&gt;

&lt;p&gt;As you can see below, my organization has different Content Items, the various chairs, of the Content Type, Product, that I am now representing in the different Collections of NA, EU, LATAM, MEA and APAC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WklpPnEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/8f619341-78ab-45ef-b0c6-a16970975bfd/Kontent-Content-Inventory.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WklpPnEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/8f619341-78ab-45ef-b0c6-a16970975bfd/Kontent-Content-Inventory.png" alt="Kontent Content Inventory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The filter system of the Kontent UI now has a new facet of filter by Collection that allows you to narrow down your content into the Collection that you want to work on. Below I am showing an example of filtering by the Content Type of Product and Collection of North American (NA).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V2FmjoEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/c0bb281f-6ecb-4f54-8157-f049d7a9500e/Kontent-Content-Inventory-Collection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2FmjoEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/c0bb281f-6ecb-4f54-8157-f049d7a9500e/Kontent-Content-Inventory-Collection.png" alt="Kentico Kontent Content Inventory Filter by Collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are a seasoned Kontent user, you may notice that I am actually using a Saved Filter of the Content Inventory screen to remember my filter choices. You can see this again in the screen shot above for where I have "Globo NA Product View" selected under the Your saved filters area near the top of the screen. This saved filter saves me the time and effort of constantly clicking the filter choices if I bounce between screens in the Kontent app (which I do all the time!).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; &lt;a href="https://docs.kontent.ai/tutorials/write-and-collaborate/get-right-people-on-right-content/find-your-content#a-saving-a-filter"&gt;Share your Saved Filters!&lt;/a&gt; You can share your saved filters with other editors to save them time as well. This feature is pretty killer when you combine it with Collections and have multiple team members working on the same content.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second aspect of working with Collections is creating Content Items. Click on the Create New button to create a new Content Item and you can see the screen changes to ask you what Collection you would like to create the new Content Item in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vsp8GutF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/3b3f83a9-c188-40ee-86a3-968329f90fb9/Kontent-Content-Item-Create-in-Collection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vsp8GutF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/3b3f83a9-c188-40ee-86a3-968329f90fb9/Kontent-Content-Item-Create-in-Collection.png" alt="Kontent-Content Item Create in Collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that choice the normal create Content Item process continues to ask you which type of item you would like to create and the system behaves normally from there. &lt;/p&gt;

&lt;p&gt;The last set of differences is around the security of working with content in Collections. When it comes to users and roles, the system shines. Now we can divide up our other team members into all of the Collections on the project, or lock them down to just a single Collection. Here I am giving my good friend and fellow Kontent MVP, &lt;a href="https://twitter.com/meandmyrobot"&gt;Michael Kinkaid&lt;/a&gt; access to any Collection in the project. I could actually designate a different role in the NA collection vs. the EU collection if I want to as well. Which is very fitting for Michael as he splits his time between Canada and Ireland... or at least he used to before this whole global pandemic thing. If you are reading the Michael: Cheers mate!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MK9wR37r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/4dfb87d3-dde0-4aa1-b091-81a8f878659e/Kontent-Roles-in-Collection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MK9wR37r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/4dfb87d3-dde0-4aa1-b091-81a8f878659e/Kontent-Roles-in-Collection.png" alt="Kontent Roles in Collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Collections from a Developer's Standpoint
&lt;/h3&gt;

&lt;p&gt;For those in my techincal audience I'm sure you are interested in how to inject content from the Delivery or Preview APIs that use Collections in your apps. Well it's very simple. Nothing much changes in your code and that is a benefit in my opinion. There is simply a new System filter that you use to pass in the code name of the Collection into the API call. &lt;/p&gt;

&lt;p&gt;Even though it sounds simple, it actually took me a second or two to figure out how to do this though. The documentation explains what to do, but doesn't actually show the full example. So I'm going to show it here. The key is to use the*&lt;em&gt;system.collection&lt;/em&gt;* querystring parameterif you are using the REST API or &lt;strong&gt;EqualsFilter&lt;/strong&gt; if you are in C# land via the .NET Kontent Delivery SDK.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://deliver.kontent.ai/"&gt;https://deliver.kontent.ai/&lt;/a&gt;/items?system.type=product&amp;amp;&lt;strong&gt;system.collection&lt;/strong&gt;=europe_&lt;em&gt;eu&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This will get you a nice result set of your content. In my example from up above it gets me this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wi4w_GyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/90a34c05-9c0c-46cd-b872-558412404c35/Kontent-DeliveryAPI-Collection-GetItems.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wi4w_GyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/90a34c05-9c0c-46cd-b872-558412404c35/Kontent-DeliveryAPI-Collection-GetItems.png" alt="Kontent DeliveryAPI Collection GetItems"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The value of the system.collection is from the &lt;strong&gt;codename&lt;/strong&gt; of the Collection item itself in the UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PBjxq_jW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/d19dad6e-e805-43a3-a38f-7953c04ef89c/Kontent-Collections-Codename.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PBjxq_jW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/d19dad6e-e805-43a3-a38f-7953c04ef89c/Kontent-Collections-Codename.png" alt="Kontent Collections Codename"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also below is a C# snippet of using the EqualsFilter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch Me and the Kontent Team Present
&lt;/h3&gt;

&lt;p&gt;If you want to actually watch me demo and talk more on Collections and even hear from the Kontent team themselves on the subject, you can check out the recording of the last &lt;a href="https://www.youtube.com/channel/UCy6XSB_tJGTnAWEfLv2EqcA"&gt;North American Kontent User Group on Youtube at my channel&lt;/a&gt; or embedded below:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bxF3eTcGIVU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  What Collections Can't Yet Do
&lt;/h3&gt;

&lt;p&gt;There is one large limitation of Collections that I feel is fair to bring up. That is the Asset management feature of Kontent, the storage, management, and delivery of images, files, and pdfs has no concept yet of Collections. There is still just the simple folders of Assets that Kontent gives you. I'm hoping that the Kontent team adds in the ability to segment out assets by Collections over time. There is a simple workaround to build more folder structures in the Asset manager, that mimic your Collections, but as you can tell, I'm not a huge fan of nested folders within folders for dealing with content or assets. &lt;/p&gt;

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

&lt;p&gt;I hope that after reading this blog post you can tell that Collections in Kentico Kontent are a critical factor for success for large content operations. I recommend using them in your Kontent project. The feature is definitely more than just a folder. If you are already using them in your project, let me know on twitter at &lt;a href="https://twitter.com/mcbeev"&gt;@mcbeev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z8TQn7jH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/0d8aa14b-7024-44bb-a20a-6455cda55de6/Kontent-Collections-Rad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z8TQn7jH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/0d8aa14b-7024-44bb-a20a-6455cda55de6/Kontent-Collections-Rad.png" alt="Kontent Collections Rad"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kenticokontent</category>
      <category>headlesscms</category>
      <category>headless</category>
    </item>
    <item>
      <title>Kentico Xperience 13 is Here</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sun, 08 Nov 2020 15:28:20 +0000</pubDate>
      <link>https://forem.com/bizstream/kentico-xperience-13-is-here-4bc6</link>
      <guid>https://forem.com/bizstream/kentico-xperience-13-is-here-4bc6</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In case you hadn't heard, or seen the press release, &lt;a href="https://www.kentico.com/articles/kentico-software-launches-kentico-xperience-13-and-reveals-the-future-of-its-digital-experience-platform"&gt;Kentico Software launched Kentico Xperience 13&lt;/a&gt; a week ago to the public. However, that is not what I am talking about. I'm talking about that fact that Kentico Xperience 13 is right here at my blog at &lt;a href="https://www.mcbeev.com/"&gt;mcbeev.com&lt;/a&gt; ! Along side .Net Core MVC, it now powers my blog at Mcbeev.com, and I'm stocked about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mcbeev.com Past
&lt;/h3&gt;

&lt;p&gt;The previous version of this blog was &lt;a href="https://www.mcbeev.com/kentico-cms-blog-migration-complete"&gt;started back in February of 2012 on Kentico 6.0&lt;/a&gt;, it was a port over from &lt;a href="https://blogengine.io/"&gt;BlogEngine.Net&lt;/a&gt;. which, at the time, was a fantastic product and looks like it still is. When the original migration happened, I built the site on the modern development methodology of the time in Kentico, known as the Portal Engine. The Portal Engine was built on the full .Net Framework 2.0 using ASP.NET WebForms. That site and codebase made it 8 years! That's a pretty good track record, but time has marched on. The blog was starting to show its age and having some performance issues, so it was time for something new.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mcbeev.com Present
&lt;/h3&gt;

&lt;p&gt;For the last few months I have been working on a new version of the site. I have been lucky enough to be majorly helped by some amazing team members over at &lt;a href="https://www.bizstream.com/"&gt;BizStream&lt;/a&gt; in the process. I think the longest part of the process was coming up with the new design, which I really like (especially &lt;strong&gt;dark mode&lt;/strong&gt;). The site is now written in &lt;a href="https://xperience.io/"&gt;Kentico Xperience 13&lt;/a&gt;, &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/introduction"&gt;.NET Core 3.1&lt;/a&gt;, and &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/overview?view=aspnetcore-3.1"&gt;ASP.NET Core MVC&lt;/a&gt;. It was one heck of a process to migrate over 225 blog posts from the old site to this one, but I couldn't be happier with the results.&lt;/p&gt;

&lt;p&gt;The experience of using Kentico 13 is a welcome one. The editing interface is faster and sleeker than the previous version of Kentico that I was using. The new content model that we created using structured content makes it easier to write and publish blog posts in a simple way. Here's an example of the editing interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ae__RLbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/4d3a1f57-5bbf-4d5b-bebf-d47fb8ce5522/Mcbeevcom-Kentico-13-Edit-Post.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ae__RLbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/4d3a1f57-5bbf-4d5b-bebf-d47fb8ce5522/Mcbeevcom-Kentico-13-Edit-Post.png" alt="Kentico Xperience 13 Edit Post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From a technical standpoint the developers on the project and myself have really enjoyed using VS Code to work with the solution and we are leveraging multiple new aspects of ASP.NET Core like &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1"&gt;View Components&lt;/a&gt;, &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-3.1"&gt;Tag Helpers&lt;/a&gt;, and &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-3.1&amp;amp;tabs=visual-studio"&gt;Razor Class Libraries&lt;/a&gt;. An example of writing Kentico Xperience code in .NET Core in VS Code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qO2aYEJd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/4bfd96e4-6c88-4a57-ac09-dbab87118bb1/Mcbeevcom-Kentico-13-Code.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qO2aYEJd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/4bfd96e4-6c88-4a57-ac09-dbab87118bb1/Mcbeevcom-Kentico-13-Code.png" alt="Kentico Xperience 13 .Net Core Code Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shameless plug, I was even quoted in the press release about the release of Kentico Xperience 13:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I absolutely love the fact that Kentico Xperience 13 is fueling the next generation of DXP capabilities with its ASP.NET Core first approach, re-designed Marketing Automation engine, and MVC Page Builder improvements." - Brian McKeiver, Co-Owner at BizStream&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Mcbeev.com Future
&lt;/h3&gt;

&lt;p&gt;Yes, I am already planning on the future. The reason that I am excited about this build is that it sets me up very well for transitioning to the next major release of .NET and the next 8 years of running this blog on sound technology should be easily able to be supported. I can say that because this week is &lt;a href="https://www.dotnetconf.net/"&gt;.NET Conf 2020&lt;/a&gt;. At .NET Conf 2020 .NET 5 will be released to the world. You might have heard &lt;a href="https://www.mcbeev.com/net-5-0-preview-1-with-kentico-13-beta-2-a-double-phoenix"&gt;me talk about .NET 5 and Kentico Xperience&lt;/a&gt; before, but these two technologies line up really well. It will be a very easy upgrade for me to go from .NET Core 3.1 to .NET 5. In fact I don't think it should take more than a day's worth of time to do so. This is another good reason to get your projects upgraded to MVC Core as soon as you can with Kentico Xperience.   &lt;/p&gt;

&lt;p&gt;Once the update to .NET 5 is completed, I plan on switching out my search engine from the internal Kentico Xperience Smart Search to using Azure Cognitive Search, but I didn't have enough time to do that yet. I also plan to re-create my automatic blog post notification workflow in the new Xperience Marketing Automation re-write. Finally I want to create a few re-usable MVC Core widgets from a few aspects of my site, like the Related Blog Posts feature, and contribute those to the &lt;a href="https://devnet.kentico.com/marketplace"&gt;Kentico Xperience Open Source Marketplace&lt;/a&gt;. I wish there was more time in the day. &lt;/p&gt;

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

&lt;p&gt;For those of you who are still on a previous version of Kentico Xperience and still using Portal Engine (WebForms), I highly recommend that you check out the &lt;a href="https://xperience.io/product/mvc-transition-guide"&gt;MVC Transition Guide&lt;/a&gt; that has been updated for the Kentico Xperience 13 release. If you are not an existing Kentico Xperience user and want to create a powerful digital experience platform on a future-proof web framework utilizing .NET Core MVC, you can download a free trial at &lt;a href="https://xperience.io/get-started/trial"&gt;https://xperience.io/get-started/trial&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blogging</category>
      <category>dotnetcore</category>
      <category>aspnetcore</category>
      <category>kenticoxperience</category>
    </item>
    <item>
      <title>Kentico Rocks Episode #035 - Examining Web Spotlight for Kentico Kontent</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Wed, 23 Sep 2020 11:35:01 +0000</pubDate>
      <link>https://forem.com/bizstream/kentico-rocks-episode-035-examining-web-spotlight-for-kentico-kontent-3575</link>
      <guid>https://forem.com/bizstream/kentico-rocks-episode-035-examining-web-spotlight-for-kentico-kontent-3575</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this episode of &lt;strong&gt;Kentico Rocks&lt;/strong&gt; , &lt;strong&gt;Brian McKeiver&lt;/strong&gt; is joined by fellow Kentico Kontent MVP &lt;strong&gt;Andy Thompson&lt;/strong&gt;. Andy and Brian discuss the newly released &lt;a href="https://webspotlight.kontent.ai/"&gt;Web Spotlight feature&lt;/a&gt; for &lt;a href="https://kontent.ai/?utm_source=kenticorocks35&amp;amp;utm_medium=mvp_27116&amp;amp;utm_campaign=extended_trial"&gt;Kentico Kontent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;According to Andy, Web Spotlight addresses the elephant in the room when it comes to utilizing a Headless CMS, which is, how can we expect our content teams to develop a website without a head to look at it with?&lt;/p&gt;

&lt;p&gt;Check out the latest episode of Kentico Rocks to find out what developers need to know about implementing Web Spotlight, how to implement it in a .Net Core MVC project, and how it possibly changes your content model requirements. Brian and Andy both agree that ultimately, when implemented correctly, Web Spotlight by Kontent can take your Headless CMS site editing experience to the next level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch Now
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vENFZ46FtD4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  In This Episode
&lt;/h3&gt;

&lt;p&gt;Brian McKeiver and Andy Thompson discuss the following topics in Kentico Rocks podcast episode #35:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  What Web Spotlight is for Kentico Kontent&lt;/li&gt;
&lt;li&gt;  What developers need to know about getting started with Web Spotlight&lt;/li&gt;
&lt;li&gt;  A few pitfalls to watch out for&lt;/li&gt;
&lt;li&gt;  How to integrate a .Net Core MVC site with the new Smart Link SDK&lt;/li&gt;
&lt;li&gt;  A review of Andy's blog post and his custom tag helper for MVC Core&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related Links to this episode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://kontent.ai/?utm_source=kenticorocks35&amp;amp;utm_medium=mvp_27116&amp;amp;utm_campaign=extended_trial"&gt;Kentico Kontent as a Headless CMS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.gatsbyjs.org/"&gt;Web Spotlight for Kontent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.luminary.com/blog?author=Andy%20Thompson"&gt;Andy Thompson's MVP blog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.luminary.com/blog/web-spotlight-visual-page-editing-headless-kontent"&gt;Andy's blog post on Web Spotlight&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also listen to the previous episode of Kentico Rocks where I interview Adam about &lt;a href="https://dev.to/Blog/July-2020/Kentico-Rocks-34"&gt;getting started with Kentico Kontent and GatsbyJS&lt;/a&gt;. Or you can check out all of my &lt;a href="https://www.mcbeev.com/kenticorocks"&gt;Kentico Rocks podcasts here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>headless</category>
      <category>dotnetcore</category>
      <category>kenticokontent</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>Azure Logic App URL Too Long for Webhook?</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sat, 05 Sep 2020 19:18:27 +0000</pubDate>
      <link>https://forem.com/bizstream/azure-logic-app-url-too-long-for-webhook-1m24</link>
      <guid>https://forem.com/bizstream/azure-logic-app-url-too-long-for-webhook-1m24</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Microsoft &lt;a href="https://azure.microsoft.com/services/logic-apps"&gt;Azure Logic Apps&lt;/a&gt; is an Azure cloud service that helps you schedule, automate, and orchestrate tasks, business processes, and &lt;a href="https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-overview#logic-app-concepts"&gt;workflows&lt;/a&gt; when you need to integrate apps, data, systems, and services across enterprises or organizations. Well that is the official definition any way. I like to think of them as a serverless way to bridge the gaps between systems like Slack, CRM, Twitter, Email and other APIs.&lt;/p&gt;

&lt;p&gt;What really has always impressed me about Logic Apps is that they are incredibly simple to setup and use, where in years past, you as a developer, would have to write a lot of code to integrate each of the actions that they can take. Instead of having to spend hours per integration point, the work becomes just a few minutes of configuration inside of the Azure Portal and Logic Apps designer.  &lt;/p&gt;

&lt;p&gt;That is why I was surprised a few weeks back when I was using an Azure Logic App to integrate with my Kentico Xperience website and internal Slack team. During that work, I received a message from the third-party service that I was using, that my Webhook URL was too long. WTF? “How can a Webhook URL be too long?”, was my first thought when I saw that message. Then when I went to see where I could to configure the URL endpoint in my Logic App, I was again surprised that this didn’t seem possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Scenario
&lt;/h3&gt;

&lt;p&gt;First, a little background on the scenario. What I was working on was something a little fun for my team at BizStream. BizStream recently celebrated our 10-year anniversary of being a Kentico Xperience Gold Partner. My marketing team wanted to collect a few short videos of our customers saying congrats to our team. We wanted a simple way to provide a page on our website that customers could record some video. We ended up choosing a service called &lt;a href="https://addpipe.com/"&gt;Pipe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was an easy decision to use this service because within about 30 minutes, I was able to add a widget into our Kentico Xperience site. I had a basic landing page with the Pipe video recorder in no time. It allowed our customers to record a video and it uploaded those to a dashboard in Pipe. Our internal marketing team could now watch and download the new assets. We then launched an email marketing campaign to drive our customers to this new landing page. Within a few hours, we were accepting our first few customer recordings. The page with the widget looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.bizstream.com/celebrate-10-with-kentico"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1lY-ANVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/BizStream-com-AddPipe.png" alt="BizStream Celebrates 10 Years of being Kentico Gold Partners" title="BizStream Celebrates 10 Years of being Kentico Gold Partners" width="782" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The First Challenge: How to Integrate Pipe with Slack
&lt;/h3&gt;

&lt;p&gt;After refreshing the Pipe dashboard a few times I realized that I didn’t want to manually check for new recordings every 5 minutes. Luckily, there was a tab in the admin tool named Webhooks. I happen to be a big fan of Webhooks and was happy to see this capability. After seeing that I knew that I wanted to get the new video recorded event to show up in our marketing team’s Slack channel.&lt;/p&gt;

&lt;p&gt;I instantly thought that yes, I can use &lt;strong&gt;Azure Logic Apps&lt;/strong&gt; for this in no time! I fired up the Azure Portal and created a new Logic app. After deciding what is the correct trigger, “&lt;strong&gt;When a HTTP request is received&lt;/strong&gt;”, I quickly had the Logic app configured to create a message in the Slack channel that reported to the marketing team when a new recording was received.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uXuFQ8Ib--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-Designer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uXuFQ8Ib--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-Designer.png" alt="Azure Logic App Designer" title="Azure Logic App Designer" width="762" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running it in the Logic app designer worked flawlessly. But when I went to try it for real in the Webhook admin settings in Pipe, the Webhook failed every time and no Slack message showed up in my channel. “What the heck?!” I thought. After some debugging efforts, it turned out the Webhook URL field couldn’t handle the length of the Azure Logic app HTTP Post URL. &lt;strong&gt;The Azure Logic app generated URL was too long&lt;/strong&gt; for Pipe to handle.&lt;/p&gt;

&lt;p&gt;The URL that Azure Logic app generated for the When HTTP request is received trigger looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JHQSD6ND--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-HTTP-Post.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JHQSD6ND--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-HTTP-Post.png" alt="Azure Logic App HTTP Post" title="Azure Logic App HTTP Post" width="501" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you copy out and look at the entire HTTP Post URL field from the screen shot above you see the full URL as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href="https://prod-31.eastus2.logic.azure.com:443/workflows/a456db78ab075ab020fd10740409173f/triggers/manual/paths/invoke?api-version=2016-10-01&amp;amp;sp=%2Ftriggers%2Fmanual%2Frun&amp;amp;sv=1.0&amp;amp;sig=7VqFXQVJlwcnalgfdOHZliG_xqHzB1nJtJS3dW_wDDE"&gt;https://prod-31.eastus2.logic.azure.com:443/workflows/a456db78ab075ab020fd10740409173f/triggers/manual/paths/invoke?api-version=2016-10-01&amp;amp;sp=%2Ftriggers%2Fmanual%2Frun&amp;amp;sv=1.0&amp;amp;sig=7VqFXQVJlwcnalgfdOHZliG_xqHzB1nJtJS3dW_wDDE&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh, and don’t worry that’s not my real URL pasted above either. However, if you do a character count on that URL, it is about 223 characters long. The URL actually includes the main workflow path (including region) and some securtiy signature properties in the querystring. That's why its so darn long. Pipe, as well as, other services I have worked with, only allow for 200 characters in the Webhook URL field.&lt;/p&gt;

&lt;p&gt;Since the solution was working in the Logic app designer, I knew I had to find a way how to handle the Azure Logic app webhook URL being too long.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Challenge: How to Shorten an Azure Logic App Webhook URL
&lt;/h3&gt;

&lt;p&gt;After looking through all the configurations and settings, I settled on the fact that there is nothing inside of Logic apps that allow you to change the URL for an HTTP trigger.  Doing some quick Googling led me to the fact that Azure Logic Apps just do not have this configuration ability, but it also led me to the answer. To shorten or customize your Azure Logic App Webhook URL you need to add a different Azure service into the mix, &lt;a href="https://docs.microsoft.com/en-us/azure/api-management/api-management-key-concepts"&gt;Azure API Management&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, I have some experience with Azure API Management. I have used in a few past projects with connecting internal on-premise APIs and Azure App Service APIs to Kentico Xperience projects. I have even &lt;a href="https://dev.to/Blog/February-2018/I-m-Speaking-at-Orlando-Code-Camp-2018"&gt;spoken about Azure API Management&lt;/a&gt; at a few tech conferences.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Combining Azure Logic Apps and Azure API Management
&lt;/h3&gt;

&lt;p&gt;First, I will be honest, I did not come up with this solution, but I think it’s worth detailing again. I used the excellent Microsoft &lt;a href="https://docs.microsoft.com/en-us/azure/api-management/import-logic-app-as-api"&gt;documentation on how to Import a Logic App as an API in Azure API Management&lt;/a&gt; for the majority of the solution. The steps for the whole solution boil down to:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create a new Azure API Management resource.
&lt;/h4&gt;

&lt;p&gt;I used the Consumption based pricing tier for the API Management Service which requires you to use only certain regions in Azure.  I used the “(US) Central US” region. With this configuration we get one million free API calls and a 99.9% SLA for free. If you are going to use this resource for something real you might want to consider a higher pricing tier. I named the resource &lt;strong&gt;apim-apppipe&lt;/strong&gt; to keep the URL short to start with, which ends up as &lt;a href="https://apim-apppipe.azure-api.net"&gt;https://apim-apppipe.azure-api.net&lt;/a&gt; for the base URL.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Import the Logic App as an API in APIM
&lt;/h4&gt;

&lt;p&gt;Again, using the &lt;a href="https://docs.microsoft.com/en-us/azure/api-management/import-logic-app-as-api"&gt;documentation&lt;/a&gt; this was fairly easy. Your Logic App should show up in the list to import. Give your API a name, I went with logic-addpipe-prod and named the operation recordings. This results in a new API Management URL of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://apim-apppipe.azure-api.net/webhooks/v1/recordings"&gt;https://apim-apppipe.azure-api.net/webhooks/v1/recordings&lt;/a&gt; (which is a short 57 characters).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AexFIexb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-APIM-Import-Logic-App.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AexFIexb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-APIM-Import-Logic-App.png" alt="Azure APIM Import Logic App" title="Azure APIM Import Logic App" width="701" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After importing your Logic app, and once you have given the operation it name it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mcbeev.com/MBV/media/uploads/2020/API-in-Azure-API-Management.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y6Lj0Odb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/API-in-Azure-API-Management_t.png" alt="API in Azure API Management" title="API in Azure API Management - Click to Enlarge" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Updated the Webhook URL field to the new API in APIM
&lt;/h4&gt;

&lt;p&gt;Since I knew that 57 characters would work (much less than 223), I was confident that the solution would work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z5ebG5fm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/AddPipe-Webhook-APIM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z5ebG5fm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/AddPipe-Webhook-APIM.png" alt="AddPipe Webhook APIM" title="AddPipe Webhook APIM" width="729" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sure enough, after applying the change to call the API from APIM, instead of directly calling the Azure Logic App HTTP endpoint. The solution…. errored out. What? Yes, it errored. It turned out that the post object between Pipe and the real Logic app wasn’t quite pure JSON as I was expecting. It happened to have a wrapping layer of payload={…JSON object within…}.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. [Optional] Use Azure Logic App Expressions to transform HTT Post data
&lt;/h4&gt;

&lt;p&gt;Luckily, I was able to use some expression steps in the Azure Logic app to remove the “payload=” string and convert the string body of the request to a full JSON object because Logic apps have that capability built in (another reason they are awesome). That was done through a combination of initial variable operations that you can massage the data through like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2v3lxlaO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-Init-Variable.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2v3lxlaO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-Init-Variable.png" alt="Azure Logic App Initialize Variable" title="Azure Logic App Initialize Variable" width="621" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Success: The Message Shows up in Slack
&lt;/h3&gt;

&lt;p&gt;Now that everything works, the final result looks like this from a systems overview perspective:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jq-On9RU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Azure-Logic-App-Slack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jq-On9RU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Azure-Logic-App-Slack.png" alt="Kentico Azure Logic App Slack" title="Kentico Azure Logic App Slack" width="697" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final result in the Slack channel looks like this for our marketing team:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AAhi4r97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-Slack-Message-Result.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AAhi4r97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Azure-Logic-App-Slack-Message-Result.png" alt="Azure Logic App Slack Message Result.png" title="Azure Logic App Slack Message Result.png" width="729" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that the message contains data from the payload of the webhook post to our Azure Logic app and the marketing team is now clued into the fact that there is a new recording to view all right from within Slack.&lt;/p&gt;

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

&lt;p&gt;There is literally a ton more you can do with Azure API Management and Azure Logic Apps and I have only scratched the surface. I hope I have shown that when you need to integrate apps or websites, data, systems, and services across enterprises or organizations Azure Logic Apps is a service that is a good choice. I really like how easy it was to integrate with our Kentico Xperience website at BizStream.com with a third party video recording service that notifies Slack when activity happens. I no longer have to manually refresh any dashboards, and now my marketing team knows when and how much the integration is used.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>logicapps</category>
      <category>serverless</category>
      <category>webhooks</category>
    </item>
    <item>
      <title>Introducing The Kentico Xperience SQL Utility Scripts Open Source Repo</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sun, 23 Aug 2020 12:55:56 +0000</pubDate>
      <link>https://forem.com/bizstream/introducing-the-kentico-xperience-sql-utility-scripts-open-source-repo-1mcd</link>
      <guid>https://forem.com/bizstream/introducing-the-kentico-xperience-sql-utility-scripts-open-source-repo-1mcd</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Over the years of working with Kentico CMS, Kentico EMS, and now Kentico Xperience I have either written, or been a part of team that has written, various TSQL scripts to support the SQL Database side of working with the tool. Most recently I was actually working on a script that was meant to clean up e-commerce order and customer history. That task had some acceptance criteria of keeping some order history for a certain list of customers (those customers with a certain email domain), but removing all the rest (which is a pretty good idea in the world of data privacy and data security when you are copying databases to bring up new environments of a e-commerce website). That last requirement made the task call for a custom script as opposed to a one time TRUNCATE all type of solution. &lt;/p&gt;

&lt;p&gt;As I was doing that, I got to thinking, there have been many times over the years where I have had to do this. Why not find all of these one of utility type of scripts and open source them on GitHub so that other Kentico Xperience developers out there could benefit. And with that, the idea for the Kentico Xperience SQL Utility Script repository was born.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kentico Xperience SQL Utility Script GitHub Repository
&lt;/h3&gt;

&lt;p&gt;If you head on over to the GitHub repository at &lt;a href="https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts"&gt;https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts&lt;/a&gt;, or click the image below you can see the actual scripts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZSgDKCrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-SQL-Utility-Scripts.png" alt="Kentico Xperience SQL Utility Scripts" title="Kentico Xperience SQL Utility Scripts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repo has a collection of SQL Scripts used to help maintain and work with Kentico Xperience databases. But remember, with great power comes great responsibility. These scripts are only tested in a few environments. Make sure to test them out first in your development environment and please be sure to create a database backup before running for real.&lt;/p&gt;

&lt;p&gt;A few notes about the repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Most of the scripts will be most useful with clean up of long running Kentico Xperience instances, where you want to trim down a database size from say over 25 GB back down to less than 5 GB.&lt;/li&gt;
&lt;li&gt;  There are version specific folders inside of /src for each main version of Kentico: &lt;a href="https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts/tree/master/src/KX12"&gt;KX12&lt;/a&gt; == Kentico Xperience 12.0.x.&lt;/li&gt;
&lt;li&gt;  There is an &lt;a href="https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts/tree/master/src/All"&gt;All subfolder&lt;/a&gt; that has a useful &lt;a href="https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts/blob/master/src/All/KenticoShrinkSQLLogFile.sql"&gt;Shrink SQL Log File script&lt;/a&gt; in it, or in my head is a place for a script that works across all versions of Kentico.&lt;/li&gt;
&lt;li&gt;  The one we use the most of at over at &lt;a href="https://www.bizstream.com"&gt;BizStream&lt;/a&gt; is the &lt;a href="https://github.com/mcbeev/Kentico-Xperience-SQL-Utility-Scripts/blob/master/src/KX12/KenticoDisableTasksForDevSpinup.v12.sql"&gt;Disable Tasks for Development Environment Spinup&lt;/a&gt;. This script will ensure your new restore to dev doesn't do something stupid like e-mail out to 10k real email addresses.&lt;/li&gt;
&lt;li&gt;  I can personally attest to using each of these scripts and seeing them work, they are however, to use at your own risk.&lt;/li&gt;
&lt;li&gt;  Feel free to collaborate with me on the scripts, if you have a new one and want to add it, shoot me a Pull Request. If you think my SQL is terrible, fix it, and shoot me a Pull Request.&lt;/li&gt;
&lt;li&gt;  Please make sure to include some comments on what the script does and what version of Kentico it is intended for.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I hope the Kentico Xperience development community finds these scripts useful for working with Kentico databases. Again, if you have a new one and want to add it, shoot me a PR. If you think my SQL is terrible, fix it, and shoot me a PR. Thanks!&lt;/p&gt;

</description>
      <category>kenticoxperience</category>
      <category>dotnet</category>
      <category>cms</category>
    </item>
    <item>
      <title>🤦‍♂️ Weekly fail (34/2020)</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Tue, 18 Aug 2020 12:08:55 +0000</pubDate>
      <link>https://forem.com/kontent_ai/weekly-fail-34-2020-398a</link>
      <guid>https://forem.com/kontent_ai/weekly-fail-34-2020-398a</guid>
      <description>&lt;p&gt;You would think trying to stream live code of Q and A session would be easy right? No need to do a full dry run ahead of time because what could possibly go wrong? Well I'm here to say I failed last week doing that very thing. You see, streaming on YouTube or Twitch looks easy, as we watch our tech colleagues do it all the time. Making the assumption that "it should just work" is one way to fail spectacularly. And that is the key fail that I did this past week.&lt;/p&gt;

&lt;p&gt;I attempted to stream a joint live Q and A session for answering Kentico Xperience development community questions with my good friend. It seemed to have went perfectly well for both him and I, as we had our conversation and answered a few questions on YouTube live for about 45 mins. In fact, I really enjoyed the conversation and thought we provided some good insight on how to ask a development question. I didn't even realize there was a problem until the stream was finished and I took my phone off of silent mode. My phone immediately lit up with about 10 notifications saying "Brian, the sound!, its doubling up and echoing!". The echoing was so bad that the few people watching didn't make it all the way through with us.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson learned:&lt;/em&gt; &lt;strong&gt;Test your audio/video setup ahead of time, exactly as it should be, even with a second or third guest during that test, and even do a production stream to prove it's working. That way you can be sure not to fail like I did.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>fail</category>
      <category>lessonslearned</category>
      <category>livestream</category>
      <category>twitch</category>
    </item>
    <item>
      <title>How to Add Azure App Configuration and Feature Flags into Blazor in .Net 5</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sun, 19 Jul 2020 14:36:20 +0000</pubDate>
      <link>https://forem.com/bizstream/how-to-add-azure-app-configuration-and-feature-flags-into-blazor-in-net-5-1037</link>
      <guid>https://forem.com/bizstream/how-to-add-azure-app-configuration-and-feature-flags-into-blazor-in-net-5-1037</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In case you haven't heard, &lt;strong&gt;&lt;a href="https://azure.microsoft.com/en-us/services/app-configuration/"&gt;Azure App Configuration&lt;/a&gt;&lt;/strong&gt; is a newer service out of Azure that is billed as a tool that &lt;strong&gt;provides a way to centrally manage application settings&lt;/strong&gt;. &lt;strong&gt;Azure App Configuration&lt;/strong&gt; is not just another way to manage configuration files, in my opinion, it is a bit different because it actually provides a mechanism to easily modify your application's behavior at runtime with the click of a button. It does this through the use of &lt;a href="https://docs.microsoft.com/en-us/azure/azure-app-configuration/concept-feature-management"&gt;&lt;strong&gt;Feature Flags&lt;/strong&gt;&lt;/a&gt; which seamlessly connect to App Configuration and can easily be used through a few simple NuGet packages in your applications.&lt;/p&gt;

&lt;p&gt;The ability to easily change my application's behavior would have been nice to have in a side project I worked on this year. I was creating a dashboard and scoring application in &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-3.1"&gt;&lt;strong&gt;Blazor&lt;/strong&gt;&lt;/a&gt; that I needed for a local event. II had two goals for this project. One, I wanted to learn how to use &lt;strong&gt;Blazor&lt;/strong&gt;, and two, I needed to build something fast as I only had a few days to create a solution. Had I started with App Configuration in Blazor and utilized a Feature Flag, &lt;strong&gt;I would have saved myself from the production disaster&lt;/strong&gt; that happened during the event.&lt;/p&gt;

&lt;p&gt;Keep reading this blog post to find out &lt;strong&gt;How to Add Azure App Configuration and Feature Flags into Blazor in .NET 5.0&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - Create Your Blazor App with .NET 5.0
&lt;/h2&gt;

&lt;p&gt;In my opinion the best way to get started with Blazor today is to use the .NET 5.0 version that is available at this time. That would be &lt;a href="https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-preview-6/"&gt;.NET 5 Preview 6&lt;/a&gt; at time of writing this blog post. If you don't have the preview build on your machine, you need to start with downloading the &lt;a href="https://dotnet.microsoft.com/download/dotnet/5.0"&gt;.NET 5 Preview SDK&lt;/a&gt;. Go do that if you haven't. Once the SDK is installed I would create a new folder on your drive to house the new project and then fire up a terminal window through &lt;strong&gt;VS Code&lt;/strong&gt; or open up PowerShell to that location. You could use &lt;strong&gt;Visual Studio 2019&lt;/strong&gt; to do this, but you would need a &lt;a href="https://visualstudio.microsoft.com/vs/preview/"&gt;recent preview build of Studio&lt;/a&gt; to make that happen. Honestly, it is easier and faster with VS Code and a terminal because we are going to use the &lt;a href="https://dev.to/Blog/May-2019/Kentico-Rocks-Podcast-Episode-20"&gt;DotNet CLI tool&lt;/a&gt; to create our basic structure.&lt;/p&gt;

&lt;p&gt;At a terminal, run the following command to see if you have the SDK correctly installed. It should indicate that you also have the &lt;strong&gt;Blazorserver&lt;/strong&gt; or &lt;strong&gt;Blazorwasm&lt;/strong&gt; templates available.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;dotnet new -h
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should see the welcome message stating preview 6 and in the list of templates the two Blazor templates should be there.&lt;/p&gt;

&lt;p&gt;Now to create the project for VS Code run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;dotnet new blazorserver -o BlazorFeatureFlags
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command will create a new Blazor Server application in a sub folder named BlazorFeatureFlags. The name in the -o switch can be whatever you want. I always like to make sure that the first install of a project works so optionally you can then run &lt;strong&gt;dotnet build&lt;/strong&gt; to see the project compile, and then run &lt;strong&gt;dotnet run&lt;/strong&gt; to be able to browse to the website at port 5000 or port 5001 on https. But you don't have to if you are a brave soul.&lt;/p&gt;

&lt;p&gt;Once the base is there, we need to add in a few NuGet packages from Microsoft to work with an Azure App Configuration resource and the ability to use Feature Flags in our C# project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration

dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore

dotnet add package Microsoft.FeatureManagement
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running those commands will restore the NuGet packages into the new project and set us up to start using Azure App Configuration in Blazor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Modify Startup.cs and Program.cs to Know About Azure App Configuration
&lt;/h3&gt;

&lt;p&gt;Now that the base of the project is there, we need to start using the features we just added through the NuGet packages. This second step is the most crucial step to get correct, and my motivation for this blog post, as it just didn't seem to be fully clear on how best to do this when I was working on it myself.&lt;/p&gt;

&lt;p&gt;Inside of &lt;strong&gt;Startup.cs&lt;/strong&gt; we need to add in a using statement and inside of &lt;strong&gt;ConfigureServices&lt;/strong&gt;(...) add the ability to use &lt;strong&gt;FeatureManagement&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.FeatureManagement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRazorPages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddServerSideBlazor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFeatureManagement&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WeatherForecastService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IWebHostEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHsts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseStaticFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAzureAppConfiguration&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRouting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseEndpoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapBlazorHub&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapFallbackToPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/_Host"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The next file we need to modify is inside of &lt;strong&gt;Program.cs&lt;/strong&gt;. We need to replace the creation of default host builder with one that uses Azure App Configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IHostBuilder&lt;/span&gt; &lt;span class="nf"&gt;CreateHostBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;

 &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDefaultBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureWebHostDefaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webBuilder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
     &lt;span class="n"&gt;webBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureAppConfiguration&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;hostingContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAzureAppConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ConnectionString"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureRefresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refresh&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Settings:Sentinel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refreshAll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                                   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetCacheExpiration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                        &lt;span class="p"&gt;})&lt;/span&gt;
                   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseFeatureFlags&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;
     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseStartup&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There is an important note about this configuration. We are telling the application to refresh the values of the configuration every 1 minute based off of a &lt;strong&gt;Sentinel key&lt;/strong&gt;. There is nothing special about the name Sentinel other than its our main indicator that if we change this key value, the configuration of the entire Azure App Configuration gets reloaded. Note the &lt;strong&gt;UseFeatureFlags&lt;/strong&gt; method has a way to do this for just Feature Flags inside of the Azure resource, but technically you can have both Feature Flags and Configuration without Feature Flags if you want. In this example we are now refreshing both types of configs because we have the middlewear pipeline being refreshed in &lt;strong&gt;Startup.cs with the call to use.AzureAppConfiguration()&lt;/strong&gt; (which technically is optional, but required for dynamic refresh).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Create an Azure App Configuration Resource
&lt;/h3&gt;

&lt;p&gt;With the base project setup, and the code aware of wanting to connect to an Azure App Configuration resource let's actually create the resource in Azure. I am not going to re-write what is already 100% documented, so just follow the documentation at this link to create the Azure resource. If you are reading this blog post, I am assuming you are very familiar with creating resources in Azure and most likely even already have the resource generated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-app-configuration/quickstart-aspnet-core-app?tabs=core2x#create-an-app-configuration-store"&gt;https://docs.microsoft.com/en-us/azure/azure-app-configuration/quickstart-aspnet-core-app?tabs=core2x#create-an-app-configuration-store&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, to complete this example, &lt;strong&gt;make sure you create a new key value in Configuration explorer named Setting:Sentinel&lt;/strong&gt; with an empty value and empty category and empty label.  Also go ahead and &lt;strong&gt;create a new Feature Flag inside of the Feature Manager called LiveReload and turn the State On.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F_zdpsCt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Config-Explorer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F_zdpsCt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Config-Explorer.png" alt="Azure App Configuration Config Explorer" title="Azure App Configuration Config Explorer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fe-2g4tf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Feature-Manager.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fe-2g4tf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Feature-Manager.png" alt="Azure App Configuration Feature Manager" title="Azure App Configuration Feature Manager"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the resource is created, with the configurations mentioned above, we can grab the connection string from the Access Keys blade. Grab the primary or secondary connection string and copy it to your clipboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VczsFVWp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Access-Keys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VczsFVWp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Access-Keys.png" alt="Azure App Configuration Access Keys" title="Azure App Configuration Access Keys"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we are going to go back to powersell in your project and run the following command to place the connection string value as an Environment Variable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;$Env:ConnectionString = "connection-string-of-your-app-configuration-store"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, make sure you replace the value in the command from the Access Keys -&amp;gt; Connection String in the Azure Portal. This lines up with line 32 or so in your Program.cs file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 - Create a Feature Flag and Represent It in Code
&lt;/h3&gt;

&lt;p&gt;Most of the setup is now done and we can move on to coding. &lt;strong&gt;Create a folder in your project called Features and add a public enum named FeatureFlags&lt;/strong&gt; there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;BlazorFeatureFlags.Features&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Flags&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;LiveReload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Preview&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Make sure you define a flag with the same name as you made the Feature Flag in Azure. If you are following along you should have at least one named &lt;strong&gt;LiveReload&lt;/strong&gt;. You can have a few others if you like. But these flags should match up with the names you see as keys in the Feature Manager in the App Configuration resource.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 - Modify Your Razor Component to use the new Feature Flag
&lt;/h3&gt;

&lt;p&gt;This is the last step. We are going to now tell the home page of the Blazor app to use a feature flag through Azure App Configuration. Most examples you will see on Blazor talk about adding all the code in the main razor component file. I am not a fan of that. I like having the code behind the file in a .cs file to keep the C# away from the HTML. I know, old habits die hard. To do that create a new file named Index.razor.cs inside of the Pages folder in your application with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.FeatureManagement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BlazorFeatureFlags.Features&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;BlazorFeatureFlags.Pages&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Index&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ComponentBase&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IFeatureManager&lt;/span&gt; &lt;span class="n"&gt;FeatureManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;featureDisplay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;OnInitializedAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;FeatureManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsEnabledAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LiveReload&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;featureDisplay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;featureDisplay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I am keeping this really simple just to show the connection has worked between the Blazor app and Azure. I'm injecting the FeatureManager object into the razor component and then checking is the feature enabled in for the LiveReload enum flag we created.&lt;/p&gt;

&lt;p&gt;The very last step is to take that simple string property and add it on the front end file. &lt;strong&gt;Open up the main Index.razor file&lt;/strong&gt; and add in some html to show the property value. &lt;strong&gt;Save the new files you created&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Welcome&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SurveyPrompt&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"How is Blazor working for you?"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Feature&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Azure&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;@featureDisplay&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then simply &lt;strong&gt;build and run the project&lt;/strong&gt; and you should see the word "true" show up. By now you should be able to run your application and see the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yTmazkMq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Blazor-Azure-App-Configuration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yTmazkMq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Blazor-Azure-App-Configuration.png" alt="Blazor Azure App Configuration" title="Blazor Azure App Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Make the Blazor App Editable with Kentico Kontent
&lt;/h3&gt;

&lt;p&gt;I am not a huge fan of having content directly in the code base, as I am a .NET CMS enthusiast. So if you are at all interested in checking out &lt;a href="http://kontent.ai/?utm_source=blazorazureappconfig&amp;amp;utm_medium=mvp_27116&amp;amp;utm_campaign=extended_trial"&gt;&lt;strong&gt;Kentico Kontent&lt;/strong&gt;&lt;/a&gt;, a headless cms that can make your apps editable, this section is for you. You can &lt;a href="https://kontent.ai/?utm_source=blazorazureappconfig&amp;amp;utm_medium=mvp_27116&amp;amp;utm_campaign=extended_trial"&gt;sign up for a free Kentico Kontent developer account&lt;/a&gt; quite easily to check it out.&lt;/p&gt;

&lt;p&gt;I created a simple Page content type in Kontent to represent the home page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iigRjvqY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Kentico-Kontent-Content-Item.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iigRjvqY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Kentico-Kontent-Content-Item.png" alt="Kentico Kontent Content Item"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the the &lt;a href="https://github.com/Kentico/kontent-generators-net"&gt;&lt;strong&gt;Kontent Model Generator&lt;/strong&gt;&lt;/a&gt; I created a C# class that represented the &lt;strong&gt;Page content type&lt;/strong&gt; and placed the two files it generates (&lt;strong&gt;Page.cs&lt;/strong&gt; and &lt;strong&gt;CustomTypeProvider.cs&lt;/strong&gt;) into a &lt;strong&gt;Models&lt;/strong&gt; folder in our application. To do that you install the &lt;strong&gt;Kontent Model Generator global tool&lt;/strong&gt; and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;KontentModelGenerator --projectid &amp;amp;lt;&lt;/span&gt;your-project-id&amp;amp;gt&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now to use the content in Kontent for your Blazor app, simply add in the NuGet package for Kontent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;dotnet add package Kentico.Kontent.Delivery
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then add in configuration for the DeliveryClient options into your &lt;strong&gt;appSettings.json&lt;/strong&gt; file as the documentation for Kontent states.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logging&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LogLevel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Information&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microsoft&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Warning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microsoft.Hosting.Lifetime&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Information&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DeliveryOptions-Production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ProjectId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bfa07c03-your-key-here-3eadfb798&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PreviewApiKey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GMpaUsCDs3alio8sbwmlBGf------8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WaitForLoadingNewContent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DeliveryOptions-Development&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ProjectId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e452de54-your-key-here-e53bb287ae3d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PreviewApiKey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ew0KICAiYWxnIjogIkhTMjU2IiwNC----o&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WaitForLoadingNewContent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AllowedHosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Modify Startup.cs again to use the Delivery SDK for Kontent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRazorPages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddServerSideBlazor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFeatureManagement&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDeliveryClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DeliveryOptions-Production"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDeliveryClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"development"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DeliveryOptions-Development"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WeatherForecastService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I added two clients so I can actually tie an Azure Feature Flag to tell the app to use either the Production environment in Kontent or the Development environment (&lt;strong&gt;a new feature of Kontent&lt;/strong&gt;) by simply enabling or disabling a flag in Azure.&lt;/p&gt;

&lt;p&gt;To use the Kontent Delivery Client I had to modify Index.razor.cs to look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.FeatureManagement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BlazorFeatureFlags.Features&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Kentico.Kontent.Delivery.Abstractions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BlazorFeatureFlags.Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;BlazorFeatureFlags.Pages&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Index&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ComponentBase&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IDeliveryClientFactory&lt;/span&gt; &lt;span class="n"&gt;DeliveryClientFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IFeatureManager&lt;/span&gt; &lt;span class="n"&gt;FeatureManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;featureDisplay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt; &lt;span class="n"&gt;homePageContentItem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;OnInitializedAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;environmentName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;FeatureManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsEnabledAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PreviewInApp&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;environmentName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"development"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;//Get a DeliveryClient object from the DeliveryClientFactory&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;deliveryClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DeliveryClientFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;environmentName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;//Get our home page item if type Page from Kontent&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;itemResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;deliveryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetItemAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"home_page"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;//Assume we found it, and cast it to a strongly typed model of Home&lt;/span&gt;
            &lt;span class="n"&gt;homePageContentItem&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;itemResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CastTo&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;FeatureManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsEnabledAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LiveReload&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;featureDisplay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;featureDisplay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And then the front end Index.razor file to use the new content fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;

&lt;span class="nf"&gt;@if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;homePageContentItem&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Loading&lt;/span&gt; &lt;span class="p"&gt;...&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;@homePageContentItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;MarkupString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;homePageContentItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SurveyPrompt&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"How is Blazor working for you?"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Feature&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Azure&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;@featureDisplay&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And now I can switch to either my production Kontent environment or development Kontent environment to have a Headless CMS connected to my Blazor app.&lt;/p&gt;

&lt;p&gt;Here is the content in Kontent and how it shows up on the website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Axab29UY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Kontent-Blazor-App-Home-Page.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Axab29UY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Kontent-Blazor-App-Home-Page.png" alt="Kontent Blazor App Home Page" title="Kontent Blazor App Home Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z1eBLdZF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Blazor-App-Home-Page.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z1eBLdZF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Blazor-App-Home-Page.png" alt="Blazor App Home Page" title="Blazor App Home Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if I toggle the Feature Flag in Azure App Configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v32kbVzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Feature-Switch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v32kbVzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Azure-App-Configuration-Feature-Switch.png" alt="Azure App Configuration Feature Switch" title="Azure App Configuration Feature Switch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In less than a minute I can refresh my page and see the development content:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n0ETl5JP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Blazor-App-Dev-Home-Page.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n0ETl5JP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/mbv/media/uploads/2020/Blazor-App-Dev-Home-Page.png" alt="Blazor App Dev Home Page" title="Blazor App Dev Home Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's pretty cool for less than an hour of more work.&lt;/p&gt;

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

&lt;p&gt;There you have it. You have seen how easily it is to get dynamically reloaded configuration at runtime into your Blazor Server application using Azure App Configuration. If you are creating .NET Core of .NET 5.0 apps this could be a useful tool in your developer tool belt.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>blazor</category>
      <category>azure</category>
      <category>kenticokontent</category>
    </item>
    <item>
      <title>Kentico Rocks Episode #034 - How Easy Is It for a Beginner to Build a GatsbyJS / Kentico Kontent Site?</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sun, 05 Jul 2020 15:55:45 +0000</pubDate>
      <link>https://forem.com/bizstream/kentico-rocks-episode-034-how-easy-is-it-for-a-beginner-to-build-a-gatsbyjs-kentico-kontent-site-1d7g</link>
      <guid>https://forem.com/bizstream/kentico-rocks-episode-034-how-easy-is-it-for-a-beginner-to-build-a-gatsbyjs-kentico-kontent-site-1d7g</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this episode of &lt;strong&gt;Kentico Rocks&lt;/strong&gt; , Adam Amran, Product Designer at &lt;a href="https://kontent.ai/?utm_source=kenticorocks34&amp;amp;utm_medium=mvp_27116&amp;amp;utm_campaign=extended_trial"&gt;Kentico Kontent&lt;/a&gt;, joins host Brian McKeiver. They talk about Adam's experience with creating a &lt;strong&gt;GatsbyJS&lt;/strong&gt; site backed by the &lt;strong&gt;Kentico Kontent Headless CMS&lt;/strong&gt; as a new programmer. Adam and Brian go into the story of how Adam needed to create a new website for a side project he was working on, &lt;a href="http://untools.co"&gt;Untools.co&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Being a Designer by trade, Adam wasn’t quite sure where to start as he only had basic programming knowledge of HTML, CSS, and JavaScript. After forming the new idea for the project, creating his content model in Kontent, and settling on GatsbyJS as the right solution, the new site came together quickly and is now blazing fast.&lt;/p&gt;

&lt;p&gt;Listen to the episode to find out what pitfalls happened along the way, and why Adam us now very happy with the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch Now
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/98dD23RjkZY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  In This Episode
&lt;/h3&gt;

&lt;p&gt;Brian McKeiver and Adam Amran discuss the following topics in Kentico Rocks podcast episode #34:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Kentico Kontent as a headless cms&lt;/li&gt;
&lt;li&gt;  Getting started building a GatsbyJS site from scratch&lt;/li&gt;
&lt;li&gt;  Why WebFlow was not the answer for Designers looking to build a dynamic site&lt;/li&gt;
&lt;li&gt;  How Easy is it get started with Kontent and GatsbyJS as a beginner&lt;/li&gt;
&lt;li&gt;  Adam's one thing he would do differently knowing what he knows now (hint: React basics)&lt;/li&gt;
&lt;li&gt;  A little bit about Adam's side project at UnTools.co&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related Links to this episode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://kontent.ai/?utm_source=kenticorocks34&amp;amp;utm_medium=mvp_27116&amp;amp;utm_campaign=extended_trial"&gt;Kentico Kontent as a Headless CMS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.gatsbyjs.org/"&gt;GatsbyJS.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/Kentico/gatsby-starter-kontent"&gt;Kentico Kontent GatsbyJS Starter Template&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.gatsbyjs.org/docs/sourcing-from-kentico-kontent/"&gt;Kentico Kontent Source Plugin for GatsbyJS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://untools.co"&gt;UnTools.co&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also listen to the previous episode of Kentico Rocks where I talk about &lt;a href="https://www.mcbeev.com/Blog/June-2020/Kentico-Rocks-33-Net-Core-Xperience-Beta-3"&gt;The .NET Core Future of Kentico Xperience 13 with Sean Wright&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>kenticokontent</category>
    </item>
    <item>
      <title>Kentico Rocks Episode #033 - The .NET Core Future is Now For Kentico Xperience 13</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sat, 27 Jun 2020 14:27:51 +0000</pubDate>
      <link>https://forem.com/bizstream/033-the-net-core-future-is-now-for-kentico-xperience-13-3o92</link>
      <guid>https://forem.com/bizstream/033-the-net-core-future-is-now-for-kentico-xperience-13-3o92</guid>
      <description>&lt;p&gt;In this episode of the &lt;strong&gt;Kentico Rocks Podcast&lt;/strong&gt; , our host &lt;a href="https://www.mcbeev.com"&gt;Brian McKeiver&lt;/a&gt;, Co-Owner at &lt;a href="https://www.bizstream.com"&gt;BizStream&lt;/a&gt;, is joined by &lt;a href="https://dev.to/seangwright"&gt;Sean G. Wright&lt;/a&gt;, Kentico MVP at &lt;a href="https://www.wiredviews.com/"&gt;WiredViews&lt;/a&gt;. Brian and Sean discuss the recently released &lt;a href="https://devnet.kentico.com/download/beta/"&gt;beta 3 of Kentico Xperience&lt;/a&gt;, the digital experience platform offering from &lt;a href="https://www.kentico.com/"&gt;Kentico&lt;/a&gt;. They get into how the newest release will allow for full support of .NET Core, the most modern released version of .NET.&lt;/p&gt;

&lt;p&gt;Sean and Brian also talk about what this technology shift means for MVC 5 or WebForms developers who are not yet well versed in .NET Core. Listen to the episode to gain some tips and insights on why .NET Core is different, and how to get started in Kentico and .NET Core if you are still in the Portal Engine of MVC 5 world.&lt;/p&gt;

&lt;p&gt;Remember, &lt;a href="https://open.spotify.com/show/4LDuqV2NKush3NJqNP4rO6"&gt;you can subscribe to the Kentico Rocks podcast on spotify&lt;/a&gt;. Click on over to that if you haven't start following Kentico Rocks yet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/show/4LDuqV2NKush3NJqNP4rO6"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zHGZ5eY2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2018/spotify-podcast-badge-blk-grn-165x40.png" alt="Listen on Spotify to Kentico Rocks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch Now
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Wp9Oyyeh0i8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  In This Episode
&lt;/h3&gt;

&lt;p&gt;Brian McKeiver and Sean Wright discuss the following topics in Kentico Rocks podcast episode #33:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Kentico Xperience 13 Beta 3 and .NET Core&lt;/li&gt;
&lt;li&gt;  Benefits of .NET Core compared to previous .Net frameworks&lt;/li&gt;
&lt;li&gt;  How Xperience supports .NET Core better than ever&lt;/li&gt;
&lt;li&gt;  What new developers need to know about the switch to .NET Core from MVC 5&lt;/li&gt;
&lt;li&gt;  How .NET Core allows for more flexibility and freedom for your team&lt;/li&gt;
&lt;li&gt;  A few business benefits of .NET Core, like deployment to Azure Web Apps based on Linux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related Links to this episode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://devnet.kentico.com/download/beta/"&gt;.Kentico Xperience Beta 3 Download&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.to/seangwright/kentico-xperience-13-beta-3-page-builder-view-components-in-asp-net-core-onm"&gt;Sean's Dev.To Kentico Blog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/get-started?tabs=windows"&gt;Getting Started with .NET Core Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Previously on Kentico Rocks
&lt;/h3&gt;

&lt;p&gt;You can also listen to the previous episode of Kentico Rocks where I talk about &lt;a href="https://dev.to/Blog/June-2020/032-Whats-New-in-Net"&gt;What's New in .Net, Azure Static Web Apps, and Kentico Kontent&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kenticoxperience</category>
      <category>dotnetcore</category>
      <category>aspnet</category>
      <category>kentico</category>
    </item>
    <item>
      <title>The Latest on Kentico 13 Beta 3 or Should I Say Kentico Xperience</title>
      <dc:creator>Brian McKeiver</dc:creator>
      <pubDate>Sun, 14 Jun 2020 15:53:22 +0000</pubDate>
      <link>https://forem.com/bizstream/the-latest-on-kentico-13-beta-3-or-should-i-say-kentico-xperience-3keo</link>
      <guid>https://forem.com/bizstream/the-latest-on-kentico-13-beta-3-or-should-i-say-kentico-xperience-3keo</guid>
      <description>&lt;p&gt;This past Friday, I had a chance to sit down and chat with &lt;a href="https://xperience.io/"&gt;&lt;strong&gt;Kentico Xperience&lt;/strong&gt;&lt;/a&gt; Product Director, &lt;strong&gt;Michal Kadák&lt;/strong&gt; and Product Owner, &lt;strong&gt;David Komárek&lt;/strong&gt;. Our goal was to discus the Kentico EMS to Kentico Xperience re-branding from an insiders standpoint. But we spent most of our time on &lt;strong&gt;Kentico 13 beta 3&lt;/strong&gt;, including the reveal of long awaited release date of beta 3.&lt;/p&gt;

&lt;p&gt;Michal and David and I were actually trying to record the next episode of my &lt;a href="https://www.mcbeev.com/kenticorocks"&gt;&lt;strong&gt;Kentico Rocks podcast&lt;/strong&gt;&lt;/a&gt;. But, the technology gods frowned upon my &lt;a href="https://obsproject.com/"&gt;OBS&lt;/a&gt; abilities /skills. The audio recorded with such a bad echo that it is unusable. You'd think after 30 episodes or so I would have figured this out by now, but 3 audio streams was too much for me. I promise I'll have it correct next time. Yet, technology be damned. The content of the recording was so good, and the timing so right, I couldn't wait to get this information out to the Kentico community. Instead I have went with plan b, and I have turned the audio recording into this interview style blog post.&lt;/p&gt;

&lt;p&gt;Keep reading to find out David and Michal's thoughts on Kentico Xperience, what's included in Kentico 13 beta 3, and when you can get your hands on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kentico Xperience Interview
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fvOvuQ57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/81a149ed-b2a5-475b-bb7a-577b8da99163/Interview-Kentico-Xperience-Team.png.aspx%3Fwidth%3D819%26height%3D474" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fvOvuQ57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/getmedia/81a149ed-b2a5-475b-bb7a-577b8da99163/Interview-Kentico-Xperience-Team.png.aspx%3Fwidth%3D819%26height%3D474" alt="Brian McKeiver interviewing Michal and David from Kentico"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hi Michal and David. Thanks or joining me. Can you guys introduce yourselves and mention what what you do at Kentico?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks Brian, ok I will start. My name is Michal, Michal Kadak, the Product Director at Xperience. I think many of you know me, but if you don't know me, after being on Kentico Rocks I will be famous. At least I hope so. If you don't know me, you can find me on &lt;a href="https://twitter.com/MichalKadak"&gt;Twitter&lt;/a&gt; and on &lt;a href="https://www.youtube.com/channel/UC_CnV72OeDm-ukP3XSIzZ-g"&gt;YouTube&lt;/a&gt;. Basically I am David's boss [in a nutshell Michal is in charge of what makes it in and out of Kentico Xperience and the development roadmap], but David go ahead. &lt;/p&gt;

&lt;p&gt;Ok, my name is David, David Komerak. I am not famous at all like Michal is on social media, but I am the Product Owner in Xperience. But in the office, it is quite the opposite. If you come by the office I am happy to speak the truth on all things Kentico Xperience and answer any questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is this Kentico Xperience thing, David? What's the new name and why did Kentico make the change?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well there is a lot actually when you talk about re-branding. If you read some of the blog posts that &lt;strong&gt;Petr Palas&lt;/strong&gt;, Kentico CEO, published about &lt;a href="https://xperience.io/discover/blog/2020-05/accelerate-your-digital-transformation"&gt;Kentico Xperience&lt;/a&gt;, the whole industry is moving away from wcms or cms or web content management as a term. It's time to move to something that is more relevant to today's customers, and that is now known as a digital eperience platform. As you know Kentico EMS stands for enterprise marketing solution, we named it that several years ago because it was not just a CMS, it had extra digital marketing features even back then. Because of this we have decided to go with Kentico Xperience as the new name for the product.&lt;/p&gt;

&lt;p&gt;There is still some discussion on what is the short name for Kentico Xperience, esecially internally, but we have decided to go with KX as the short name, so if you guys want to shorten it, we think KX or KX13 works. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fantastic, that makes sense. I can tell you from the US Kentico Partner side, all of the feedback that I have heard has been good. Most of the US partners like the new name and aknowledge the market has shifted to DXP.&lt;/strong&gt; [Reader note: If you want to know more about Kentico Xperience you can read our post at the &lt;a href="https://www.bizstream.com/"&gt;BizStream&lt;/a&gt; blog at &lt;a href="https://www.bizstream.com/blog/may-2020/what-is-kentico-xperience"&gt;What is Kentico Xperience&lt;/a&gt;.]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Michal, How is Kentico 13 coming along? We've had a taste of it with the first two betas and want more.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With beta 3 our focus is on Page Builder within MVC Core, Form Builder was already there on MVC Core, so we wanted to finish the Page Builder. We see these as the most important parts before the finishing the Xperience 13 product. The stress is on this MVC Core support, we really want the feeback on where ASP.Net Core support is going with Kentico. This is key, because we won't have a ton of time after beta 3. So the Page Builder, Form Builder, and other aspects of MVC Core support is huge to us right now. We want to really get a feedback around these functionalities so we know that if there is something not as good as it should be, we have time to make it better before the actual release. We only have a very limited scope with what we can do after this release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'm excited about MVC Core as well. I've definitely got my hands wet with with Kentico 13 beta 1 and beta 2. MVC Core as an agency and as a group of developers is huge, it is the future of .Net for sure. I know that's what most developers want to know about I'm also excited about what Page Builder can do in Core.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jfxubzfj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-Interview-2020.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jfxubzfj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-Interview-2020.png" alt="Kentico Xperience Interview 2020"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Michal, Can we speak to routing at all in MVC Core for Kentico Xperience?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is correct, that is the last thing we have to do around the MVC Core epic because the router is still under development. We have to wait until the router is dev complete in MVC 5 before we finish it in MVC Core. We are still building it in Kentico Phoenix for the first time. That's the reason why it wasn't in the beta 2, and not available yet. Routing should be available in the beta 3 release now when it comes out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I think that the new routing support in Kentico 13 is amazing because no matter your development style or stack, you will be able to have routing support. It doesn't matter if it is MVC 5 or .Net Core. Maybe even the &lt;a href="https://www.mcbeev.com/Blog/March-2020/Net-5-with-Kentico-13-Beta-2"&gt;future of .Net 5 and Kentico&lt;/a&gt; will just work as well. &lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; In the Phoenix_Milestone_2 beta 2 release download zip, there is a set of fantastic documentation in the Dynamic Routing folder about how Content Tree based routing is going to work in Kentico Xperience 13. I highly recommend reading it. Or since it is public knowledge, you can download the docs right here as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.mcbeev.com/MBV/media/uploads/2020/Content-Tree-based-Routing.pdf"&gt;Content Tree based Routing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.mcbeev.com/MBV/media/uploads/2020/Enabling-Alternative-URLs.pdf"&gt;Enabling Alternate Urls&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.mcbeev.com/MBV/media/uploads/2020/Managing-Page-URLs.pdf"&gt;Managing Page Urls&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.mcbeev.com/MBV/media/uploads/2020/Page-Types.pdf"&gt;Page Types&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Is the main goal of have the third beta be the last beta? Or will there be a fourth beta?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main goal of the beta release is to gain feedback. So it is important for us to do that when it is early in the year. It is kind of tricky to have another beta that is a preview right before the complete solution. In fact we may be able to give you everything soon around the fall Kentico Connection event, but we are not sure yet. Every year we have this discussion and have arguments around is this the right move or not. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;David, Can you tell us how to give feedback on beta releases? How can we be impactful?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thank you for that question! We have published several betas over the years. Sometimes the feedback has been quite nice, but sometimes we provide a download of a beta and receive hardly no feedback. Sometimes we don't get any feedback at all. In fact, with the Milestone two beta, we have had very sporadic feedback to almost no feedback. Feedback is crucial to Kentico. If we don't receive that feedback than we don't know if the solution works well for your agency or not. If we don't know about it, then we don't know if we are doing it the wrong way.&lt;/p&gt;

&lt;p&gt;Our marketing team is going to provide a feedback form to collect your feedback on beta 3. In our feedback form, we provide testing scenarios for developers and even for some of the marketing teams to get us feedback. Please share it, please use the testing scenarios! We expect to you to share it. We want and need feedback to make the product better based on this feedback.&lt;/p&gt;

&lt;p&gt;[Michal adds] I know that I heard that, if you don't fill out the feedback form, Santa does not bring you any presents under the tree this year. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Haha, true Michal. Kentico community if you are reading this please fill out that feedback form on Kentico Xperience beta when it comes in your inbox!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BU5rQzAj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-Interview-2020-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BU5rQzAj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-Interview-2020-2.png" alt="Kentico Xperience Interview 2020 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I didn't tell you this ahead of time, because I want your honest opinion here. You both have worked on and at Kentico for a long time as we know. What is your most favorite thing you have gotten to do on the product or at the company or in the Kentico community, and what is something you don't like about it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;[David leads with] Well I can tell you something I don't like right away. I hate having to cut scope as a release comes near. We receive a lot of requests for new features, do different performance improvements, tweak existing features etc. etc.. I want to do it all! My least favorite part is seeing the awesome prototypes for new features that we create but then having to cut them out of the scope because we just run out of time. But the thing is you always have to prioritize. &lt;/p&gt;

&lt;p&gt;While foosball with my colleagues is great, and 7 cups of coffee a day is great, my favorite part is being able to talk to all of the Kentico partners and clients around the world and see them, see their offices, and just meet them all. Talking to all of the developers and see what they can build with the Kentico product is amazing, that is my most favorite part.&lt;/p&gt;

&lt;p&gt;Well if it is my turn [Michal says], I am going to be even more specific. My favorite this was the &lt;a href="https://www.youtube.com/watch?v=IqYSL7_p3Ts"&gt;&lt;strong&gt;Raptor world tour&lt;/strong&gt;&lt;/a&gt;. This action that we did, the whole world tour, the t-shirts, the logos, the videos and everything around it was the most amazing thing I have done while at Kentico. For example surfing during that tour was amazing. Of course within the product there are so many amazing things that happened as well. &lt;/p&gt;

&lt;p&gt;One thing I can tell you that I don't like is that if I was a sales guy, I wouldn't want to sell and I don't like having to try and sell it. I don't like having to justify getting more around the pricing changes or licenses changes going on without giving out the whole product. I'd love to give everyone in the world the whole solution all the time. I wish we could give it all and not have to worry about the pricing and licensing that goes with it.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wow thank you guys, those were some great answers and I couldn't agree more. I know the world tour and all of &lt;a href="https://www.mcbeev.com/Blog/October-2019/Kentico-Rocks-Podcast-Episode-25"&gt;Kentico Connection events&lt;/a&gt; are a highlight for me and many others as well.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lastly, and most importantly, do you have any updates on the actual Kentico 13 Beta 3 Release Date, Michal?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next beta will be will actually be released in one, two, three, ... four more days actually, &lt;strong&gt;Tuesday June 16th, 2020 is our target for Kentico 13 beta 3&lt;/strong&gt;. [David chimes in here with this date is not 100% in stone yet, it could go live on the 17th as well, some of the links that will come in the newsletters will come little later because obviously we don't want to spam everybody like at the first date or the release but so little longer than that for some for the general public]. Even with a new website, we should be able to distribute it in the same way we always have.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In case you don't know how to get the latest Kentico Xperience beta, you can download it at the &lt;a href="https://devnet.kentico.com/download/beta/"&gt;Xperience DevNet page&lt;/a&gt; (free account will be required).&lt;/strong&gt; &lt;/p&gt;

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

&lt;p&gt;A big thanks to Michal and David for joining me on our discussion about the Kentico EMS to Kentico Xperience re-brand and the state of Kentico 13 Beta 3. Next time I promise to have the audio quirk figured out and share the whole recording!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KMXd_CTH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-Interview-Conclusion.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KMXd_CTH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.mcbeev.com/MBV/media/uploads/2020/Kentico-Xperience-Interview-Conclusion.png" alt="Kentico Xperience Interview Conclusion"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kentico</category>
      <category>kenticoxperience</category>
      <category>dotnetcore</category>
      <category>cms</category>
    </item>
  </channel>
</rss>
