Revolutionise Your Content Management: Building Custom Apps for Contentful

  • user
    Ryan
Revolutionise Your Content Management: Building Custom Apps for Contentful

Integrating with Contentful is a quick and easy way to give non-developers Control over site content. But what if you want more?

Out of the box

Before we start talking about how to customise Contentful and get “more”, lets quickly talk through what the out of the box experience looks like.

The first step is to model the content types in the Contentful web app. Your content models can define fields as text, images, dates, booleans, JSON objects, locations, and references to other content nodes. You can set up restrictions so to ensure your content is created as expected - for example only accept certain string values, only refer to certain content types, limit character counts etc.

Then use the Contentful GraphQL API to fetch content and build components to render the site. There are template content models and apps to help get started quickly. So far so good, we have an impressive amount of control over the content that will be shown to users.

Image of two people building a web page

Say Hello to Contentful Apps

Over time you might realise that your content model has grown complex, a field is difficult for an editor to fill in, or you really want to use AI and integrate with <SERVICE>. Custom Contentful apps extend the Contentful web app and let you do all these things!

The Contentful app marketplace contains apps published publicly for anyone to use. This is the place to be if you want common functionality like:

  • Load or generate content - Ecommerce platforms, AI Generation, various translation services to name a few
  • Add generic functionality like a nicer JSON display, conditional fields, new field types or set a focal point on images at different screen sizes
  • Integrate with popular services - Push updates to AWS, load ticket data from Jira, send slack notifications, etc.

Custom Apps

If there’s a niche service you want to integrate with, you want to preview content using your custom components or want bespoke functionality that isn’t available on the marketplace you can use the Contentful app framework to make it happen. Let’s look an example to get an idea how they’re built.

Controlling Content Deployments to Github

When you work on content you will only see changes over the API if you publish your changes. If your site is statically generated you might be using webhooks to trigger new builds of your site when content is published. A common requirement is the ability to disable publishing. Separating publishing from deployment to give editors more control and less waiting on support tasks, but also reduces time & cost of workflows running when lots of content is published serially. This is the perfect use case for a custom app.

Getting Started

$ npx create-contentful-app my-first-app
$ tree -I '*.spec.tsx'
    .
    ├── components
       └── LocalhostWarning.tsx
    ├── locations
       ├── ConfigScreen.tsx
       ├── Dialog.tsx
       ├── EntryEditor.tsx
       ├── Field.tsx
       ├── Home.tsx
       ├── Page.tsx
       └── Sidebar.tsx
    ├── App.tsx
    ├── index.tsx
    ├── react-app-env.d.ts
    └── setupTests.ts

Running the npm package to generate a custom app gives us the above folder structure. There’s quite a lot going on here but what’s important is the locations folder, this is how you slot your custom functionality into different parts of the Contentful web app. They directly relate to the locations in app config in Contentful. Lets set up the app config to use the Page location, then the React code in Page.tsx will be rendered as a separate Page in Contentful.

Screenshot of Contentful app config for a custom page app

Now that our component can be accessed as a custom page in Contentful it’s time to make it do something. The app framework provides an SDK React hook, which gives us an easy way to query and manage content. We want our app to deploy published content so lets use it to get content entries ordered by the date they were last published at.

 const sdk = useSDK<PageAppSDK>();
 const content = await sdk.cma.entry.getMany({
   spaceId: sdk.ids.space,
   environmentId: sdk.ids.environment,
   query: {
     order: "-sys.publishedAt",
   },
 });

Integrating

The next thing to figure out is how we can integrate with Github to deploy. The SDK comes with a function for request signing so that we can verify a HTTP request has actually come from Contentful. So, we can host a secure API that manages the integration with Github which verifies the request before triggering the deployment. Contentful has packages for doing this in Node, and has an explanation for how it works in case you want to implement it in other languages. Given the low and inconsistent traffic, serverless functions are a great place to put this integration logic. We can set up two functions, one to fetch previous workflow runs and another to trigger the workflow.

 // building the client request
 const { additionalHeaders } = await sdk.cma.appSignedRequest.create({
     appDefinitionId: sdk.ids.app!,
   },
   {
     path: new URL(req.url).pathname,
     headers: req.headers,
     method: "POST",
     body: req.body,
 });

 // verify the request on the server
 import { verifyRequest } from "@contentful/node-apps-toolkit";
 const isValid = verifyRequest(process.env["CONTENTFUL_SIGNING_SECRET"], request);

Bringing it all together and we can finish our app by deploying to Contentful. Our users can now see the most recently updated content, easily identify what still needs to be deployed, and run pipelines to update the site.

Screenshot of a list of content on a custom page app in Contentful

This blog post wasn’t intended to be a complete tutorial on how to implement custom apps but there are great docs from Contentful to give you more detail, and explain anything we didn’t cover, like hosting functions using Contentfuls infrastructure.

Hopefully this has given you an idea of what’s possible in Contentful and how to architect a custom app that can pretty much do anything.

Tags:
Get in touch

Let’s do something great