sindre.bakken.naesset@gmail.com

Dealing with Contentful types in TypeScript

If you are familiar with Contentful and have considered using it in a TypeScript project you have probably cringed at the idea of writing type defenitions for the deeply nested and recursive responses you get back from your Contentful Client.

export async function getStaticProps() { const model = await contentfulClient.getEntries({ content_type: 'someModel', }); return { props: { someImageUrl: model.items[0]?.fields.image.fields.file.url }, }; }

However if you have used Contentful without TypeScript you also know how hard it is to keep track of the shape of the response, which makes your code slow to write and prone to errors.

Thankfully there is an easy fix to this problem using the contentful-typescript-codegen package.


First we need to install a few packages. I will assume you already have the contentful package installed.

npm i -D contentful-typescript-codegen

If you dont have the Contentful Management package, go ahead and install that too.

npm i contentful-management

The next step is to create a file called getContentfulEnvironment.js in your projects root folder that should look like this:

require('dotenv').config(); const contentfulManagement = require('contentful-management'); module.exports = async function () { const contentfulClient = contentfulManagement.createClient({ accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN, }); return contentfulClient .getSpace(process.env.CONTENTFUL_SPACE_ID) .then((space) => space.getEnvironment(process.env.CONTENTFUL_ENVIROMENT)) .catch(console.error); };

Now it's important to note that CONTENTFUL_MANAGEMENT_TOKEN is NOT the same as your usual Access Token. To create a Management Token, go to your Contentful space, click settings > API keys, and then on the top bar click Content management tokens to create a new key. The CONTENTFUL_ENVIROMENT variable just refers to your enviroment in Contentful, it defaults to master.


Finally we just have to add a script to package.json that will generate the type defenitions:

{ // ... "scripts": { "contentful:generate": "contentful-typescript-codegen --output src/types/generated/contentful.d.ts" } }

For more options, see the npm page.

Now all you have to do is run the codegen script whenever you make changes to your model, and enjoy your freshly generated type defenitions!