If you are a content creator for the web, you may have used the Open Graph protocol. The Open Graph protocol is a way to display and share information about your resource on the internet. You may have seen these in action when sharing websites and URLs on Twitter and Facebook, or when you are chatting with your coworkers on Slack. The preview and metadata for the link is shown to the user as in the Twitter post below.
Building an app on the App Framework can be as simple as creating a single custom button or as complicated as composing multiple components in different locations of Contentful. I want to run through an example app I’ve created which makes use of the App Framework’s ability to handle complexity, but more importantly shows how to pass data between different app locations.
In Contentful, we can create our own Open Graph data by making use of a simple content type that provides the user with the necessary fields to show these kinds of previews. Then, using the App Framework, we can augment the editor experience to allow for automated title generation of our content as well as a visual preview.
In this post, we will cover two things:
Creating a content type to handle simple Open Graph data.
Creating an app which helps visualize the data and allows for a preview mode.
When all is said and done, our Open Graph content type will still need to be pulled from a Contentful API response when we generate our web pages. The information contained in an Open Graph entry will be enough information to populate meta tags in the head of our HTML filles. Let’s get started!
Creating the content type
We can start by creating a new content type in our space called “Open Graph,” which will have five fields:
Title: short text
Content: single reference (in our case, referencing blog posts)
Type: short text
URL: short text
This content type does a few things. First, it allows editors to pick a reference entry. In many cases, this could be a blog post, web page, link or other type of media. In our example, we will be using the Open Graph content type in a blog. This means our Content reference field will reference “Blog Post” content types.
Second, we can automate the “Title” field by asking the editor to select a blog post and grabbing the title from that post. This is something we will look at when we dive into the code.
Lastly, we can create a custom button that will show the editor a preview of our Open Graph data as it might appear in a card UI such as Twitter or Facebook.
Now that we have our content type set up, let’s start developing our app.
Creating the app
For those that are familiar with the App Framework and want to see the source code of the app, you can see it here on GitHub. For those less familiar, I’ve written a few tutorials in the past about how to build apps. We also have a tutorial for beginners, Building your first app, where we explain all the necessary steps to get up and running.
An app is a single page application that runs inside of an iframe and can be rendered in different locations inside of the Contentful Web App. While building an app can be done using any framework (or lack thereof), I’m going to use the Create Contentful App CLI tool, which will bootstrap a React app with all the necessary logic required to get up and running inside of Contentful's React CMS capabilities.
To initialize and run our app locally, run these commands in your terminal:
The app is now running as a single page application on http://localhost:3000. In order to see our app in Contentful, we will need to create an AppDefinition and assign our app to show up in the correct locations.
Creating the AppDefinition
An AppDefinition is the entity that represents an app in Contentful. It contains general app information, like where it is visible. It also provides settings that enable it to run independently, or enable particular settings for any current and future installations.
Note: In order to create an AppDefinition, you must be a Contentful organization admin or developer. If you are not, you can ask your admin for access or sign up for a free Contentful account to use as a sandbox.
Let’s create a new AppDefinition. Go to your organization settings. In the top menu, select Apps. From here we will create a new AppDefinition with the following properties:
Name: Open Graph
App URL: http://localhost:3000 (remember this is running on our machine)
First location: Field - short text
Second location: Page
Once filled in, hit the Create button in the top-right corner. Next, let’s install our app into the space where we created our Open Graph content type.
Installing and developing the app
To install the app, head over to the space where we created our Open Graph content type. In the Apps menu bar, click “Manage apps” then find the Open Graph app in the list of available apps (it will show up with a private tag next to it). Click Install.
Once our app is installed, it is ready to be assigned to our Open Graph content type. Navigate to the Content Model page and select the Open Graph content type. In there we will modify the settings of our “Title” field by navigating to the appearance area selecting our Open Graph app. Click save.
Now, create a new Open Graph entry to see how the app renders. We can see that our app is rendering by the message that is showing up in our Title field. Of course, we’d like it if our title field actually showed a title instead of a developer message, so at this point it is time to dive into the code that was created earlier by our create-contentful-app CLI tool.
To start, create a field that shows a title based off of the reference blog post in our Content field. To get this functionality, we will make use of Forma 36 — the Contentful Design System to implement UI elements which have the same look and feel as Contentful itself. We’re going to use a TextInput which will be disabled for manual editing but will automatically pull the title information from our content reference field.
In our code, modify src/components/Field.tsx to create a better experience.
To start, import a few libraries that come out of the box when we ran the create-contentful-app CLI commands:
We are using React here for our UI. Tokens is a Forma 36 utility that will provide us with certain variables like color and sizing. The Forma 36 components also come out of the box and will be useful for constructing our UI. Since we are using TypeScript, I’m also including the SDK typings by default.
Next, we’ll want to modify the component itself to handle state, pull information from another field and render some UI.
First, create some state:
Next, listen for changes to our
content reference field. When the
content field has been populated with data, grab the entry, find the title and set that as the title in state. Also save that as the title field’s value in the Open Graph content type.
Last, we can render our UI based on the above logic to give editors some validation hints. We can either warn that a reference needs to be picked, or if a reference is picked, to use the correct title information in our field. We are also going to include a button, which will open up our page location by passing the entry’s ID. We will touch on that more below.
Our full component code looks like this now:
Now that we have a field that can automatically pull a title from the referenced blog post, we also want to build out a page location, which will show a preview of the Open Graph to editors when they click the preview button. The button is under our Title and says “Preview Open Graph.” This button will direct us to our page location which we will create soon.
Let’s start by modifying our src/components/Page.tsx file. Again, we are going to import a few things from Forma 36 in order to build a nice preview UI for our Open Graph components.
sdk.parameters.invocation.path to access the custom path in the URL of our app, which was passed in by
sdk.navigator.openCurrentAppPage from our field component as the on click function of the button.
Now, complete the
useEffect function with some network calls to get all the data we need to display the preview:
Notice that we’re using
Promise.all to get data about the entry and the image asset which we will use in our preview.
Now render the component UI:
For the most part, I am using Skeleton components, which are for looks; they show a loading preview. The Card component is used for actually displaying the content in the Open Graph card. All together, the Page component code looks like this:
In the final code, I’ve added some Typescript interfaces to ensure we are working with the correct data structures. If you’d like to check out the complete code, visit the repo: davidfateh/ctfl-open-graph: Multi location app for Open Graph.
If you’d like to go beyond this functionality, Salma recently wrote a post on solving this issue using Puppeteer and Node.js to generate this data programmatically.
Passing data between app locations can be very useful for creating cohesive experiences for editors as they work on content that is meant to be visualized in different ways. The Open Graph app is one example of how retrieving entry data and passing it around inside of an app can extend some basic functionality.
If you have an app idea or are working on a prototype, our Slack Community can be very helpful if you want to share or get help implementing ideas. You can take advantage of some of the cool things we are doing and discussing over there. Our extensibility team and I are active in our community, and we are always curious to hear ideas about your next big projects!