Skip to main content

Adding Kontent data

tip

This tutorial assumes you have completed the basic tutorial and have the artifacts from that already present in Uniform.

Let's add some content data from Kontent into your Uniform Canvas-powered Next app. To do this we will need to add a new Kontent-powered parameter to your component type, and then tell your Next app how to fetch and parse the Kontent data to display it. Canvas provides a framework for enhancing data in your Canvas composition with data from other tools, like CMSes, DAMs, commerce, and search indexes. This enhancement is done on the app side, leaving full flexibility to the developer as to the best and most efficient way to get the data.

First let's connect Uniform to Kontent by installing the integration. You'll need a Kontent account to do this (a free one is fine).

  1. Go to Settings on your on https://uniform.app project, then click Integrations
  2. Find the Kontent integration and add it
  3. Click the button to add a content source
  4. Provide the Project ID, Management API Key, and Preview API Key for the Kontent project that you want to bring content from into Canvas

Now that we're connected to Kontent, we can add a new parameter to our Canvas component type that links to a Kontent item.

  1. Go to your Component Library settings
  2. Open your component type (there should be only one, if you've been following along)
  3. Click (+) next to Parameters
  4. Name your parameter something like 'Kontent Item', choose Kontent Item as the type, pick a Kontent source (project) from which items will be selected, pick Kontent content type(s) that can be linked, and as before choose a public ID to use as the name in code. (e.g. kontentItem)

Now that the parameter is added to the component type, we need to link the composition we have been rendering to an actual Kontent item:

  1. Click Compositions, then open your composition from earlier
  2. You should see a Kontent parameter alongside the text parameter we created before
  3. Choose a Kontent item to link to and save your composition
  4. That's it - you've linked to a Kontent item in your composition

With the data schema setup complete, now let's set up Next.js. Right now we're doing nothing with the Kontent data - the Next app will look exactly the same as it did before, except it has a new parameter we're doing nothing with. To get the Kontent data, we need to add an enhancer to the Next app's data fetching so that Canvas knows what to do with Kontent parameters.

  1. If your Kontent Delivery API is secured (by default the Delivery API is not secured), you will need your Kontent Delivery API token, which can be found in your Kontent project settings for the content source you selected in the Kontent Canvas integration settings.

  2. Install the @uniformdev/canvas-kontent and @kentico/kontent-delivery packages, which contains the Canvas Kontent enhancer and the Kontent Delivery JS SDK respectively.

  3. Open your pages/index.js file and import the Kontent enhancer, and add enhance to the existing canvas import:

    import {
    createKontentEnhancer,
    CANVAS_KONTENT_PARAMETER_TYPES,
    KontentClientList,
    } from '@uniformdev/canvas-kontent';
    import { enhance, CanvasClient, EnhancerBuilder } from '@uniformdev/canvas';
    import { DeliveryClient } from '@kentico/kontent-delivery';
  4. In getStaticProps, create the enhancer and configure it to connect to Kontent and enhance your composition data:

    // ...fetching the composition here

    // create the Kontent client
    const client = new DeliveryClient({
    // NOTE: for production code ensure you use environment variables to
    // configure Kontent, not hard-coded values.
    projectId: 'your-kontent-project-id',
    // note: secureApiKey is only necessary if your delivery API is secured
    secureApiKey: 'optional-kontent-delivery-api-key',
    });

    // create the Kontent enhancer
    const kontentEnhancer = createKontentEnhancer({ clients: new KontentClientList({ client }) });

    // apply the enhancers to the composition data, enhancing it with external data
    // In this case, the _value_ of the Kontent parameter you created is enhanced
    // with data from the Kontent item you selected in the Kontent item selector.
    // You can create your own enhancers easily; they are a simple function.
    await enhance({
    composition,
    enhancers: new EnhancerBuilder().parameterType(CANVAS_KONTENT_PARAMETER_TYPES, kontentEnhancer),
    context: {},
    });

    // ...returning the props

    The Next app should still be working, but we're not rendering any of the Kontent data yet. Let's do that!

  5. In the Home component implementation, get the Kontent parameter value and pick a field from it:

    export default function Home({ composition }) {
    return (
    <Composition data={composition}>
    {/* note: `kontentItem` is the "public id" value you provided for
    the Kontent Item parameter. */}
    {({ greeting, kontentItem }) => (
    <article>
    <p>{greeting}</p>
    {/* we assume your item type has a field called 'title' on it */}
    <p>{kontentItem.elements.title.value}</p>
    </article>
    )}
    </Composition>
    );
    }
  6. That's it - now you're rendering data from Kontent! The default structure of the enhancer result is that of a single Kontent item fetched from the Kontent Entry API.

tip

Use TypeScript? So do we. Here's the same code with TypeScript.

TypeScript Code
import { enhance, CanvasClient, EnhancerBuilder, ComponentInstance } from '@uniformdev/canvas';
import { Composition } from '@uniformdev/canvas-react';
import {
KontentEnhancerResult,
createKontentEnhancer,
KontentClientList,
CANVAS_KONTENT_PARAMETER_TYPES,
} from '@uniformdev/canvas-kontent';
import { DeliveryClient } from '@kentico/kontent-delivery';
import { GetStaticProps } from 'next';

type HomeProps = {
composition: ComponentInstance;
};

type MyCanvasComponentType = {
greeting: string;
kontentItem: KontentEnhancerResult;
};

export default function Home({ composition }: HomeProps) {
return (
<Composition<MyCanvasComponentType> data={composition}>
{({ greeting, kontentItem }) => (
<article>
<p>{greeting}</p>
<p>{kontentItem.elements.title.value}</p>
</article>
)}
</Composition>
);
}

export const getStaticProps: GetStaticProps<HomeProps> = async () => {
// create the Canvas client
const canvasClient = new CanvasClient({
// if this weren't a tutorial, ↙ should be in an environment variable :)
apiKey: 'your-api-key-here',
// if this weren't a tutorial, ↙ should be in an environment variable :)
projectId: 'your-project-id-here',
});

// fetch the composition from Canvas
const { composition } = await canvasClient.getCompositionBySlug({
// if you used something else as your slug, use that here instead
slug: '/',
});

const client = new DeliveryClient({
projectId: 'your-kontent-project-id',
secureApiKey: 'optional-kontent-delivery-api-key',
});

const kontentEnhancer = createKontentEnhancer({ clients: new KontentClientList({ client }) });

await enhance({
composition,
enhancers: new EnhancerBuilder().parameterType(CANVAS_KONTENT_PARAMETER_TYPES, kontentEnhancer),
context: {},
});

return {
props: {
composition,
},
};
};