Black and white profile shot of David

David Boland

Blogging about web, mobile, and whatever other tech stuff I come across. I work a lot with content management systems. I am an Optimizely (formerly Episerver) MVP, and a Contentful certified developer.

_ _ ___ __
| | | | / _ \ / /
__| | ___| |__ _ __ _ _| | | |/ /_
/ _` |/ _ \ '_ \| '_ \| | | | | | | '_ \
| (_| | __/ |_) | |_) | |_| | |_| | (_) |
\__,_|\___|_.__/| .__/ \__,_|\___/ \___/
| |

Content Modeling Custom CTAs for Contentful Web Pages

June 3rd, 2021

A common use case for Contentful is building a website. And there are lots of examples how to setup your Content Model for a website. I even did a post on content modeling that addressed this use case.

Lots of these examples contain models for everything you would expect from a website. Standard pages, articles, SEO, assets, blocks, and so on. There is one subtle aspect that can get tricky, which are CTAs.

What do we mean by CTAs?

CTAs are calls to action. You run across these every day whenever you see a button that has "Buy" or "Read More" on it.

They are buttons you want your site visitor to click on. They are sometimes presented along with a teaser, which is an image and text that adds some context to the CTA. This could be a product teaser that shows the price, image, and description of the product you are about to buy. In the "Read More" example, this could be an image and title of an article that you will are redirected to from the CTA.

Modeling CTAs in Contentful

From the content modelers perspective, you might go straight to a CTA content type. This would consist of the microcopy for the CTA, as well as the URL that the CTA would redirect the user. While from a modeling perspective this makes sense, once you start entering content this will get messy. If you have any type of listing page (article or product), you could have hundreds or thousands of products. If you need to create a CTA entry for each one of these, you would end up with hundreds or thousands of CTA entries.

So what's the fix here? The cleanest way to implement a CTA would to be adding a CTA Text field to the entry that is being referenced. For example, if you have a Blog Post content type, you would add a short string field for CTA Text. Within there you can specify "Read More" or "Continue Story" or whatever microcopy you want.

Blog Post With CTA

When building your listing, or whatever page you have the CTA, you can reference the entry of the page (Blog Post in this example). When rendering, you can get both the URL and the CTA from the Blog Post entry. This allows you to customize CTA text without flooding Contentful with separate entries.

You might come across instances where you need CTAs for pages that are not in Contentful. Maybe it's an asset that you want to add a "Download" CTA for. Or it could be a page on a separate website. For these we would create separate content types, and make sure to include the CTA Text field on them.

In the asset example, that would mean a content type, call it "Downloadable Asset". It would have at least 2 fields, a Image reference field to the asset in Contentful, and the CTA Text field. The external URL could be the example we discussed above, where you have a Content Type that is made up of a URL field and a CTA Text field. The only difference being that the URL here would only point to external sites.

Taking It a Step Further

While this works for most instances, there are always options for expanding. One way would be adding fields for teaser data. As I mentioned above, this could be relevant for articles or product pages. You could add a reference field to an image asset, fields for a teaser title and teaser text for the description. Wherever you reference the page entry, you'll have all the content you need to render your teaser.

You could also create a CTA Text content type, that can be referenced by the pages. This would be different than the CTA type that we mentioned above. Instead of containing fields for URL and Text and getting referenced on the entry where the CTA would live, we would have a field just for text. Then we can reference it on the entry the CTA points to. So similar to our "cleanest" solution above, with the exception that the CTA Text field is its own separate entry, and referenced by the Blog Post page.

The benefit of this would be two fold. If you only planned to have two separate CTAs, say "Read More" and "Buy", you could create entries for those and reference them on your pages. Then, if you wanted to update the text sitewide. Say, go from "Buy" to "Purchase", you can make the change in one place and be done.

Separating the CTAs to referenced entries can also create opportunities for A/B testing. You could have a multi reference field for CTAs on the product page, reference a "Buy" CTA and a "Purchase" CTA. During testing, you can pull one or the other based on your criteria.


Content modeling can be tricky. For every approach to solving a problem, there are 3 others that can seem just as good depending on your use case. Finding the right approach requires understanding your editors, business uses, and technical requirements.

For more info on Content Modeling in Contentful, check out my previous post about it. And as always, if you have additional questions, please comment below or reach out on Twitter.

Thanks to #WOCinTech for the teaser photo used in this post!