Skip to main content
Skip table of contents

4.0 Creating a simple React app

Introduction

In this tutorial you’ll learn how to:

  • Create a Consumer Application

  • Retrieve content using the SDK

  • Display your content in a React app

What you’ll create

A Consumer Application with a React front-end that fetches and displays your content.

The outcome should look something like the following, depending on the images you use:

image-20240703-150643.png

Your content retrieved from the CMS and displayed in a grid in a React component

Before you begin…

Before writing the Consumer Application, you must complete the following prerequisite steps:

  1. Add content to the CMS

  2. Create the Visual Studio project

  3. Add the Forrit package source

  4. Install the Forrit packages (the SDK)

  5. Obtain configuration information (from Azure or Service Delivery Hub)

  6. Authenticate Visual Studio with Azure Services

1. Add content to the CMS

You can skip this step if you wish to pull down existing content – but if so you must:

  • Ensure the content has been published to your Consumer Application

  • Update the referenced object properties in the ImagesControllerlater

Before you can consume your content, you must first add it to the CMS and publish it.

  1. Create a Task

    1. Create a new Task to safely learn in during this tutorial

  2. Add Media Items

    1. Upload the images that will be used in your content

  3. Add a Content Type

    1. Add the Content Type of your content – use the example below if you wish to use the code snippets later without modification (you don’t need the hints)

      image-20240628-145913.png

      The Content Type used in this tutorial

  4. Add Content Entries

    1. Add the units of actual content that you’ll retrieve – for example:

      image-20240628-150035.png

      One of the Content Entries used in this tutorial

  5. Create a Release

    1. Create a Release from your Task

  6. Publish to a Consumer Application

    1. Publish the Release to a non-production (e.g. staging) Consumer Application

It’s not recommended that you publish to a production Consumer Application during this tutorial. However, if you wish, you can do so by reviewing and completing your Task, creating a Release from the Approved Content, and then choosing a production environment when publishing.

2. Create the Visual Studio project

  1. Click FileNewProject...

  2. Select the React and ASP.NET Core (TypeScript) template

  3. Choose a name (e.g. ReactTutorial) and a location for the project

    1. If you choose a different name, remember to replace the namespaces in the code later

  4. Select .NET 8.0 (Long Term Support)

  5. Click Create

image-20240703-143243.png

The Visual Studio project creation screen for React and ASP.NET Core template

3. Add the Forrit package source

As this is a private package, you must first be granted access by Forrit.

  1. Select ToolsNuGet Package ManagerPackage Manager SettingsPackage Sources

  2. Add the following package source:

    1. Name: Forrit

    2. Source: https://forrit.pkgs.visualstudio.com/_packaging/cortex-sdk/nuget/v3/index.json

  3. Keep your existing package sources selected as shown in the image below

  4. You may have to reboot Visual Studio and enter credentials

image-20240701-102310.png

NuGet Package Sources

4. Install the Forrit packages

  1. Select ToolsNuget Package ManagerManage NuGet Packages for Solution...

  2. Change the package source to Forrit

  3. For the server project, install the latest (4.x version):

    1. Forrit.Consumers

    2. Forrit.Consumers.Types

image-20240701-102404.png

The Forrit NuGe packages

5. Obtain configuration from Service Delivery Hub

If you aren’t set up with Service Delivery Hub, you can instead retrieve the information directly from Azure. For more information about how to do this, see4.0 Retrieving configuration information from Azure.

Keep a note of the details in the following steps; you’ll need them later.

1. Tenant ID

You can find your Tenant ID below the tenant name, as outlined below.

image-20241003-143826.png

2. Connection strings

To get the connection string information, first select the CMS instance.

image-20241003-143859.png

Scroll down and click More info for the relevant Project.

image-20241003-144017.png

Click the connection strings button for your Consumer Application.

image-20241003-144142.png

Note the consumer key.

image-20241003-141600.png

And the service bus namespace, the releases SAS URL and the manifests SAS URL:

image-20241003-143357.png

If the Service Bus namespace is incorrect here, you can also find it in the App Config section:

image-20241003-144430.png

6. Authenticate with Azure Services in Visual Studio

  • In Visual Studio, go to ToolsOptionsAzure Service Authentication and choose an account to authenticate

    image-20240701-125253.png

    Visual Studio Azure Service Authentication

Write the Consumer Application

With the setup all done, you’re now ready to develop a Consumer Application with a React front-end, by completing the following steps:

  1. Add CMS connection settings

  2. Add Forrit CMS services

  3. Create an API for your content

  4. Consume your content with React

  5. Run the project

1. Add CMS connection settings

In appsettings.json, add the following configuration block and replace the values with your information from the Service Delivery Hub (or Azure):

JSON
  "FCMS": {
    "ConsumerKey": "{consumer-app-id}",
    "ManifestsContainerSas": "{manifests-container-sas-url}",
    "ReleasesSas": "{releases-table-sas-url}",
    "ServiceBusNamespace": "https://{service-bus-namespace}",
    "TenantId": "{tenant-id}",
    "DefaultLocale": "{default-locale-short-code}"
  }

This is used by the SDK to connect to and retrieve content from Azure.

2. Add Forrit CMS services

In Program.cs, add the following reference:

C#
using Forrit.Consumers.Extensions;

And the following lines of code:

C#
builder.Services.AddHttpContextAccessor();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddForritCmsServices(builder.Configuration);

This adds services you can use to readily retrieve CMS content, such as:

  • The ManifestsService – retrieves Page content

  • The RoutingService – retrieves and sets up routings defined in the CMS Routing Manager

  • The ContentService (used in this tutorial) – retrieves Content Types and Content Entries

3. Create an API for your content

Update the config

In the client project, update vite.config.ts:

  • Update the proxy property from '^/weatherforecast' to '^/api/images'

In the server project, update ReactTutorial.Server.http:

  • Update the end of the GET address from /weatherforecast/ to /api/images/

Add the controller

In the server project, add a new controller called ImagesControllerwith the following code:

C#
using Forrit.Consumers.Models;
using Forrit.Consumers.Services;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

namespace ReactTutorial.Server.Controllers
{
    [ApiController]
    public class ImagesController : ControllerBase
    {
        private readonly IContentService _contentService;
        private readonly IConfiguration _configuration;

        public ImagesController(IContentService contentService, IConfiguration configuration)
        {
            _contentService = contentService;
            _configuration = configuration;
        }

        [HttpGet("api/images")]
        public async Task<IActionResult> GetImagesAsync([FromQuery] string? locale)
        {
            // Use the default locale from config if none is given
            string localeShortCode = locale ?? _configuration.GetValue<string>("FCMS:DefaultLocale");

            // Fetch your Content Entries
            List<ContentEntryResponse> contentEntryResponses
                = await _contentService.GetContentEntriesForTypeAsync("Image");

            // Select each entry's content for the given locale
            IEnumerable<object> localeContentEntries = contentEntryResponses

                .Select(contentEntryResponse => GetLocaleContentEntry(contentEntryResponse, localeShortCode));
            return Ok(localeContentEntries);
        }

        private object GetLocaleContentEntry(ContentEntryResponse contentEntryResponse, string localeShortCode)
        {
            string localeContent = contentEntryResponse.LocaleContentEntries
                .First(localeContentEntry => localeContentEntry.LocaleShortCode == localeShortCode).Content;

            return new
            {
                Name = contentEntryResponse.Name,
                Content = JsonSerializer.Deserialize<object>(localeContent)
            };
        }
    }
}

Note that this requires that an "Image" Content Type is published to your Consumer Application.

Remember to update the namespace if you chose a different name for your project.

ImagesController operation

  • When a client requests /api/images, the ImagesControlleruses the SDK’s ContentService to retrieve all of the Content Entries for the “Image" Content Type

  • The ImagesControllerthen returns only the Content Entries for the requested Locale (based on the locale URL query parameter – or the default from your configuration file if none is given)

4. Consume your content with React

The following steps use React to fetch and display your content.

Fetch content with React

Replace src/App.tsx with the following:

HTML
import { useEffect, useState } from 'react';
import './App.css';

interface Images {
    name: string;
    content: {
        Image: string;
        AltText: string;
    }
}

function App() {
    const [images, setImages] = useState<Images[]>();

    useEffect(() => {
        fetchImages();
    }, []);

    const contents = images === undefined
        ? <p><em>Loading... Please refresh once the ASP.NET backend has started. See <a href="https://aka.ms/jspsintegrationreact">https://aka.ms/jspsintegrationreact</a> for more details.</em></p>
        : <div className="grid">
            {images.map(image =>
                <img
                    className="grid-item"
                    key={image.name}
                    src={image.content.Image}
                    alt={image.content.AltText}
                />
            )}
        </div>

    return (
        <div>
            <h1>React example</h1>
            <p>This component demonstrates fetching your content </p>
            {contents}
        </div>
    );

    async function fetchImages() {
        const response = await fetch('api/images?locale=en-GB');
        const data = await response.json();
        setImages(data);
    }
}

export default App;

Note that this example depends on your content having:

  • An Image field of type Media Item

  • An AltText field of the text type

App.tsx operation
  • Creates a component that fetches content from your API and displays it in a grid

    • To retrieve content from another Locale, change the query string ?locale=en-GB in the above code

Add styling

In src/App.css, add the following:

CSS
body {
    background: #FFFAFA;
}

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    gap: 10px;
}

.grid-item {
    width: 300px;
    height: 600px;
    object-fit: cover;
}

5. Run the project

To see the project in action, complete the following steps:

  • Run the Visual Studio project

image-20240703-151423.png
  • Wait for the server to start up, then refresh the page to retrieve your content – for example:

    image-20240703-150712.png

    Your content displayed in a grid in a React component

If you have added appropriate content to the CMS and published it to the Consumer Application, you should see it displayed in a grid.

Tutorial outcome

In this tutorial, you have:

  • Created a basic Consumer Application

  • Used the SDK to retrieve your CMS content

  • Displayed the content in a React application

Note that the code in this tutorial has been simplified for demonstration purposes and is not suitable for production.

Troubleshooting

If you’re having issues with this tutorial, see the following troubleshooting sections.

Azure authentication

If you’re receiving Azure authentication errors, try:

  • Rebooting Visual Studio and reauthenticating:

    • Go to ToolsOptionsAzure Service Authentication, and choose an account to authenticate

  • You may need to install the Azure authentication package (azd) and run azd auth login

  • Ensuring that the Shared Access Signature URLs have not expired

  • Checking that the SAS URLs are assigned to the correct keys in your config

NuGet package installation

If you’re having issues installing the NuGet packages:

  • Make sure you haven’t deselected your existing package sources

  • Ensure you have received access to the private NuGet source from Forrit

Missing content

  • Make sure your Release is the latest one to be published to the target Consumer Application

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.