If you're familiar with web development, you'll know for sure React. This framework, built by Facebook, is becoming more and more popular to build client-side web experiences. Unlike other frameworks like Vue.js or Angular, React focuses only on the View component of a web application. It isn't a fully fledged framework like jQuery or Angular, which have an opinion on everything and, as such, they provide lot of features to perform all the kind of tasks, from HTML templates to APIs to handle HTTP requests. You need to rely on plain old JavaScript (or TypeScript, if you prefer) or on 3rd party libraries to achieve these goals.
What makes React peculiar (and not so easy to understand at the beginning if you're coming from traditional client-side development for Windows, like me) is the different development approach. You may be used to patterns like MVC or MVVM, which goal is to separate the UI from the business logic so that you can make your application easier to test, maintain and evolve. React, instead, being focused only on the View, is based on the concept ofcomponents, which are the different pieces that compose a page. Every component is independent from the other and it includes both the UI and the logic to handle the various events that it can trigger.
Since code is easier to understand than words, here is how a typical React component looks like:
As you can see, the component defines both the UI and the logic to handle the events associated with it:
Therender()function is the one which declares the UI that this component will display.
TheshowAlert()function is triggered when the user clicks on the button declared in the UI.
ThecomponentDidMount()function is part of the component's lifecycle and it's triggered when the component has been rendered and it's ready to work.
The UI might look like HTML, but it's actually defined using a special language calledJSX, which is based on XML and it allows to declare your UI with JavaScript. It may sound blasphemous, but the goal is to go past the standard templating approach used by other frameworks, which is good when you just want to display some data, but it has its limitations when you want to do something more complex, like displaying or hiding something based on a specific condition. In the previous code you can see an example of this approach. In jQuery or another similar framework, you would need to use an API to get a reference to the button and then hook up the event. In React, instead, we can declare it just inline, by subscribing to theonClickevent and by specifying the name of the function to invoke inside curly brackets.
<div>and<button>may look like plain HTML tags, but they're actually not. You can notice it, for example, by the usage of two attributes,classNameandonClick, which don't exist in standard HTML. React will take care of translating these JSX controls into the corresponding HTML ones and to handle the various state changes. To make thing simpler, the JSX controls in React resembles as much as possible the HTML ones, so the syntax will be very familiar to you.
Due to the growing popularity of React, Facebook has decided to extend the framework to support mobile development with the introduction of React Native. This was made possible by the fact that one of the core features offered by React isabstraction. React itself doesn't offer too many built-in features which are tight to a specific platform, but it leverages arender targetto make sure that the View is rendered in the proper way. In the previous examples, React used a render target that can turn JSX into plain HTML. As such, React Native in nothing more than React with a different render target, which turns JSX into mobile controls.
React Native, from a mobile development experience point of view, can be seen as a mix between the classic Xamarin approach and the Xamarin Forms one. Like Xamarin Forms, it shares the opportunity of building truly native applications. React Native, in fact, doesn't use a WebView to render the HTML and JavaScript, like other web based technologies like Cordova. The various JSX controls are rendered using the corresponding native controls for Android or iOS, making the UI and the user experience coherent with the rest of the operating system. Xamarin Forms does the same, but by leveraging XAML as a markup language. However, like classic Xamarin, the goal of React Native isn't really to write an application once and run it everywhere, but rather allowing a team to build mobile applications using the same knowledge and sharing the same libraries. You will find out, in fact, that React Native includes many controls which are cross-platform (likeTextorImage), but also many others which are specific for Android and iOS and that can't be used in a cross-platform way.
React Native includes a render target for iOS and Android but, since BUILD 2018, Microsoft has started to work on a render target for Windows. At BUILD 2019, however, Microsoft has announced a rewrite of the framework from C# to C++, with the goal to get better performances and to be better aligned with the core react-native implementation, which is built in C++ as well. The technology behind this framework is the Universal Windows Platform. React Native for Windows creates a new UWP project and the various JSX controls are rendered using native controls from the Universal Windows Platform and, in the future, from the WinUI library.
The framework is really flexible and it opens up many opportunities for Windows developers:
You can build UWP applications from scratch using only React Native.
You can integrate React Native components inside native UWP applications, allowing you to mix UWP controls with React Native controls.
You can integrate React Native components inside WPF or Windows Forms applications, by leveraging XAML Islands, the technology which allows to render UWP controls inside Win32 applications.
In this blog post we're going to explore all these options. However, the purpose of this post isn't to be a comprehensive overview of React Native. I will give for granted that you're already familiar with this technology. If it's not your case and you want to learn more, you will find lot of tutorials and documentation onthe official website. You can also start fromthe React website. The main concepts, in fact, are exactly the same between the two platforms, with the only difference that React outputs HTML, while React Native native controls.
Getting started
Let's start by setting up our computer with all the requirements needed to build React Native applications for Windows. The first one is Visual Studio 2019 with the following workloads installed:
Universal Windows Platform development (make sure to enable theC++ (v142) Universal Windows Platform toolsoption)
Desktop development with C++
Make sure also to check, in the Indivual components section, the following ones underCompilers, build tools and runtimes:
MSVC v141 - VS 2017 C++ x64/x86 build tools (v14.16)
MSVC v141 - VS 2017 C++ ARM build tools (v14.16)
Now let's move to the "web tools". The first one isNodeJS, the JavaScript runtime built on top of the Chrome JavaScript engine. Everything around React Native (the core, libraries, etc.) is distributed as packages through the popular NPM package manager, so you'll need the NodeJS runtime to leverage it. You can get it from theofficial website.
Optionally (but highly suggested) is to installYarn, a package manager for Node. As we're going to see in the next steps, it will help us a lot in setting up the whole environment. You can download it fromthe official website.
Last but not the least, if you want to debug your application you will need to leverage the Developer Tools included in Chromium. Theofficial guidance on GitHubspecifically invites you to install Chrome, but alsothe new Edge based on Chromiumworks like a charm.
That's it! Now we can start to create our first React Native project. You can refer to the guidance providedon the GitHub repository. I won't repeat them here since the steps might change in the future (for example, the targeted React Native version has changed multiple times since the project started).
The last tool I'm going to mention isn't exactly a requirement, but a strong suggestion. In order to build your React Native application you will need to use an IDE. Sure, you can use also Notepad, but there are better options out there, likeVisual Studio Code, which offers alsoan extension for React Nativewhich gives you IntelliSense, debugging, etc.
Make sure to have plenty of space on your hard disk. Since the React Native implementation for Windows is based on C++, the compilation artifacts will be quite big, so an average project's folder can easily reach the size of 5-6 GB.
Running your React Native for Windows project
The easiest way to launch your React Native for Windows project is to run the following command from your project's folder:
react-native run-windows
In the past there have been some issues that prevented this command to work properly. Most of them should be fixed now but, in case you're still hitting one of them, here is an alternative procedure:
Open in File Explorer thewindowsfolder inside the folder which contains your React Native project.
Open the Visual Studio solution you'll find there. The name of the solution will match the name of the project.
The solution is made by different projects, all based on C++. The main one (which contains the actual application to deploy) is the one which name matches with the React Native project's name. In our case, it'sTodosFeed.
Compile the whole solution (again, it will take a while because of the C++ projects), then right click on the UWP project and choose Deploy. Make sure that, in the configuration dropdown, you choose an architecture which is suitable for your computer, like x86 or x64. The default value, in fact, will be ARM.
You should always launch the UWP project either from the Start menu or by pressing CTRL-F5 in Visual Studio, without attaching the debugger. The reason is that, in this scenario, the UWP app is just the "host" of the React Native application, so the real debugging must be done on the React code.
Before launching the application, however, you have to manually run the React packager by typing the following command in the project's folder:
yarn start
What is theReact packager? It takes care of a few important tasks, like translating JSX into code that the target platform will understand and combining all your JavaScript into a single file. When you're in development mode, the command prompt with the React packager must always be up & running. This way, every time you make a change to the code of your React Native application, the packager will automatically create a new bundle and refresh the application.
Once the packager is ready, it should automatically launch Chrome on the local server which is used to serve the React application. If it doesn't happen, you can open it manually (or you can launch Edge based on Chromium) and open the URL http://localhost:8081/debugger-ui/. Then you can press F12 or CTRL-SHIFT-J to turn on the developer tools, which will help you to see any error that might arise in the React Native application. This operation is very important because, if the local development server isn't up & running, the UWP application won't be able to render the React Native content and you will get an error like the following one:
Now that both the packager and the development server are up & running, you can launch the UWP application you have deployed. If you did everything well, you will see the packager starting to serve the various files in the command prompt and, in the UWP application, you will see the default React Native starter template.
Using React Native to build a full UWP application
This is the simplest task, since with all the steps we have taken so far we have already created a full UWP application based on React Native. Let's try to create a more realistic one compared to the default template, which we're going to reuse for the next scenarios. As already mentioned, the UWP app is just the host of the React Native one, so to start actually coding you need to open the React Native project's folder with Visual Studio Code. Just right click on the folder and chooseOpen with Visual Studio Codeor, alternatively, if you're still in the command prompt, type:
code .
As mentioned, the default page you see in the application is defined in theApp.jsfile. Let's replace the default content with a simple application that displays a list of to-dos, downloaded from a REST service. This will be the final look & feel:
Nothing too complex, but enough to play with the React Native and Windows capabilities.
Let's start by building a component that will display the list of to-dos. Create a new folder in the project calledcomponentsand, inside it, create a file calledTodosList.js.
We're going to use four controls from React Native:
ActivityIndicator, to display a loading icon when the data is being downloaded from the REST service.
View, which is the basic container of React Native. Typically, it's the main entry point which contains, as child, the other controls. Think of it like thePagecontrol in XAML.
FlatListto display the list of to-dos we have downloaded.
This is the basic skeleton, since the component doesn't actually include any data or any action. The component is defined using the standard React Native syntax based on ES6, the latest definition of the JavaScript language. We create a new class which extends theComponentone, which is provided by the React library. The component defines arender()method, which include the JSX that represents the UI. The currentViewcontains anActivityIndicatorand aFlatListwhich, however, we need to populate with some data.
First we need to introduce one of the most important concepts in React,state. It's a key - value pair collection where we can store data that must be displayed by the user interface. The nice bonus of the state management in React is that it automatically keeps the UI in sync. Whenever you're going to change one of the values stored in the state, every UI component connected to that value will be automatically updated. If you're a XAML developer, this concept should be familiar to you since it's similar to binding.
We define the state in the constructor of the component and we setup two properties: one calledtodos, which is an array that will store our collection of to-dos; the other one is calledloadingand it's a boolean we're going to use to hide / display the loading indicator.
Now that we have a place where to store our to-dos, we need to download them when the component is rendered. To achieve this goal we leverage thecomponentDidMount()method, which is one of the many available functions to handle the lifecycle of a component. Inside the function we use the JavaScriptfetch APIto download the list of to-dos from a REST service. We're usinghttps://jsonplaceholder.typicode.comas endpoint, which is a service that returns fake data for testing and development purposes. The fetch API is asynchronous, so we use the async / await approach (supported by all the modern browsers nowadays) to handle it. In the end we convert the response into a JSON object by calling another asynchronous method,json(), and we store the result inside thetodosobject in the state. We also change the value of theloadingproperty, so that we can hide the loading indicator.
You can notice two things:
To set the state, we are using thesetState()method instead of setting it directly. This is required to enable the sync, otherwise the UI won't be notified that the value of one of the properties has changed.
We use theslice()method to take only the first 20 items from the result.
Now that we have some real data inside the state, we can populate the UI controls we have previously created:
We connect theanimatingproperty of theActivityIndicatorcontrol to theloadingproperty stored in the state (this.state.loading). This way, the loading indicator will be displayed when we start the operation and hidden when the data from the REST service has been downloaded.
We connect thedataproperty of theFlatListcontrol to thetodosproperty stored in the state (this.state.todos). This way, the list will be automatically populated with all the items that have been downloaded from the REST service.
We use therenderItemproperty of theFlatListcontrol to define how every single item of the list should be rendered. We express this property using a lambda expression, which gives us a reference to a single to-do in the list. For the moment we use a simpleTextcontrol and, inside it, we display the value of thetextproperty of the to-do. We can understand where this property is coming from by openingthe URLof the REST API in a browser or in a tool likePostman. We will see that each item inside the collection has the following properties:
userId
id
title
completed
As such, from theitemobject we can directly access to each of them.
Now that we have defined theTodosListcomponent, we need to display it in replacement of the original React Native template. Move to theApp.jsfile and, inside the class which defines the main component, change therender()method to:
That's it! Now make sure that the React packager is still up & running and that Edge / Chrome is open on the developer tools. The UWP application should update itself and you should see the list of to-dos being downloaded and rendered:
The controls we have defined using JSX have been translated into native UWP controls:
Textis now aTextBlock
ActivityIndicatoris now aProgressRing
FlatListis now aListView
The nice benefit of the live debugger is that you won't have to redeploy the UWP application every time you make a change. Just change something in the React Native code in Visual Studio Code, hit save and the content of the UWP app will be reloaded to display the updates.
That's it! We have our first React Native application running in Windows as a full UWP application!
Embedding the React Native component inside a UWP app
Let's move to the next step and see another scenario. What if we want to use the React Native component we have just built not as part of a full React Native application, but inside an existing UWP application? You may have a UWP application already in development, but you may want to integrate a React Native component built by the mobile team for the Android and iOS versions of the same app.
Let's start! The first step is to move the React Native component we have built before from a full UWP app to a custom control, that can be reused in other UWP applications. Open the solution created by the React Native for Windows CLI (you'll find it inside thewindowsfolder of your project). Then right click on it and chooseAdd โ New projectand select theWindows Runtime Component (Universal Windows)template:
In this case I'm building a C# component since it's the language I'm most familiar with. However, you could use the C++ template as well since, other than setting up the React Native infrastructure, we aren't actually going to build something. All the content displayed in this control will be provided by the React Native implementation.
Feel free to delete the default class that is included in the project, then right click on it and chooseAdd โ New item. PickUser controlfrom the list and give it a meaningful name, likeTodosFeedControl.xaml.
Now we need to include inside the newly created user control the React Native for Windows initialization. As first thing, right click on the project, chooseAdd โ Referenceand pick up from the list the project calledReactUWP.
Now that the React Native for Windows runtime is referenced, we need to add in the XAML file the control which will host the React Native application. First, let's declare the relevant namespace in user control definition:
xmlns:react="using:react.uwp"
Then, inside the mainGrid, you need to add aReactControl, which is part of the namespace you have just declared:
This is boilerplate code to initialize React Native for Windows. The only relevant parts to highlight are the two constants declared at the top:
JSFILENAMEdefines the name of the JavaScript file which contains the starting point of the React Native app, without the .js extension. In our case, it's theindexfile.
JSCOMPONENTNAMEdefines the name of the component which acts as a starting point of the application. This string must match the name of the project; in our case it'sTodosFeed.
That's it! Now we have a component that we can leverage in a full UWP application. Let's try this but, instead of using a basic UWP app, let's use a real one, to make things more interesting. We're going to use theXAML VanArsdel Inventory Sample, which is an open-source project developed by Microsoft to showcase the usage of the latest and greatest XAML controls in a real product.
As first step, clone or download the project on your computer, then open theInventory.slnsolution. Now we need to add a reference to the user control we have just created. However, since the React Native for Windows implementation isn't stored in a library or in a NuGet package, we'll need to reference also the same C++ project that are referenced by the UWP application which hosts React Native.
To keep things cleaner, I decided to create a solution folder (right click on the solution and chooseAdd โ New Solution Folder), where to store all the project related to React Native. Once you have created it, right click on it and chooseAdd โ Existing project. You will need to reference the following 5 projects, which are all stored in the folder that contains the React Native project.
Folly, which is included in thenode_modules\react-native-windows\Follyfolder.
ReactUWP, which is included in thenode_modules\react-native-windows\ReactUWPfolder.
ReactCommon, which is included in thenode_modules\react-native-windows\ReactCommonfolder.
ReactWindowsCore, which is included in thenode_modules\react-native-windows\ReactWindowsCorefolder.
All the previous project files will have the extension.vcxproj, since they're based on C++. The last and fifth project to reference is the one we have just created to store our user control. In my case, it's calledTodosFeed.Componentand it's stored in thewindowsfolder. This project's file extension will be, instead,.csproj, since it's based on C#.
This is how your solution should look like:
Now we have everything we need! We can right click on the Inventory.App project, choose Add โ Reference and select the TodosFeed.Component project. We're going to add our React Native component in the main dashboard of the application, along with the other widgets.
We can find the dashboard definition inside theViews โ Dashboard โ DashboardView.xamlfile. Let's first add the namespace of our user control:
xmlns:react="using:TodosFeed.Component"
The page contains aGridViewcontrol with different panels declared as children. Let's add a new one at the end:
That's it. The user control we have just added contains all the logic required to initialize the React Native component, so we don't need to do anything else other adding it to the XAML page.
Now it's time to build and deploy the application. Before doing it, however, we need to make sure that the React packager is up & running, otherwise the React Native component won't be rendered. As such, make sure that you have launched theyarn startcommand on the React Native project and that your browser is opened on thehttp://localhost:8081/debugger-ui/URL.
If you have done everything correctly, after logging in on the dashboard you should see this:
Voilร ! Now our React Native component is being rendered inside the dashboard, along all the other native UWP controls.
Embedding the React Native component inside a Win32 app
Thanks toXAML Islands, we have the opportunity to embed inside a Win32 application a UWP control, either built-in in the platform or a custom one, like the one we have just created to reuse our React Native control. Let's move on and add our component to a WPF application built on top of .NET Core 3.0, since it's the platform that provides the best compatibility with XAML Islands.
Create a new solution in Visual Studio 2019 and chooseWPF (.NET Core)as project's type:
As first step, you need to reference again all the projects required to run React Native and the user control we have created. These are the same ones we have added in the previous scenario:Folly,ReactCommon,ReactUWP,ReactWindowsCoreand the custom controlTodosFeed.Component.
Now we need to setup the whole infrastructure required to support XAML Islands in a WPF application. The official documentation contains a very detailed step-by-step guide, which isavailable here. As such, I won't repeat all the required steps in this post. The only thing to pay attention is that, compared to the documentation, we already have a project which contains a custom control in our scenario. As such, you can skip the step calledCreate a custom UWP control. You just need to make sure to add to the project's file the two properties which are required to make it working with a Win32 application.
Right click on theTodosFeed.Componentproject and chooseUnload Project. Then right click on it again and chooseEdit. Create a newPropertyGroupinside the<Project>element with the following entries:
Then reload the project again and you will be good to go. Just remember to add a reference to theTodosFeed.Componentproject both to the dummy UWP application and the WPF project.
Setup the WPF project
Microsoft provides an easy way to integrate XAML Islands in a WPF application by offering a control that does most of the heavy-lifting for you. The control is calledWindowsXamlHostand it's included in the Windows Community Toolkit. To use it, you need to add the NuGet package calledMicrosoft.Toolkit.Wpf.UI.XamlHostin your WPF application.
The other step is to configure your solution to target a specific platform, since UWP controls can't target the genericAny CPUarchitecture. As such, right click on the solution in Visual Studio and chooseProperties โ Configuration Properties โ Configuration Manager. UnderActive solution platform, chooseNew, then addx64orx86, as you prefer.
All the projects in the dialog should list, under thePlatformcolumn, the same architecture that is defined in theActive solution platformdropdown.
Add the React Native component
Now that the project is setup in the right way, you can add to your WPF application theWindowsXamlHostcontrol we have previously included with the NuGet package. We're going to add it to theMainPage.xamlfile of the WPF application. First, you need to add to theWindowelement the following namespace:
TheInitialTypeNameproperty is set with the full signature of the user control which hosts the React Native component.
Package the application as MSIX
The easiest way to make sure that everything works in the right way with XAML Islands is to package the WPF application as MSIX. However, compared to a traditional application, there are some extra steps to take, in order to make sure that all the files are included in the package in the right way. Make sure to read the section titledPackage the appin the documentationand follow all the steps.
Run it!
That's it! As usual, before testing our WPF app, we need to launch the React packager and the local web server. Once everything is up and running, you can right click on the Windows Application Packaging Project and chooseDeployor press CTRL-F5. The WPF application will start and, if you have done everything properly, you will see your WPF application hosting your familiar React Native component:
Wrapping up
In this (long) blog post we have learned how React Native is a great solution not just to build mobile application, but also Windows experiences. If you're a C# and XAML developer and you're interested in building cross-platform experiences, Xamarin and Xamarin Forms are still the best choice. However, in many cases, you may need to work with a development team with a strong web background and, in such a case, React Native is a great fit. As you have learned in this post, the React Native implementation for Windows is really flexible. Maybe you won't need to build a full UWP application from scratch with React Native, but the framework opens up many opportunities to reuse React Native components built by your web team inside your Windows applications.
React Native for Windows is still a work in progress and, as such, the deployment story isn't available yet. Right now, regardless of the way you compile your React Native for Windows project, you always need the Metro packager up & running in order to render the React content. Of course, this isn't the expected experience for the final user. Once the work on the deployment will be completed, you will be able to create a self-contained MSIX package (like for a regular UWP or Win32 packaged application) and publish it on the Store, share it through a website, deploy with enterprise tools like SSCM or Intune, etc. You can see a glimpse of the expected experience by taking a lookat the deployment story for the current React Native for Windows version.
You can find all the samples mentioned in this articleon GitHub.
I would try to open an issue on the official RNW repository on GitHub, so that the team can help you in diagnosing the issue. From my side, unfortunately, I'm not able to reproduce it. I just tried to create a new RNW 0.71 project and to generate a Release package and I can see the application starting up without having the Metro debugger running in background.
Regrading the metro issue, I want to elaborate little more, as I did fresh build to rule this out. In my machine there was no previous release package installed. But it still did not work. Moreover one of my colleague also did same steps and he is getting same issue.
Any pointers to look where is the issue would be much appreciated.
Few more details:
I have used below command to create my react-native application:
regarding the long building time, unfortunately that's expected. When you generate the package for distribution, Visual Studio rebuilds the whole solution from scratch and, since React Native is added through the whole source code, it takes a long time to build the C++ core. Things should improve if and when the team will be able to move the RNW core to NuGet, so that you don't have to rebuild it every time.
Regarding the Metro issue, that's weird. A Release package shouldn't ask you to connect to Metro, since the JS bundle is embedded into the package. Make sure to uninstall all the instances of your application before deploying the Release package, there might be some conflicts because both packages you use for debugging and for distribution share the same unique identifier (the package family name).
I have tried below steps to publish my React Native application for windows:
Open the solution in Visual Studio
Select the Release configuration from the Configuration Manager drop-down.
Build the solution. You can now launch without first launching Metro.
If you want to build an APPX package to share or publish, use theProject>Publish>Create App Packages...option.
Observations: For building the app it takes a hell lot of time (more than 30 mins) and after completing build successfully I'm not able to launch my RN application without Metro. It gives me error "A connection with the server could not be established" (see below error screen-shot).
After publishing I see there is an react-native application automatically installed into my system with the same name of my application and upon double clicking it I'm getting same error.
Error screen-shot:
Could you please advice me how we can create React Native application for Windows project, standalone package which will work without explicitly running Metro (without running npm start command).
Hello brodman_apterainc , a React Native for Windows application is, in the end, a UWP app, so the same techniques to do CI/CD for UWP apps will work. You can absolutely publish the app on the Store, as well.
Matteo Pagani do we have any updated documentation on building/publishing a react native windows app into an appx in a CI/CD environment (specifically Azure DevOps)? I will be side-loading so even if Store publishing is not ready yet, any docs you can point to would be helpful.
Hello nanduahmed I can confirm that React Native for Windows 0.62 has fixed the problem. If you move your project to the latest React Native version, the XAML Island project will work just fine. I have submitted a PR with the required changes to the sample. In the meantime, if you are eager to give it a try, you can check my fork: https://github.com/qmatteoq/react-native-windows-samples/tree/master/samples/TodosFeed
Hi nanduahmed unfortunately no, there are still some issues. I'm currently on vacation and I'll get back at the end of the month. I will follow up with the team as soon as I'm back.
I appreciate your response. I hope this should be solved in the next version.
Share
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Social_Sharing\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:ModernWorkAppConsult\",\"message:912093\"],\"name\":\"BlogMessagePage\",\"props\":{},\"url\":\"https://techcommunity.microsoft.com/blog/modernworkappconsult/getting-started-with-react-native-for-windows/912093\"}}})":{"__typename":"ComponentRenderResult","html":""}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCoverImage\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCoverImage-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeTitle\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTimeToRead\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1737115705000"}],"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/Pager/PagerLoadMorePreviousNextLinkable\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMorePreviousNextLinkable-1737115705000"}],"message({\"id\":\"message:1846169\"})":{"__ref":"BlogReplyMessage:message:1846169"},"message({\"id\":\"message:1549374\"})":{"__ref":"BlogReplyMessage:message:1549374"},"message({\"id\":\"message:1527556\"})":{"__ref":"BlogReplyMessage:message:1527556"},"message({\"id\":\"message:1527508\"})":{"__ref":"BlogReplyMessage:message:1527508"},"message({\"id\":\"message:1390161\"})":{"__ref":"BlogReplyMessage:message:1390161"},"message({\"id\":\"message:3739440\"})":{"__ref":"BlogReplyMessage:message:3739440"},"message({\"id\":\"message:3736043\"})":{"__ref":"BlogReplyMessage:message:3736043"},"message({\"id\":\"message:3735983\"})":{"__ref":"BlogReplyMessage:message:3735983"},"message({\"id\":\"message:3735939\"})":{"__ref":"BlogReplyMessage:message:3735939"},"message({\"id\":\"message:1846271\"})":{"__ref":"BlogReplyMessage:message:1846271"},"cachedText({\"lastModified\":\"1737115705000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1737115705000"}]},"CachedAsset:pages-1740560923339":{"__typename":"CachedAsset","id":"pages-1740560923339","value":[{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1740560923339,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","entityType":"CATEGORY","displayId":"microsoft365","nodeType":"category","depth":3,"title":"Microsoft 365","shortTitle":"Microsoft 365","parent":{"__ref":"Category:category:products-services"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","entityType":"CATEGORY","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","entityType":"CATEGORY","shortTitle":"Products"},"Blog:board:ModernWorkAppConsult":{"__typename":"Blog","id":"board:ModernWorkAppConsult","entityType":"BLOG","displayId":"ModernWorkAppConsult","nodeType":"board","depth":4,"conversationStyle":"BLOG","title":"Modern Work App Consult Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:microsoft365"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:microsoft365"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"shortTitle":"Modern Work App Consult Blog","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/","tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"PRESET_ONLY"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":5,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:44595":{"__typename":"User","id":"user:44595","uid":44595,"login":"Matteo Pagani","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS00NDU5NS02MzA4OGkwNTU0MkU2NzQwODM2NTE0"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":117,"biography":null,"topicsCount":39,"kudosReceivedCount":132,"kudosGivenCount":1,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2017-03-19T04:38:14.936-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":1,"entityType":"USER","eventPath":"community:gxcuf89792/user:44595"},"BlogTopicMessage:message:912093":{"__typename":"BlogTopicMessage","uid":912093,"subject":"Getting started with React Native for Windows","id":"message:912093","revisionNum":6,"repliesCount":21,"author":{"__ref":"User:user:44595"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"conversation":{"__ref":"Conversation:conversation:912093"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:912093"},"teaser":"","body":"
If you're familiar with web development, you'll know for sure React. This framework, built by Facebook, is becoming more and more popular to build client-side web experiences. Unlike other frameworks like Vue.js or Angular, React focuses only on the View component of a web application. It isn't a fully fledged framework like jQuery or Angular, which have an opinion on everything and, as such, they provide lot of features to perform all the kind of tasks, from HTML templates to APIs to handle HTTP requests. You need to rely on plain old JavaScript (or TypeScript, if you prefer) or on 3rd party libraries to achieve these goals.
\n
\n
What makes React peculiar (and not so easy to understand at the beginning if you're coming from traditional client-side development for Windows, like me) is the different development approach. You may be used to patterns like MVC or MVVM, which goal is to separate the UI from the business logic so that you can make your application easier to test, maintain and evolve. React, instead, being focused only on the View, is based on the concept ofcomponents, which are the different pieces that compose a page. Every component is independent from the other and it includes both the UI and the logic to handle the various events that it can trigger.
\n
\n
Since code is easier to understand than words, here is how a typical React component looks like:
As you can see, the component defines both the UI and the logic to handle the events associated with it:
\n
\n
Therender()function is the one which declares the UI that this component will display.
\n
TheshowAlert()function is triggered when the user clicks on the button declared in the UI.
\n
ThecomponentDidMount()function is part of the component's lifecycle and it's triggered when the component has been rendered and it's ready to work.
\n
\n
The UI might look like HTML, but it's actually defined using a special language calledJSX, which is based on XML and it allows to declare your UI with JavaScript. It may sound blasphemous, but the goal is to go past the standard templating approach used by other frameworks, which is good when you just want to display some data, but it has its limitations when you want to do something more complex, like displaying or hiding something based on a specific condition. In the previous code you can see an example of this approach. In jQuery or another similar framework, you would need to use an API to get a reference to the button and then hook up the event. In React, instead, we can declare it just inline, by subscribing to theonClickevent and by specifying the name of the function to invoke inside curly brackets.
\n
\n
<div>and<button>may look like plain HTML tags, but they're actually not. You can notice it, for example, by the usage of two attributes,classNameandonClick, which don't exist in standard HTML. React will take care of translating these JSX controls into the corresponding HTML ones and to handle the various state changes. To make thing simpler, the JSX controls in React resembles as much as possible the HTML ones, so the syntax will be very familiar to you.
\n
\n
Due to the growing popularity of React, Facebook has decided to extend the framework to support mobile development with the introduction of React Native. This was made possible by the fact that one of the core features offered by React isabstraction. React itself doesn't offer too many built-in features which are tight to a specific platform, but it leverages arender targetto make sure that the View is rendered in the proper way. In the previous examples, React used a render target that can turn JSX into plain HTML. As such, React Native in nothing more than React with a different render target, which turns JSX into mobile controls.
\n
\n
React Native, from a mobile development experience point of view, can be seen as a mix between the classic Xamarin approach and the Xamarin Forms one. Like Xamarin Forms, it shares the opportunity of building truly native applications. React Native, in fact, doesn't use a WebView to render the HTML and JavaScript, like other web based technologies like Cordova. The various JSX controls are rendered using the corresponding native controls for Android or iOS, making the UI and the user experience coherent with the rest of the operating system. Xamarin Forms does the same, but by leveraging XAML as a markup language. However, like classic Xamarin, the goal of React Native isn't really to write an application once and run it everywhere, but rather allowing a team to build mobile applications using the same knowledge and sharing the same libraries. You will find out, in fact, that React Native includes many controls which are cross-platform (likeTextorImage), but also many others which are specific for Android and iOS and that can't be used in a cross-platform way.
\n
\n
React Native includes a render target for iOS and Android but, since BUILD 2018, Microsoft has started to work on a render target for Windows. At BUILD 2019, however, Microsoft has announced a rewrite of the framework from C# to C++, with the goal to get better performances and to be better aligned with the core react-native implementation, which is built in C++ as well. The technology behind this framework is the Universal Windows Platform. React Native for Windows creates a new UWP project and the various JSX controls are rendered using native controls from the Universal Windows Platform and, in the future, from the WinUI library.
\n
\n
The framework is really flexible and it opens up many opportunities for Windows developers:
\n\n
You can build UWP applications from scratch using only React Native.
\n
You can integrate React Native components inside native UWP applications, allowing you to mix UWP controls with React Native controls.
\n
You can integrate React Native components inside WPF or Windows Forms applications, by leveraging XAML Islands, the technology which allows to render UWP controls inside Win32 applications.
\n\n
In this blog post we're going to explore all these options. However, the purpose of this post isn't to be a comprehensive overview of React Native. I will give for granted that you're already familiar with this technology. If it's not your case and you want to learn more, you will find lot of tutorials and documentation onthe official website. You can also start fromthe React website. The main concepts, in fact, are exactly the same between the two platforms, with the only difference that React outputs HTML, while React Native native controls.
\n
\n
Getting started
\n
Let's start by setting up our computer with all the requirements needed to build React Native applications for Windows. The first one is Visual Studio 2019 with the following workloads installed:
\n
\n
Universal Windows Platform development (make sure to enable theC++ (v142) Universal Windows Platform toolsoption)
\n
Desktop development with C++
\n
\n
Make sure also to check, in the Indivual components section, the following ones underCompilers, build tools and runtimes:
\n
\n
MSVC v141 - VS 2017 C++ x64/x86 build tools (v14.16)
\n
MSVC v141 - VS 2017 C++ ARM build tools (v14.16)
\n
\n
Now let's move to the \"web tools\". The first one isNodeJS, the JavaScript runtime built on top of the Chrome JavaScript engine. Everything around React Native (the core, libraries, etc.) is distributed as packages through the popular NPM package manager, so you'll need the NodeJS runtime to leverage it. You can get it from theofficial website.
\n
\n
Optionally (but highly suggested) is to installYarn, a package manager for Node. As we're going to see in the next steps, it will help us a lot in setting up the whole environment. You can download it fromthe official website.
\n
\n
Last but not the least, if you want to debug your application you will need to leverage the Developer Tools included in Chromium. Theofficial guidance on GitHubspecifically invites you to install Chrome, but alsothe new Edge based on Chromiumworks like a charm.
\n
\n
That's it! Now we can start to create our first React Native project. You can refer to the guidance providedon the GitHub repository. I won't repeat them here since the steps might change in the future (for example, the targeted React Native version has changed multiple times since the project started).
\n
The last tool I'm going to mention isn't exactly a requirement, but a strong suggestion. In order to build your React Native application you will need to use an IDE. Sure, you can use also Notepad, but there are better options out there, likeVisual Studio Code, which offers alsoan extension for React Nativewhich gives you IntelliSense, debugging, etc.
\n
\n
\n
Make sure to have plenty of space on your hard disk. Since the React Native implementation for Windows is based on C++, the compilation artifacts will be quite big, so an average project's folder can easily reach the size of 5-6 GB.
\n
\n
Running your React Native for Windows project
\n
The easiest way to launch your React Native for Windows project is to run the following command from your project's folder:
\n
\n
react-native run-windows\n
\n
In the past there have been some issues that prevented this command to work properly. Most of them should be fixed now but, in case you're still hitting one of them, here is an alternative procedure:
\n\n
\n
Open in File Explorer thewindowsfolder inside the folder which contains your React Native project.
\n
\n
\n
Open the Visual Studio solution you'll find there. The name of the solution will match the name of the project.
\n
\n
\n
The solution is made by different projects, all based on C++. The main one (which contains the actual application to deploy) is the one which name matches with the React Native project's name. In our case, it'sTodosFeed.
\n
\n
Compile the whole solution (again, it will take a while because of the C++ projects), then right click on the UWP project and choose Deploy. Make sure that, in the configuration dropdown, you choose an architecture which is suitable for your computer, like x86 or x64. The default value, in fact, will be ARM.
\n\n
\n
You should always launch the UWP project either from the Start menu or by pressing CTRL-F5 in Visual Studio, without attaching the debugger. The reason is that, in this scenario, the UWP app is just the \"host\" of the React Native application, so the real debugging must be done on the React code.
\n
\n
Before launching the application, however, you have to manually run the React packager by typing the following command in the project's folder:
\n
\n
yarn start\n
\n
What is theReact packager? It takes care of a few important tasks, like translating JSX into code that the target platform will understand and combining all your JavaScript into a single file. When you're in development mode, the command prompt with the React packager must always be up & running. This way, every time you make a change to the code of your React Native application, the packager will automatically create a new bundle and refresh the application.
\n
\n
\n
\n
Once the packager is ready, it should automatically launch Chrome on the local server which is used to serve the React application. If it doesn't happen, you can open it manually (or you can launch Edge based on Chromium) and open the URL http://localhost:8081/debugger-ui/. Then you can press F12 or CTRL-SHIFT-J to turn on the developer tools, which will help you to see any error that might arise in the React Native application. This operation is very important because, if the local development server isn't up & running, the UWP application won't be able to render the React Native content and you will get an error like the following one:
\n
\n
\n
\n
Now that both the packager and the development server are up & running, you can launch the UWP application you have deployed. If you did everything well, you will see the packager starting to serve the various files in the command prompt and, in the UWP application, you will see the default React Native starter template.
\n
\n
\n
\n
Using React Native to build a full UWP application
\n
This is the simplest task, since with all the steps we have taken so far we have already created a full UWP application based on React Native. Let's try to create a more realistic one compared to the default template, which we're going to reuse for the next scenarios. As already mentioned, the UWP app is just the host of the React Native one, so to start actually coding you need to open the React Native project's folder with Visual Studio Code. Just right click on the folder and chooseOpen with Visual Studio Codeor, alternatively, if you're still in the command prompt, type:
\n
\n
code .\n
\n
As mentioned, the default page you see in the application is defined in theApp.jsfile. Let's replace the default content with a simple application that displays a list of to-dos, downloaded from a REST service. This will be the final look & feel:
\n
\n
\n
\n
Nothing too complex, but enough to play with the React Native and Windows capabilities.
\n
Let's start by building a component that will display the list of to-dos. Create a new folder in the project calledcomponentsand, inside it, create a file calledTodosList.js.
We're going to use four controls from React Native:
\n
\n
ActivityIndicator, to display a loading icon when the data is being downloaded from the REST service.
\n
View, which is the basic container of React Native. Typically, it's the main entry point which contains, as child, the other controls. Think of it like thePagecontrol in XAML.
\n
FlatListto display the list of to-dos we have downloaded.
This is the basic skeleton, since the component doesn't actually include any data or any action. The component is defined using the standard React Native syntax based on ES6, the latest definition of the JavaScript language. We create a new class which extends theComponentone, which is provided by the React library. The component defines arender()method, which include the JSX that represents the UI. The currentViewcontains anActivityIndicatorand aFlatListwhich, however, we need to populate with some data.
First we need to introduce one of the most important concepts in React,state. It's a key - value pair collection where we can store data that must be displayed by the user interface. The nice bonus of the state management in React is that it automatically keeps the UI in sync. Whenever you're going to change one of the values stored in the state, every UI component connected to that value will be automatically updated. If you're a XAML developer, this concept should be familiar to you since it's similar to binding.
\n
\n
We define the state in the constructor of the component and we setup two properties: one calledtodos, which is an array that will store our collection of to-dos; the other one is calledloadingand it's a boolean we're going to use to hide / display the loading indicator.
\n
Now that we have a place where to store our to-dos, we need to download them when the component is rendered. To achieve this goal we leverage thecomponentDidMount()method, which is one of the many available functions to handle the lifecycle of a component. Inside the function we use the JavaScriptfetch APIto download the list of to-dos from a REST service. We're usinghttps://jsonplaceholder.typicode.comas endpoint, which is a service that returns fake data for testing and development purposes. The fetch API is asynchronous, so we use the async / await approach (supported by all the modern browsers nowadays) to handle it. In the end we convert the response into a JSON object by calling another asynchronous method,json(), and we store the result inside thetodosobject in the state. We also change the value of theloadingproperty, so that we can hide the loading indicator.
\n
\n
You can notice two things:
\n
\n
To set the state, we are using thesetState()method instead of setting it directly. This is required to enable the sync, otherwise the UI won't be notified that the value of one of the properties has changed.
\n
We use theslice()method to take only the first 20 items from the result.
\n
\n
Now that we have some real data inside the state, we can populate the UI controls we have previously created:
\n
\n
\n
We connect theanimatingproperty of theActivityIndicatorcontrol to theloadingproperty stored in the state (this.state.loading). This way, the loading indicator will be displayed when we start the operation and hidden when the data from the REST service has been downloaded.
\n
\n
\n
We connect thedataproperty of theFlatListcontrol to thetodosproperty stored in the state (this.state.todos). This way, the list will be automatically populated with all the items that have been downloaded from the REST service.
\n
\n
\n
We use therenderItemproperty of theFlatListcontrol to define how every single item of the list should be rendered. We express this property using a lambda expression, which gives us a reference to a single to-do in the list. For the moment we use a simpleTextcontrol and, inside it, we display the value of thetextproperty of the to-do. We can understand where this property is coming from by openingthe URLof the REST API in a browser or in a tool likePostman. We will see that each item inside the collection has the following properties:
\n
\n
userId
\n
id
\n
title
\n
completed
\n
\n
\n
\n
As such, from theitemobject we can directly access to each of them.
\n
\n
Now that we have defined theTodosListcomponent, we need to display it in replacement of the original React Native template. Move to theApp.jsfile and, inside the class which defines the main component, change therender()method to:
That's it! Now make sure that the React packager is still up & running and that Edge / Chrome is open on the developer tools. The UWP application should update itself and you should see the list of to-dos being downloaded and rendered:
\n
\n
\n
The controls we have defined using JSX have been translated into native UWP controls:
\n
\n
Textis now aTextBlock
\n
ActivityIndicatoris now aProgressRing
\n
FlatListis now aListView
\n
\n
The nice benefit of the live debugger is that you won't have to redeploy the UWP application every time you make a change. Just change something in the React Native code in Visual Studio Code, hit save and the content of the UWP app will be reloaded to display the updates.
\n
\n
That's it! We have our first React Native application running in Windows as a full UWP application!
\n
\n
Embedding the React Native component inside a UWP app
\n
Let's move to the next step and see another scenario. What if we want to use the React Native component we have just built not as part of a full React Native application, but inside an existing UWP application? You may have a UWP application already in development, but you may want to integrate a React Native component built by the mobile team for the Android and iOS versions of the same app.
\n
\n
Let's start! The first step is to move the React Native component we have built before from a full UWP app to a custom control, that can be reused in other UWP applications. Open the solution created by the React Native for Windows CLI (you'll find it inside thewindowsfolder of your project). Then right click on it and chooseAdd โ New projectand select theWindows Runtime Component (Universal Windows)template:
\n
\n
\n
\n
In this case I'm building a C# component since it's the language I'm most familiar with. However, you could use the C++ template as well since, other than setting up the React Native infrastructure, we aren't actually going to build something. All the content displayed in this control will be provided by the React Native implementation.
\n
\n
Feel free to delete the default class that is included in the project, then right click on it and chooseAdd โ New item. PickUser controlfrom the list and give it a meaningful name, likeTodosFeedControl.xaml.
\n
Now we need to include inside the newly created user control the React Native for Windows initialization. As first thing, right click on the project, chooseAdd โ Referenceand pick up from the list the project calledReactUWP.
\n
\n
Now that the React Native for Windows runtime is referenced, we need to add in the XAML file the control which will host the React Native application. First, let's declare the relevant namespace in user control definition:
\n
\n
xmlns:react=\"using:react.uwp\"\n
\n
Then, inside the mainGrid, you need to add aReactControl, which is part of the namespace you have just declared:
This is boilerplate code to initialize React Native for Windows. The only relevant parts to highlight are the two constants declared at the top:
\n
\n
JSFILENAMEdefines the name of the JavaScript file which contains the starting point of the React Native app, without the .js extension. In our case, it's theindexfile.
\n
JSCOMPONENTNAMEdefines the name of the component which acts as a starting point of the application. This string must match the name of the project; in our case it'sTodosFeed.
\n
\n
That's it! Now we have a component that we can leverage in a full UWP application. Let's try this but, instead of using a basic UWP app, let's use a real one, to make things more interesting. We're going to use theXAML VanArsdel Inventory Sample, which is an open-source project developed by Microsoft to showcase the usage of the latest and greatest XAML controls in a real product.
\n
\n
\n
\n
As first step, clone or download the project on your computer, then open theInventory.slnsolution. Now we need to add a reference to the user control we have just created. However, since the React Native for Windows implementation isn't stored in a library or in a NuGet package, we'll need to reference also the same C++ project that are referenced by the UWP application which hosts React Native.
\n
\n
To keep things cleaner, I decided to create a solution folder (right click on the solution and chooseAdd โ New Solution Folder), where to store all the project related to React Native. Once you have created it, right click on it and chooseAdd โ Existing project. You will need to reference the following 5 projects, which are all stored in the folder that contains the React Native project.
\n
\n
Folly, which is included in thenode_modules\\react-native-windows\\Follyfolder.
\n
ReactUWP, which is included in thenode_modules\\react-native-windows\\ReactUWPfolder.
\n
ReactCommon, which is included in thenode_modules\\react-native-windows\\ReactCommonfolder.
\n
ReactWindowsCore, which is included in thenode_modules\\react-native-windows\\ReactWindowsCorefolder.
\n
\n
All the previous project files will have the extension.vcxproj, since they're based on C++. The last and fifth project to reference is the one we have just created to store our user control. In my case, it's calledTodosFeed.Componentand it's stored in thewindowsfolder. This project's file extension will be, instead,.csproj, since it's based on C#.
\n
\n
This is how your solution should look like:
\n
\n
\n
Now we have everything we need! We can right click on the Inventory.App project, choose Add โ Reference and select the TodosFeed.Component project. We're going to add our React Native component in the main dashboard of the application, along with the other widgets.
\n
\n
\n
\n
We can find the dashboard definition inside theViews โ Dashboard โ DashboardView.xamlfile. Let's first add the namespace of our user control:
\n
\n
xmlns:react=\"using:TodosFeed.Component\"\n
\n
The page contains aGridViewcontrol with different panels declared as children. Let's add a new one at the end:
That's it. The user control we have just added contains all the logic required to initialize the React Native component, so we don't need to do anything else other adding it to the XAML page.
\n
Now it's time to build and deploy the application. Before doing it, however, we need to make sure that the React packager is up & running, otherwise the React Native component won't be rendered. As such, make sure that you have launched theyarn startcommand on the React Native project and that your browser is opened on thehttp://localhost:8081/debugger-ui/URL.
\n
\n
If you have done everything correctly, after logging in on the dashboard you should see this:
\n
\n
\n
\n
Voilร ! Now our React Native component is being rendered inside the dashboard, along all the other native UWP controls.
\n
\n
Embedding the React Native component inside a Win32 app
\n
Thanks toXAML Islands, we have the opportunity to embed inside a Win32 application a UWP control, either built-in in the platform or a custom one, like the one we have just created to reuse our React Native control. Let's move on and add our component to a WPF application built on top of .NET Core 3.0, since it's the platform that provides the best compatibility with XAML Islands.
\n
\n
Create a new solution in Visual Studio 2019 and chooseWPF (.NET Core)as project's type:
\n
\n
\n
\n
As first step, you need to reference again all the projects required to run React Native and the user control we have created. These are the same ones we have added in the previous scenario:Folly,ReactCommon,ReactUWP,ReactWindowsCoreand the custom controlTodosFeed.Component.
\n
\n
Now we need to setup the whole infrastructure required to support XAML Islands in a WPF application. The official documentation contains a very detailed step-by-step guide, which isavailable here. As such, I won't repeat all the required steps in this post. The only thing to pay attention is that, compared to the documentation, we already have a project which contains a custom control in our scenario. As such, you can skip the step calledCreate a custom UWP control. You just need to make sure to add to the project's file the two properties which are required to make it working with a Win32 application.
\n
\n
Right click on theTodosFeed.Componentproject and chooseUnload Project. Then right click on it again and chooseEdit. Create a newPropertyGroupinside the<Project>element with the following entries:
Then reload the project again and you will be good to go. Just remember to add a reference to theTodosFeed.Componentproject both to the dummy UWP application and the WPF project.
\n
\n
Setup the WPF project
\n
Microsoft provides an easy way to integrate XAML Islands in a WPF application by offering a control that does most of the heavy-lifting for you. The control is calledWindowsXamlHostand it's included in the Windows Community Toolkit. To use it, you need to add the NuGet package calledMicrosoft.Toolkit.Wpf.UI.XamlHostin your WPF application.
\n
The other step is to configure your solution to target a specific platform, since UWP controls can't target the genericAny CPUarchitecture. As such, right click on the solution in Visual Studio and chooseProperties โ Configuration Properties โ Configuration Manager. UnderActive solution platform, chooseNew, then addx64orx86, as you prefer.
\n
\n
All the projects in the dialog should list, under thePlatformcolumn, the same architecture that is defined in theActive solution platformdropdown.
\n
\n
\n
\n
Add the React Native component
\n
Now that the project is setup in the right way, you can add to your WPF application theWindowsXamlHostcontrol we have previously included with the NuGet package. We're going to add it to theMainPage.xamlfile of the WPF application. First, you need to add to theWindowelement the following namespace:
TheInitialTypeNameproperty is set with the full signature of the user control which hosts the React Native component.
\n
Package the application as MSIX
\n
The easiest way to make sure that everything works in the right way with XAML Islands is to package the WPF application as MSIX. However, compared to a traditional application, there are some extra steps to take, in order to make sure that all the files are included in the package in the right way. Make sure to read the section titledPackage the appin the documentationand follow all the steps.
\n
Run it!
\n
That's it! As usual, before testing our WPF app, we need to launch the React packager and the local web server. Once everything is up and running, you can right click on the Windows Application Packaging Project and chooseDeployor press CTRL-F5. The WPF application will start and, if you have done everything properly, you will see your WPF application hosting your familiar React Native component:
\n
\n
\n
\n
Wrapping up
\n
In this (long) blog post we have learned how React Native is a great solution not just to build mobile application, but also Windows experiences. If you're a C# and XAML developer and you're interested in building cross-platform experiences, Xamarin and Xamarin Forms are still the best choice. However, in many cases, you may need to work with a development team with a strong web background and, in such a case, React Native is a great fit. As you have learned in this post, the React Native implementation for Windows is really flexible. Maybe you won't need to build a full UWP application from scratch with React Native, but the framework opens up many opportunities to reuse React Native components built by your web team inside your Windows applications.
\n
\n
React Native for Windows is still a work in progress and, as such, the deployment story isn't available yet. Right now, regardless of the way you compile your React Native for Windows project, you always need the Metro packager up & running in order to render the React content. Of course, this isn't the expected experience for the final user. Once the work on the deployment will be completed, you will be able to create a self-contained MSIX package (like for a regular UWP or Win32 packaged application) and publish it on the Store, share it through a website, deploy with enterprise tools like SSCM or Intune, etc. You can see a glimpse of the expected experience by taking a lookat the deployment story for the current React Native for Windows version.
\n
\n
You can find all the samples mentioned in this articleon GitHub.
\n
\n
Happy coding!
","body@stringLength":"61140","rawBody":"
If you're familiar with web development, you'll know for sure React. This framework, built by Facebook, is becoming more and more popular to build client-side web experiences. Unlike other frameworks like Vue.js or Angular, React focuses only on the View component of a web application. It isn't a fully fledged framework like jQuery or Angular, which have an opinion on everything and, as such, they provide lot of features to perform all the kind of tasks, from HTML templates to APIs to handle HTTP requests. You need to rely on plain old JavaScript (or TypeScript, if you prefer) or on 3rd party libraries to achieve these goals.
\n
\n
What makes React peculiar (and not so easy to understand at the beginning if you're coming from traditional client-side development for Windows, like me) is the different development approach. You may be used to patterns like MVC or MVVM, which goal is to separate the UI from the business logic so that you can make your application easier to test, maintain and evolve. React, instead, being focused only on the View, is based on the concept ofcomponents, which are the different pieces that compose a page. Every component is independent from the other and it includes both the UI and the logic to handle the various events that it can trigger.
\n
\n
Since code is easier to understand than words, here is how a typical React component looks like:
As you can see, the component defines both the UI and the logic to handle the events associated with it:
\n
\n
Therender()function is the one which declares the UI that this component will display.
\n
TheshowAlert()function is triggered when the user clicks on the button declared in the UI.
\n
ThecomponentDidMount()function is part of the component's lifecycle and it's triggered when the component has been rendered and it's ready to work.
\n
\n
The UI might look like HTML, but it's actually defined using a special language calledJSX, which is based on XML and it allows to declare your UI with JavaScript. It may sound blasphemous, but the goal is to go past the standard templating approach used by other frameworks, which is good when you just want to display some data, but it has its limitations when you want to do something more complex, like displaying or hiding something based on a specific condition. In the previous code you can see an example of this approach. In jQuery or another similar framework, you would need to use an API to get a reference to the button and then hook up the event. In React, instead, we can declare it just inline, by subscribing to theonClickevent and by specifying the name of the function to invoke inside curly brackets.
\n
\n
<div>and<button>may look like plain HTML tags, but they're actually not. You can notice it, for example, by the usage of two attributes,classNameandonClick, which don't exist in standard HTML. React will take care of translating these JSX controls into the corresponding HTML ones and to handle the various state changes. To make thing simpler, the JSX controls in React resembles as much as possible the HTML ones, so the syntax will be very familiar to you.
\n
\n
Due to the growing popularity of React, Facebook has decided to extend the framework to support mobile development with the introduction of React Native. This was made possible by the fact that one of the core features offered by React isabstraction. React itself doesn't offer too many built-in features which are tight to a specific platform, but it leverages arender targetto make sure that the View is rendered in the proper way. In the previous examples, React used a render target that can turn JSX into plain HTML. As such, React Native in nothing more than React with a different render target, which turns JSX into mobile controls.
\n
\n
React Native, from a mobile development experience point of view, can be seen as a mix between the classic Xamarin approach and the Xamarin Forms one. Like Xamarin Forms, it shares the opportunity of building truly native applications. React Native, in fact, doesn't use a WebView to render the HTML and JavaScript, like other web based technologies like Cordova. The various JSX controls are rendered using the corresponding native controls for Android or iOS, making the UI and the user experience coherent with the rest of the operating system. Xamarin Forms does the same, but by leveraging XAML as a markup language. However, like classic Xamarin, the goal of React Native isn't really to write an application once and run it everywhere, but rather allowing a team to build mobile applications using the same knowledge and sharing the same libraries. You will find out, in fact, that React Native includes many controls which are cross-platform (likeTextorImage), but also many others which are specific for Android and iOS and that can't be used in a cross-platform way.
\n
\n
React Native includes a render target for iOS and Android but, since BUILD 2018, Microsoft has started to work on a render target for Windows. At BUILD 2019, however, Microsoft has announced a rewrite of the framework from C# to C++, with the goal to get better performances and to be better aligned with the core react-native implementation, which is built in C++ as well. The technology behind this framework is the Universal Windows Platform. React Native for Windows creates a new UWP project and the various JSX controls are rendered using native controls from the Universal Windows Platform and, in the future, from the WinUI library.
\n
\n
The framework is really flexible and it opens up many opportunities for Windows developers:
\n\n
You can build UWP applications from scratch using only React Native.
\n
You can integrate React Native components inside native UWP applications, allowing you to mix UWP controls with React Native controls.
\n
You can integrate React Native components inside WPF or Windows Forms applications, by leveraging XAML Islands, the technology which allows to render UWP controls inside Win32 applications.
\n\n
In this blog post we're going to explore all these options. However, the purpose of this post isn't to be a comprehensive overview of React Native. I will give for granted that you're already familiar with this technology. If it's not your case and you want to learn more, you will find lot of tutorials and documentation onthe official website. You can also start fromthe React website. The main concepts, in fact, are exactly the same between the two platforms, with the only difference that React outputs HTML, while React Native native controls.
\n
\n
Getting started
\n
Let's start by setting up our computer with all the requirements needed to build React Native applications for Windows. The first one is Visual Studio 2019 with the following workloads installed:
\n
\n
Universal Windows Platform development (make sure to enable theC++ (v142) Universal Windows Platform toolsoption)
\n
Desktop development with C++
\n
\n
Make sure also to check, in the Indivual components section, the following ones underCompilers, build tools and runtimes:
\n
\n
MSVC v141 - VS 2017 C++ x64/x86 build tools (v14.16)
\n
MSVC v141 - VS 2017 C++ ARM build tools (v14.16)
\n
\n
Now let's move to the \"web tools\". The first one isNodeJS, the JavaScript runtime built on top of the Chrome JavaScript engine. Everything around React Native (the core, libraries, etc.) is distributed as packages through the popular NPM package manager, so you'll need the NodeJS runtime to leverage it. You can get it from theofficial website.
\n
\n
Optionally (but highly suggested) is to installYarn, a package manager for Node. As we're going to see in the next steps, it will help us a lot in setting up the whole environment. You can download it fromthe official website.
\n
\n
Last but not the least, if you want to debug your application you will need to leverage the Developer Tools included in Chromium. Theofficial guidance on GitHubspecifically invites you to install Chrome, but alsothe new Edge based on Chromiumworks like a charm.
\n
\n
That's it! Now we can start to create our first React Native project. You can refer to the guidance providedon the GitHub repository. I won't repeat them here since the steps might change in the future (for example, the targeted React Native version has changed multiple times since the project started).
\n
The last tool I'm going to mention isn't exactly a requirement, but a strong suggestion. In order to build your React Native application you will need to use an IDE. Sure, you can use also Notepad, but there are better options out there, likeVisual Studio Code, which offers alsoan extension for React Nativewhich gives you IntelliSense, debugging, etc.
\n
\n
\n
Make sure to have plenty of space on your hard disk. Since the React Native implementation for Windows is based on C++, the compilation artifacts will be quite big, so an average project's folder can easily reach the size of 5-6 GB.
\n
\n
Running your React Native for Windows project
\n
The easiest way to launch your React Native for Windows project is to run the following command from your project's folder:
\n
\n
react-native run-windows\n
\n
In the past there have been some issues that prevented this command to work properly. Most of them should be fixed now but, in case you're still hitting one of them, here is an alternative procedure:
\n\n
\n
Open in File Explorer thewindowsfolder inside the folder which contains your React Native project.
\n
\n
\n
Open the Visual Studio solution you'll find there. The name of the solution will match the name of the project.
\n
\n
\n
The solution is made by different projects, all based on C++. The main one (which contains the actual application to deploy) is the one which name matches with the React Native project's name. In our case, it'sTodosFeed.
\n
\n
Compile the whole solution (again, it will take a while because of the C++ projects), then right click on the UWP project and choose Deploy. Make sure that, in the configuration dropdown, you choose an architecture which is suitable for your computer, like x86 or x64. The default value, in fact, will be ARM.
\n\n
\n
You should always launch the UWP project either from the Start menu or by pressing CTRL-F5 in Visual Studio, without attaching the debugger. The reason is that, in this scenario, the UWP app is just the \"host\" of the React Native application, so the real debugging must be done on the React code.
\n
\n
Before launching the application, however, you have to manually run the React packager by typing the following command in the project's folder:
\n
\n
yarn start\n
\n
What is theReact packager? It takes care of a few important tasks, like translating JSX into code that the target platform will understand and combining all your JavaScript into a single file. When you're in development mode, the command prompt with the React packager must always be up & running. This way, every time you make a change to the code of your React Native application, the packager will automatically create a new bundle and refresh the application.
\n
\n
\n
\n
Once the packager is ready, it should automatically launch Chrome on the local server which is used to serve the React application. If it doesn't happen, you can open it manually (or you can launch Edge based on Chromium) and open the URL http://localhost:8081/debugger-ui/. Then you can press F12 or CTRL-SHIFT-J to turn on the developer tools, which will help you to see any error that might arise in the React Native application. This operation is very important because, if the local development server isn't up & running, the UWP application won't be able to render the React Native content and you will get an error like the following one:
\n
\n
\n
\n
Now that both the packager and the development server are up & running, you can launch the UWP application you have deployed. If you did everything well, you will see the packager starting to serve the various files in the command prompt and, in the UWP application, you will see the default React Native starter template.
\n
\n
\n
\n
Using React Native to build a full UWP application
\n
This is the simplest task, since with all the steps we have taken so far we have already created a full UWP application based on React Native. Let's try to create a more realistic one compared to the default template, which we're going to reuse for the next scenarios. As already mentioned, the UWP app is just the host of the React Native one, so to start actually coding you need to open the React Native project's folder with Visual Studio Code. Just right click on the folder and chooseOpen with Visual Studio Codeor, alternatively, if you're still in the command prompt, type:
\n
\n
code .\n
\n
As mentioned, the default page you see in the application is defined in theApp.jsfile. Let's replace the default content with a simple application that displays a list of to-dos, downloaded from a REST service. This will be the final look & feel:
\n
\n
\n
\n
Nothing too complex, but enough to play with the React Native and Windows capabilities.
\n
Let's start by building a component that will display the list of to-dos. Create a new folder in the project calledcomponentsand, inside it, create a file calledTodosList.js.
We're going to use four controls from React Native:
\n
\n
ActivityIndicator, to display a loading icon when the data is being downloaded from the REST service.
\n
View, which is the basic container of React Native. Typically, it's the main entry point which contains, as child, the other controls. Think of it like thePagecontrol in XAML.
\n
FlatListto display the list of to-dos we have downloaded.
This is the basic skeleton, since the component doesn't actually include any data or any action. The component is defined using the standard React Native syntax based on ES6, the latest definition of the JavaScript language. We create a new class which extends theComponentone, which is provided by the React library. The component defines arender()method, which include the JSX that represents the UI. The currentViewcontains anActivityIndicatorand aFlatListwhich, however, we need to populate with some data.
First we need to introduce one of the most important concepts in React,state. It's a key - value pair collection where we can store data that must be displayed by the user interface. The nice bonus of the state management in React is that it automatically keeps the UI in sync. Whenever you're going to change one of the values stored in the state, every UI component connected to that value will be automatically updated. If you're a XAML developer, this concept should be familiar to you since it's similar to binding.
\n
\n
We define the state in the constructor of the component and we setup two properties: one calledtodos, which is an array that will store our collection of to-dos; the other one is calledloadingand it's a boolean we're going to use to hide / display the loading indicator.
\n
Now that we have a place where to store our to-dos, we need to download them when the component is rendered. To achieve this goal we leverage thecomponentDidMount()method, which is one of the many available functions to handle the lifecycle of a component. Inside the function we use the JavaScriptfetch APIto download the list of to-dos from a REST service. We're usinghttps://jsonplaceholder.typicode.comas endpoint, which is a service that returns fake data for testing and development purposes. The fetch API is asynchronous, so we use the async / await approach (supported by all the modern browsers nowadays) to handle it. In the end we convert the response into a JSON object by calling another asynchronous method,json(), and we store the result inside thetodosobject in the state. We also change the value of theloadingproperty, so that we can hide the loading indicator.
\n
\n
You can notice two things:
\n
\n
To set the state, we are using thesetState()method instead of setting it directly. This is required to enable the sync, otherwise the UI won't be notified that the value of one of the properties has changed.
\n
We use theslice()method to take only the first 20 items from the result.
\n
\n
Now that we have some real data inside the state, we can populate the UI controls we have previously created:
\n
\n
\n
We connect theanimatingproperty of theActivityIndicatorcontrol to theloadingproperty stored in the state (this.state.loading). This way, the loading indicator will be displayed when we start the operation and hidden when the data from the REST service has been downloaded.
\n
\n
\n
We connect thedataproperty of theFlatListcontrol to thetodosproperty stored in the state (this.state.todos). This way, the list will be automatically populated with all the items that have been downloaded from the REST service.
\n
\n
\n
We use therenderItemproperty of theFlatListcontrol to define how every single item of the list should be rendered. We express this property using a lambda expression, which gives us a reference to a single to-do in the list. For the moment we use a simpleTextcontrol and, inside it, we display the value of thetextproperty of the to-do. We can understand where this property is coming from by openingthe URLof the REST API in a browser or in a tool likePostman. We will see that each item inside the collection has the following properties:
\n
\n
userId
\n
id
\n
title
\n
completed
\n
\n
\n
\n
As such, from theitemobject we can directly access to each of them.
\n
\n
Now that we have defined theTodosListcomponent, we need to display it in replacement of the original React Native template. Move to theApp.jsfile and, inside the class which defines the main component, change therender()method to:
That's it! Now make sure that the React packager is still up & running and that Edge / Chrome is open on the developer tools. The UWP application should update itself and you should see the list of to-dos being downloaded and rendered:
\n
\n
\n
The controls we have defined using JSX have been translated into native UWP controls:
\n
\n
Textis now aTextBlock
\n
ActivityIndicatoris now aProgressRing
\n
FlatListis now aListView
\n
\n
The nice benefit of the live debugger is that you won't have to redeploy the UWP application every time you make a change. Just change something in the React Native code in Visual Studio Code, hit save and the content of the UWP app will be reloaded to display the updates.
\n
\n
That's it! We have our first React Native application running in Windows as a full UWP application!
\n
\n
Embedding the React Native component inside a UWP app
\n
Let's move to the next step and see another scenario. What if we want to use the React Native component we have just built not as part of a full React Native application, but inside an existing UWP application? You may have a UWP application already in development, but you may want to integrate a React Native component built by the mobile team for the Android and iOS versions of the same app.
\n
\n
Let's start! The first step is to move the React Native component we have built before from a full UWP app to a custom control, that can be reused in other UWP applications. Open the solution created by the React Native for Windows CLI (you'll find it inside thewindowsfolder of your project). Then right click on it and chooseAdd โ New projectand select theWindows Runtime Component (Universal Windows)template:
\n
\n
\n
\n
In this case I'm building a C# component since it's the language I'm most familiar with. However, you could use the C++ template as well since, other than setting up the React Native infrastructure, we aren't actually going to build something. All the content displayed in this control will be provided by the React Native implementation.
\n
\n
Feel free to delete the default class that is included in the project, then right click on it and chooseAdd โ New item. PickUser controlfrom the list and give it a meaningful name, likeTodosFeedControl.xaml.
\n
Now we need to include inside the newly created user control the React Native for Windows initialization. As first thing, right click on the project, chooseAdd โ Referenceand pick up from the list the project calledReactUWP.
\n
\n
Now that the React Native for Windows runtime is referenced, we need to add in the XAML file the control which will host the React Native application. First, let's declare the relevant namespace in user control definition:
\n
\n
xmlns:react=\"using:react.uwp\"\n
\n
Then, inside the mainGrid, you need to add aReactControl, which is part of the namespace you have just declared:
This is boilerplate code to initialize React Native for Windows. The only relevant parts to highlight are the two constants declared at the top:
\n
\n
JSFILENAMEdefines the name of the JavaScript file which contains the starting point of the React Native app, without the .js extension. In our case, it's theindexfile.
\n
JSCOMPONENTNAMEdefines the name of the component which acts as a starting point of the application. This string must match the name of the project; in our case it'sTodosFeed.
\n
\n
That's it! Now we have a component that we can leverage in a full UWP application. Let's try this but, instead of using a basic UWP app, let's use a real one, to make things more interesting. We're going to use theXAML VanArsdel Inventory Sample, which is an open-source project developed by Microsoft to showcase the usage of the latest and greatest XAML controls in a real product.
\n
\n
\n
\n
As first step, clone or download the project on your computer, then open theInventory.slnsolution. Now we need to add a reference to the user control we have just created. However, since the React Native for Windows implementation isn't stored in a library or in a NuGet package, we'll need to reference also the same C++ project that are referenced by the UWP application which hosts React Native.
\n
\n
To keep things cleaner, I decided to create a solution folder (right click on the solution and chooseAdd โ New Solution Folder), where to store all the project related to React Native. Once you have created it, right click on it and chooseAdd โ Existing project. You will need to reference the following 5 projects, which are all stored in the folder that contains the React Native project.
\n
\n
Folly, which is included in thenode_modules\\react-native-windows\\Follyfolder.
\n
ReactUWP, which is included in thenode_modules\\react-native-windows\\ReactUWPfolder.
\n
ReactCommon, which is included in thenode_modules\\react-native-windows\\ReactCommonfolder.
\n
ReactWindowsCore, which is included in thenode_modules\\react-native-windows\\ReactWindowsCorefolder.
\n
\n
All the previous project files will have the extension.vcxproj, since they're based on C++. The last and fifth project to reference is the one we have just created to store our user control. In my case, it's calledTodosFeed.Componentand it's stored in thewindowsfolder. This project's file extension will be, instead,.csproj, since it's based on C#.
\n
\n
This is how your solution should look like:
\n
\n
\n
Now we have everything we need! We can right click on the Inventory.App project, choose Add โ Reference and select the TodosFeed.Component project. We're going to add our React Native component in the main dashboard of the application, along with the other widgets.
\n
\n
\n
\n
We can find the dashboard definition inside theViews โ Dashboard โ DashboardView.xamlfile. Let's first add the namespace of our user control:
\n
\n
xmlns:react=\"using:TodosFeed.Component\"\n
\n
The page contains aGridViewcontrol with different panels declared as children. Let's add a new one at the end:
That's it. The user control we have just added contains all the logic required to initialize the React Native component, so we don't need to do anything else other adding it to the XAML page.
\n
Now it's time to build and deploy the application. Before doing it, however, we need to make sure that the React packager is up & running, otherwise the React Native component won't be rendered. As such, make sure that you have launched theyarn startcommand on the React Native project and that your browser is opened on thehttp://localhost:8081/debugger-ui/URL.
\n
\n
If you have done everything correctly, after logging in on the dashboard you should see this:
\n
\n
\n
\n
Voilร ! Now our React Native component is being rendered inside the dashboard, along all the other native UWP controls.
\n
\n
Embedding the React Native component inside a Win32 app
\n
Thanks toXAML Islands, we have the opportunity to embed inside a Win32 application a UWP control, either built-in in the platform or a custom one, like the one we have just created to reuse our React Native control. Let's move on and add our component to a WPF application built on top of .NET Core 3.0, since it's the platform that provides the best compatibility with XAML Islands.
\n
\n
Create a new solution in Visual Studio 2019 and chooseWPF (.NET Core)as project's type:
\n
\n
\n
\n
As first step, you need to reference again all the projects required to run React Native and the user control we have created. These are the same ones we have added in the previous scenario:Folly,ReactCommon,ReactUWP,ReactWindowsCoreand the custom controlTodosFeed.Component.
\n
\n
Now we need to setup the whole infrastructure required to support XAML Islands in a WPF application. The official documentation contains a very detailed step-by-step guide, which isavailable here. As such, I won't repeat all the required steps in this post. The only thing to pay attention is that, compared to the documentation, we already have a project which contains a custom control in our scenario. As such, you can skip the step calledCreate a custom UWP control. You just need to make sure to add to the project's file the two properties which are required to make it working with a Win32 application.
\n
\n
Right click on theTodosFeed.Componentproject and chooseUnload Project. Then right click on it again and chooseEdit. Create a newPropertyGroupinside the<Project>element with the following entries:
Then reload the project again and you will be good to go. Just remember to add a reference to theTodosFeed.Componentproject both to the dummy UWP application and the WPF project.
\n
\n
Setup the WPF project
\n
Microsoft provides an easy way to integrate XAML Islands in a WPF application by offering a control that does most of the heavy-lifting for you. The control is calledWindowsXamlHostand it's included in the Windows Community Toolkit. To use it, you need to add the NuGet package calledMicrosoft.Toolkit.Wpf.UI.XamlHostin your WPF application.
\n
The other step is to configure your solution to target a specific platform, since UWP controls can't target the genericAny CPUarchitecture. As such, right click on the solution in Visual Studio and chooseProperties โ Configuration Properties โ Configuration Manager. UnderActive solution platform, chooseNew, then addx64orx86, as you prefer.
\n
\n
All the projects in the dialog should list, under thePlatformcolumn, the same architecture that is defined in theActive solution platformdropdown.
\n
\n
\n
\n
Add the React Native component
\n
Now that the project is setup in the right way, you can add to your WPF application theWindowsXamlHostcontrol we have previously included with the NuGet package. We're going to add it to theMainPage.xamlfile of the WPF application. First, you need to add to theWindowelement the following namespace:
TheInitialTypeNameproperty is set with the full signature of the user control which hosts the React Native component.
\n
Package the application as MSIX
\n
The easiest way to make sure that everything works in the right way with XAML Islands is to package the WPF application as MSIX. However, compared to a traditional application, there are some extra steps to take, in order to make sure that all the files are included in the package in the right way. Make sure to read the section titledPackage the appin the documentationand follow all the steps.
\n
Run it!
\n
That's it! As usual, before testing our WPF app, we need to launch the React packager and the local web server. Once everything is up and running, you can right click on the Windows Application Packaging Project and chooseDeployor press CTRL-F5. The WPF application will start and, if you have done everything properly, you will see your WPF application hosting your familiar React Native component:
\n
\n
\n
\n
Wrapping up
\n
In this (long) blog post we have learned how React Native is a great solution not just to build mobile application, but also Windows experiences. If you're a C# and XAML developer and you're interested in building cross-platform experiences, Xamarin and Xamarin Forms are still the best choice. However, in many cases, you may need to work with a development team with a strong web background and, in such a case, React Native is a great fit. As you have learned in this post, the React Native implementation for Windows is really flexible. Maybe you won't need to build a full UWP application from scratch with React Native, but the framework opens up many opportunities to reuse React Native components built by your web team inside your Windows applications.
\n
\n
React Native for Windows is still a work in progress and, as such, the deployment story isn't available yet. Right now, regardless of the way you compile your React Native for Windows project, you always need the Metro packager up & running in order to render the React content. Of course, this isn't the expected experience for the final user. Once the work on the deployment will be completed, you will be able to create a self-contained MSIX package (like for a regular UWP or Win32 packaged application) and publish it on the Store, share it through a website, deploy with enterprise tools like SSCM or Intune, etc. You can see a glimpse of the expected experience by taking a lookat the deployment story for the current React Native for Windows version.
\n
\n
You can find all the samples mentioned in this articleon GitHub.
\n
\n
Happy coding!
","kudosSumWeight":2,"postTime":"2019-10-14T11:15:38.780-07:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDAyaTg0QzM4NUE1RTFCNUY3NjM?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDAzaUExMTRFMEEyQTY2MURFOTQ?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA0aUZFRUJDNTM4NzRENUYxNEQ?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA1aTJCMjRBM0EyN0M5RkFCOUM?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA2aTc3QjA4QzM5OTE1QTE1MjA?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA3aTUwQzM1MTBEQjYzMDc4NkE?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDc","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA4aTM0MjVBMDRENzU0OEE1OTQ?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDg","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA5aUFBQTI3NUE3QzU4RTlDOTc?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDk","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEwaTY4MkIyMzhEQjMyQkM3OUY?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEw","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDExaUJDNUFENDFFNkI2RDQxODk?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEx","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEyaTcyM0U4NTdDNEJCNkI5NDg?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEy","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEzaTM1RUM3QjM1RTU4NjQ4ODE?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEz","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDE0aTM0ODdFMjUxMkY0MjE1RDI?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE0","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDE1aTgwNTJFNDU2OUZFQ0MyOTY?revision=6\"}"}}],"totalCount":14,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"timeToRead":22,"rawTeaser":"","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:912093_6"},"latestVersion":{"__typename":"FriendlyVersion","major":"3","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":72216},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwzNzM5NDQw","node":{"__ref":"BlogReplyMessage:message:3739440"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwzNzM2MDQz","node":{"__ref":"BlogReplyMessage:message:3736043"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwzNzM1OTgz","node":{"__ref":"BlogReplyMessage:message:3735983"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwzNzM1OTM5","node":{"__ref":"BlogReplyMessage:message:3735939"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxODQ2Mjcx","node":{"__ref":"BlogReplyMessage:message:1846271"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxODQ2MTY5","node":{"__ref":"BlogReplyMessage:message:1846169"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxNTQ5Mzc0","node":{"__ref":"BlogReplyMessage:message:1549374"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxNTI3NTU2","node":{"__ref":"BlogReplyMessage:message:1527556"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxNTI3NTA4","node":{"__ref":"BlogReplyMessage:message:1527508"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxMzkwMTYx","node":{"__ref":"BlogReplyMessage:message:1390161"}}],"pageInfo":{"__typename":"PageInfo","hasNextPage":true,"endCursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzczOTQ0MCwxMzkwMTYx","hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":6}},"Conversation:conversation:912093":{"__typename":"Conversation","id":"conversation:912093","solved":false,"topic":{"__ref":"BlogTopicMessage:message:912093"},"lastPostingActivityTime":"2023-02-10T08:27:47.051-08:00","lastPostTime":"2023-02-10T08:27:47.051-08:00","unreadReplyCount":21,"isSubscribed":false},"ModerationData:moderation_data:912093":{"__typename":"ModerationData","id":"moderation_data:912093","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDAyaTg0QzM4NUE1RTFCNUY3NjM?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDAyaTg0QzM4NUE1RTFCNUY3NjM?revision=6","title":"ReactNativeSolution.png","associationType":"BODY","width":352,"height":219,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDAzaUExMTRFMEEyQTY2MURFOTQ?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDAzaUExMTRFMEEyQTY2MURFOTQ?revision=6","title":"Packager.png","associationType":"BODY","width":2210,"height":1276,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA0aUZFRUJDNTM4NzRENUYxNEQ?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA0aUZFRUJDNTM4NzRENUYxNEQ?revision=6","title":"InstanceFailedToStart.png","associationType":"BODY","width":1659,"height":1296,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA1aTJCMjRBM0EyN0M5RkFCOUM?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA1aTJCMjRBM0EyN0M5RkFCOUM?revision=6","title":"ReactNativeTemplate.png","associationType":"BODY","width":1200,"height":933,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA2aTc3QjA4QzM5OTE1QTE1MjA?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA2aTc3QjA4QzM5OTE1QTE1MjA?revision=6","title":"TodosApp.png","associationType":"BODY","width":585,"height":600,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA3aTUwQzM1MTBEQjYzMDc4NkE?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA3aTUwQzM1MTBEQjYzMDc4NkE?revision=6","title":"TodosFirstVersion.png","associationType":"BODY","width":585,"height":601,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA4aTM0MjVBMDRENzU0OEE1OTQ?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA4aTM0MjVBMDRENzU0OEE1OTQ?revision=6","title":"WindowsRuntimeComponent.png","associationType":"BODY","width":1024,"height":710,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA5aUFBQTI3NUE3QzU4RTlDOTc?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDA5aUFBQTI3NUE3QzU4RTlDOTc?revision=6","title":"InventoryApp.png","associationType":"BODY","width":2668,"height":1607,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEwaTY4MkIyMzhEQjMyQkM3OUY?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEwaTY4MkIyMzhEQjMyQkM3OUY?revision=6","title":"InventorySolution.png","associationType":"BODY","width":444,"height":293,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDExaUJDNUFENDFFNkI2RDQxODk?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDExaUJDNUFENDFFNkI2RDQxODk?revision=6","title":"Dashboard.png","associationType":"BODY","width":1280,"height":873,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEyaTcyM0U4NTdDNEJCNkI5NDg?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEyaTcyM0U4NTdDNEJCNkI5NDg?revision=6","title":"DashboardWithReact.png","associationType":"BODY","width":1280,"height":870,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEzaTM1RUM3QjM1RTU4NjQ4ODE?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDEzaTM1RUM3QjM1RTU4NjQ4ODE?revision=6","title":"WpfNetCore.png","associationType":"BODY","width":1024,"height":710,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDE0aTM0ODdFMjUxMkY0MjE1RDI?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDE0aTM0ODdFMjUxMkY0MjE1RDI?revision=6","title":"CpuArchitecture.png","associationType":"BODY","width":702,"height":443,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDE1aTgwNTJFNDU2OUZFQ0MyOTY?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS05MTIwOTMtMTM3NDE1aTgwNTJFNDU2OUZFQ0MyOTY?revision=6","title":"WpfToDos.png","associationType":"BODY","width":786,"height":443,"altText":null},"Revision:revision:912093_6":{"__typename":"Revision","id":"revision:912093_6","lastEditTime":"2020-05-09T08:27:37.031-07:00"},"CachedAsset:theme:customTheme1-1740560922598":{"__typename":"CachedAsset","id":"theme:customTheme1-1740560922598","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#333333","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1737115705000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1737115705000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1740560920755":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1740560920755","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[{"id":"custom.widget.Social_Sharing","className":null,"props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":true,"title":"Share","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1737115705000","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1740560858594":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1740560858594","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"planner","params":{"categoryId":"Planner"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoft-endpoint-manager"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-q-l-server","params":{"categoryId":"SQL-Server"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"SMB"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1737115705000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-1740560995734":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-1740560995734","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display:block;\n box-shadow:none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size:14px;\n }\n}","texts":null,"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1a5zb_1 {\n a.custom_widget_community_banner_top-bar_1a5zb_2.custom_widget_community_banner_btn_1a5zb_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display:block;\n box-shadow:none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size:0.875rem;\n }\n}","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1a5zb_1","top-bar":"custom_widget_community_banner_top-bar_1a5zb_2","btn":"custom_widget_community_banner_btn_1a5zb_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-1740560995734":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-1740560995734","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search."},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.Social_Sharing-en-1740560995734":{"__typename":"CachedAsset","id":"component:custom.widget.Social_Sharing-en-1740560995734","value":{"component":{"id":"custom.widget.Social_Sharing","template":{"id":"Social_Sharing","markupLanguage":"HANDLEBARS","style":".social-share {\n .sharing-options {\n position: relative;\n margin: 0;\n padding: 0;\n line-height: 10px;\n display: flex;\n justify-content: left;\n gap: 5px;\n list-style-type: none;\n li {\n text-align: left;\n a {\n min-width: 30px;\n min-height: 30px;\n display: block;\n padding: 1px;\n .social-share-linkedin {\n img {\n background-color: rgb(0, 119, 181);\n }\n }\n .social-share-facebook {\n img {\n background-color: rgb(59, 89, 152);\n }\n }\n .social-share-x {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .social-share-rss {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .social-share-reddit {\n img {\n background-color: rgb(255, 69, 0);\n }\n }\n .social-share-email {\n img {\n background-color: rgb(132, 132, 132);\n }\n }\n }\n a {\n img {\n height: 2rem;\n }\n }\n }\n }\n}\n","texts":null,"defaults":{"config":{"applicablePages":[],"description":"Adds buttons to share to various social media websites","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Social_Sharing","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Adds buttons to share to various social media websites","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_Social_Sharing_social-share_c7xxz_1 {\n .custom_widget_Social_Sharing_sharing-options_c7xxz_2 {\n position: relative;\n margin: 0;\n padding: 0;\n line-height: 0.625rem;\n display: flex;\n justify-content: left;\n gap: 0.3125rem;\n list-style-type: none;\n li {\n text-align: left;\n a {\n min-width: 1.875rem;\n min-height: 1.875rem;\n display: block;\n padding: 0.0625rem;\n .custom_widget_Social_Sharing_social-share-linkedin_c7xxz_18 {\n img {\n background-color: rgb(0, 119, 181);\n }\n }\n .custom_widget_Social_Sharing_social-share-facebook_c7xxz_23 {\n img {\n background-color: rgb(59, 89, 152);\n }\n }\n .custom_widget_Social_Sharing_social-share-x_c7xxz_28 {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-rss_c7xxz_33 {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-reddit_c7xxz_38 {\n img {\n background-color: rgb(255, 69, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-email_c7xxz_43 {\n img {\n background-color: rgb(132, 132, 132);\n }\n }\n }\n a {\n img {\n height: 2rem;\n }\n }\n }\n }\n}\n","tokens":{"social-share":"custom_widget_Social_Sharing_social-share_c7xxz_1","sharing-options":"custom_widget_Social_Sharing_sharing-options_c7xxz_2","social-share-linkedin":"custom_widget_Social_Sharing_social-share-linkedin_c7xxz_18","social-share-facebook":"custom_widget_Social_Sharing_social-share-facebook_c7xxz_23","social-share-x":"custom_widget_Social_Sharing_social-share-x_c7xxz_28","social-share-rss":"custom_widget_Social_Sharing_social-share-rss_c7xxz_33","social-share-reddit":"custom_widget_Social_Sharing_social-share-reddit_c7xxz_38","social-share-email":"custom_widget_Social_Sharing_social-share-email_c7xxz_43"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-1740560995734":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-1740560995734","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_f95yq_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_f95yq_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_f95yq_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_f95yq_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_f95yq_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_f95yq_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_f95yq_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_f95yq_78.custom_widget_MicrosoftFooter_f-bare_f95yq_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_f95yq_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_f95yq_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_f95yq_78.custom_widget_MicrosoftFooter_f-bare_f95yq_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_f95yq_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_f95yq_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_f95yq_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_f95yq_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_f95yq_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_f95yq_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_f95yq_58","c-list":"custom_widget_MicrosoftFooter_c-list_f95yq_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_f95yq_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_f95yq_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1737115705000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1737115705000","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Planner":{"__typename":"Category","id":"category:Planner","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:SQL-Server":{"__typename":"Category","id":"category:SQL-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:SMB":{"__typename":"Category","id":"category:SMB","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-endpoint-manager":{"__typename":"Category","id":"category:microsoft-endpoint-manager","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:912093:6":{"__typename":"QueryVariables","id":"TopicReplyList:message:912093:6","value":{"id":"message:912093","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1737115705000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Small and Medium Businesses","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","microsoft-learn":"Microsoft Learn","s-q-l-server":"SQL Server","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Planner","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune and Configuration Manager","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","outlook":"Outlook","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1737115705000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1737115705000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1737115705000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1737115705000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1737115705000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1737115705000","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1737115705000","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1737115705000","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"ModerationData:moderation_data:3739440":{"__typename":"ModerationData","id":"moderation_data:3739440","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:3739440":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:44595"},"id":"message:3739440","revisionNum":1,"uid":3739440,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:3739440"},"body":"
I would try to open an issue on the official RNW repository on GitHub, so that the team can help you in diagnosing the issue. From my side, unfortunately, I'm not able to reproduce it. I just tried to create a new RNW 0.71 project and to generate a Release package and I can see the application starting up without having the Metro debugger running in background.
\n
\n
Best
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"213","kudosSumWeight":0,"repliesCount":0,"postTime":"2023-02-10T08:27:47.051-08:00","lastPublishTime":"2023-02-10T08:27:47.051-08:00","metrics":{"__typename":"MessageMetrics","views":9964},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:3739440","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Rank:rank:37":{"__typename":"Rank","id":"rank:37","position":17,"name":"Copper Contributor","color":"333333","icon":null,"rankStyle":"TEXT"},"User:user:1722436":{"__typename":"User","id":"user:1722436","uid":1722436,"login":"arun986","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2023-02-07T03:09:13.649-08:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-3.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:1722436"},"ModerationData:moderation_data:3736043":{"__typename":"ModerationData","id":"moderation_data:3736043","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:3736043":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:1722436"},"id":"message:3736043","revisionNum":1,"uid":3736043,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:3736043"},"body":"
Regrading the metro issue, I want to elaborate little more, as I did fresh build to rule this out. In my machine there was no previous release package installed. But it still did not work. Moreover one of my colleague also did same steps and he is getting same issue.
Any pointers to look where is the issue would be much appreciated.
Few more details:
I have used below command to create my react-native application:
My system specs: Windows 11 OS and Visual Studio 2022 professional
BR,
Arun Rastogi
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"218","kudosSumWeight":0,"repliesCount":0,"postTime":"2023-02-07T05:36:52.777-08:00","lastPublishTime":"2023-02-07T05:36:52.777-08:00","metrics":{"__typename":"MessageMetrics","views":9965},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:3736043","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"ModerationData:moderation_data:3735983":{"__typename":"ModerationData","id":"moderation_data:3735983","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:3735983":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:44595"},"id":"message:3735983","revisionNum":1,"uid":3735983,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:3735983"},"body":"
Hello Arun,
\n
regarding the long building time, unfortunately that's expected. When you generate the package for distribution, Visual Studio rebuilds the whole solution from scratch and, since React Native is added through the whole source code, it takes a long time to build the C++ core. Things should improve if and when the team will be able to move the RNW core to NuGet, so that you don't have to rebuild it every time.
\n
Regarding the Metro issue, that's weird. A Release package shouldn't ask you to connect to Metro, since the JS bundle is embedded into the package. Make sure to uninstall all the instances of your application before deploying the Release package, there might be some conflicts because both packages you use for debugging and for distribution share the same unique identifier (the package family name).
\n
\n
Best
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"203","kudosSumWeight":0,"repliesCount":0,"postTime":"2023-02-07T04:26:26.976-08:00","lastPublishTime":"2023-02-07T04:26:26.976-08:00","metrics":{"__typename":"MessageMetrics","views":10025},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:3735983","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"ModerationData:moderation_data:3735939":{"__typename":"ModerationData","id":"moderation_data:3735939","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:3735939":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:1722436"},"id":"message:3735939","revisionNum":2,"uid":3735939,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:3735939"},"body":"
I have tried below steps to publish my React Native application for windows:
Open the solution in Visual Studio
Select the Release configuration from the Configuration Manager drop-down.
Build the solution. You can now launch without first launching Metro.
If you want to build an APPX package to share or publish, use theProject>Publish>Create App Packages...option.
Observations: For building the app it takes a hell lot of time (more than 30 mins) and after completing build successfully I'm not able to launch my RN application without Metro. It gives me error \"A connection with the server could not be established\" (see below error screen-shot).
After publishing I see there is an react-native application automatically installed into my system with the same name of my application and upon double clicking it I'm getting same error.
Error screen-shot:
Could you please advice me how we can create React Native application for Windows project, standalone package which will work without explicitly running Metro (without running npm start command).
Thanks in advance!
BR,
Arun Rastogi
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"223","kudosSumWeight":0,"repliesCount":0,"postTime":"2023-02-07T03:28:17.386-08:00","lastPublishTime":"2023-02-07T04:17:15.637-08:00","metrics":{"__typename":"MessageMetrics","views":10009},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:3735939","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"ModerationData:moderation_data:1846271":{"__typename":"ModerationData","id":"moderation_data:1846271","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:1846271":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:44595"},"id":"message:1846271","revisionNum":1,"uid":1846271,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:1846271"},"body":"
Hello brodman_apterainc , a React Native for Windows application is, in the end, a UWP app, so the same techniques to do CI/CD for UWP apps will work. You can absolutely publish the app on the Store, as well.
Let me know if you're hitting any specific problem and I'll be happy to help.
\n
\n
Best
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"213","kudosSumWeight":1,"repliesCount":0,"postTime":"2020-11-02T12:16:39.826-08:00","lastPublishTime":"2020-11-02T12:16:39.826-08:00","metrics":{"__typename":"MessageMetrics","views":29916},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:1846271","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"User:user:855016":{"__typename":"User","id":"user:855016","uid":855016,"login":"brodman_apterainc","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2020-11-02T11:51:01.959-08:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-11.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:855016"},"ModerationData:moderation_data:1846169":{"__typename":"ModerationData","id":"moderation_data:1846169","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:1846169":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:855016"},"id":"message:1846169","revisionNum":1,"uid":1846169,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:1846169"},"body":"
Matteo Pagani do we have any updated documentation on building/publishing a react native windows app into an appx in a CI/CD environment (specifically Azure DevOps)? I will be side-loading so even if Store publishing is not ready yet, any docs you can point to would be helpful.
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"213","kudosSumWeight":0,"repliesCount":0,"postTime":"2020-11-02T11:56:09.637-08:00","lastPublishTime":"2020-11-02T11:56:09.637-08:00","metrics":{"__typename":"MessageMetrics","views":29922},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:1846169","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[]},"ModerationData:moderation_data:1549374":{"__typename":"ModerationData","id":"moderation_data:1549374","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:1549374":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:44595"},"id":"message:1549374","revisionNum":1,"uid":1549374,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:1549374"},"body":"
Hello nanduahmed I can confirm that React Native for Windows 0.62 has fixed the problem. If you move your project to the latest React Native version, the XAML Island project will work just fine. I have submitted a PR with the required changes to the sample. In the meantime, if you are eager to give it a try, you can check my fork: https://github.com/qmatteoq/react-native-windows-samples/tree/master/samples/TodosFeed
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"213","kudosSumWeight":0,"repliesCount":0,"postTime":"2020-07-27T23:32:19.661-07:00","lastPublishTime":"2020-07-27T23:32:19.661-07:00","metrics":{"__typename":"MessageMetrics","views":33824},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:1549374","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[]},"ModerationData:moderation_data:1527556":{"__typename":"ModerationData","id":"moderation_data:1527556","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:1527556":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:44595"},"id":"message:1527556","revisionNum":1,"uid":1527556,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:1527556"},"body":"
Hi nanduahmed unfortunately no, there are still some issues. I'm currently on vacation and I'll get back at the end of the month. I will follow up with the team as soon as I'm back.
\n
\n
Thanks for your patience
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"213","kudosSumWeight":0,"repliesCount":0,"postTime":"2020-07-16T12:57:41.434-07:00","lastPublishTime":"2020-07-16T12:57:41.434-07:00","metrics":{"__typename":"MessageMetrics","views":34349},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:1527556","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[]},"User:user:731156":{"__typename":"User","id":"user:731156","uid":731156,"login":"nanduahmed","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2020-07-16T12:35:49.268-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-6.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:731156"},"ModerationData:moderation_data:1527508":{"__typename":"ModerationData","id":"moderation_data:1527508","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:1527508":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:731156"},"id":"message:1527508","revisionNum":1,"uid":1527508,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:1527508"},"body":"
Hi Matteo Pagani, Is the XAML islands issue fixed now? Do you have any good update to share?
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"105","kudosSumWeight":0,"repliesCount":0,"postTime":"2020-07-16T12:39:12.772-07:00","lastPublishTime":"2020-07-16T12:39:12.772-07:00","metrics":{"__typename":"MessageMetrics","views":34366},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:1527508","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[]},"User:user:601893":{"__typename":"User","id":"user:601893","uid":601893,"login":"nahmed215","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2020-03-30T18:19:57.968-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-7.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:601893"},"ModerationData:moderation_data:1390161":{"__typename":"ModerationData","id":"moderation_data:1390161","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:1390161":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:601893"},"id":"message:1390161","revisionNum":1,"uid":1390161,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:912093"},"conversation":{"__ref":"Conversation:conversation:912093"},"subject":"Re: Getting started with React Native for Windows","moderationData":{"__ref":"ModerationData:moderation_data:1390161"},"body":"
I appreciate your response. I hope this should be solved in the next version.
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"126","kudosSumWeight":0,"repliesCount":0,"postTime":"2020-05-14T11:44:15.211-07:00","lastPublishTime":"2020-05-14T11:44:15.211-07:00","metrics":{"__typename":"MessageMetrics","views":38017},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:912093/message:1390161","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[]},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1737115705000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1737115705000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1737115705000","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1737115705000","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1737115705000","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1737115705000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1737115705000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1737115705000","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1737115705000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1737115705000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1737115705000","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1737115705000","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1737115705000","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1737115705000","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1737115705000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1737115705000","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1737115705000","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1737115705000","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1737115705000","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMorePreviousNextLinkable-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Pager/PagerLoadMorePreviousNextLinkable-1737115705000","value":{"loadMore":"Show More"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1737115705000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1737115705000","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"modernworkappconsult","messageSubject":"getting-started-with-react-native-for-windows","messageId":"912093"},"buildId":"rBSXYkarBGCCgv-Fy0Q8w","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.1.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/external/components/ExternalComponent.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","../shared/client/components/common/List/UnstyledList/UnstyledList.tsx","./components/messages/MessageView/MessageView.tsx","../shared/client/components/common/Pager/PagerLoadMorePreviousNextLinkable/PagerLoadMorePreviousNextLinkable.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1729284608000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Amodernworkappconsult&entity.id=message%3A912093","strategy":"afterInteractive"}]}