How we increased our average SERP by 9% and organic traffic by 14%

A magnifying glass leying on leaves, title of article: Using Contentful and investing in search engine optimization
Published
October 21, 2020
Category

Developers

We recently revamped the Contentful blog — yup, this blog that you’re currently reading. Now it’s easier than ever to find the information you’re looking for, thanks to the new design, categories, tags, and recommended articles. We also made a few additions to help readers find what they’re looking for via search engines. Under the hood, we added rich text, two metadata fields and JSON-LD schema — which dramatically increased our organic search numbers.

Using Contentful and investing in search engine optimization

Like most startups, we built our first blog with a pretty basic content model. It allowed us to publish articles about Contentful and the world of digital experience, but content was difficult to find. Some of our best articles became buried under newer articles, including How to create an SEO blog using Nuxt.js and Contentful and Will search engines index my content? It’s all in the rendering — two very relevant posts.  

We originally didn’t plan at all for SEO. Our text fields were in Markdown, and we didn’t even have a field for a meta title. The field for our meta descriptions doubled as the field for teasers — those short phrases on the homepage meant to entice human readers, not explain the content to search bots. 

The update to our blog design gave us the perfect opportunity to make improvements all around the blog. We switched out Markdown for rich text and added two metadata fields and JSON schema. 

These small additions contributed to impressive improvements in our blog’s performance. In the quarter after implantation, our organic traffic increased by 14.2%, our average search engine results page (SERP) position by 9%, and our click-through rate jumped 29%. Although it isn’t possible to attribute all of these improvements to metafields and JSON-LD Schema, they certainly contributed! I won’t go into the benefits of rich text for SEO in this post — you can read about that from our friends at Upsolve. But here’s a look at how we implemented metadata fields and JSON-LD schema. 

Adding metafields for titles and description in Contentful

It’s helpful to create a single reference for basic meta information and require it on every page-level content type. That way you can be sure to have at least a minimum of meta information, in a consistent format, for each page on your site. Ours is only three fields:

Adding metafields for titles and description in Contentful

If we need more fields for particular pages, we specifically add those on that content type.

Structured data from Contentful to create a JSON-LD schema.

JSON-LD is a data format, based on JSON, which, when used correctly, makes content easier to discover by the people for whom it was created. JSON-LD is used to communicate information about the content in a standardized format, making it easier for search engines to index the content and return it to the right searches. One of the most popular standards is schema.org, implemented using JSON-LD.

Implementing JSON-LD is easy. All it takes is wrapping an object with the right fields in a <script type=application/ld+json> tag, and inserting that script into the head of your page. Here is what that looks like.

The trickier part is getting the data you want to put in the JSON-LD object. Manually creating an object to describe each page on your website is tedious and time consuming. Luckily, Contentful’s APIs also return JSON, making it easy to use Contentful to give a basic structured overview of each page and improve your search result performance.

Here’s what that looks like on the template that builds our blog posts.

javascript
    const metaPageDescription = data.metaPageDescription
      ? data.metaPageDescription
      : "";

    const articleBody = documentToPlainTextString(
      data.bodyContent ? data.bodyContent.json : data.content
    );

    const authors =
      data.authorsCollection.items.length > 1
        ? data.authorsCollection.items.map(author => {
            return {
              "@type": "person",
              name: author.name
            };
          })
        : {
            "@type": "person",
            name: data.authorsCollection.items[0].name
          };

    const keywords = data.tagsCollection
      ? data.tagsCollection.items.map(tag => tag.title)
      : "";

    const pageImage =
      data.featureimage && data.featureimage.url
        ? `${data.featureimage.url}?fm=jpg&q=90&w=1200`
        : undefined;

    const canonical = data.externalUrl;

    const schema = {
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      headline: data.title,
      image: pageImage,
      publisher: {
        "@type": "Organization",
        name: "Contentful, GmbH",
        url: "https://www.contentful.com/",
        logo:
          "https://images.ctfassets.net/fo9twyrwpveg/6eVeSgMr2EsEGiGc208c6M/f6d9ff47d8d26b3b238c6272a40d3a99/contentful-logo.png"
      },
      url: `http://www.contentful.com/${data.fullPath}`,
      datePublished: data.publishDate,
      dateCreated: data.publishDate,
      dateModified: data.sys.publishedAt,
      description: metaPageDescription,
      author: authors,
      articleSection: data.category ? data.category.title : "",
      abstract: data.teaser ? data.teaser : "",
      keywords: keywords,
      articleBody: articleBody,
      mainEntityOfPage: data.title
    };

    const jsonLd = { ...schema, ...data.metaStructuredPageData };

With the schema object, we create a standard JSON-LD schema that will be implemented on every post using data that already exists in Contentful. You’ll also notice the jsonLd object below, which spreads in the schema object and a field called metaStructuredPageData.

metaStructuredPageData is a JSON object field in Contentful, that allows editors to add additional fields to the JSON-LD object if they want to. This makes it possible for editors to create schemas directly in the Contentful web app. 

Once our object is created using the pre-existing data, all that remains is inserting it into the page wrapped in the aforementioned script tag, like so.

javascript
<div
  dangerouslySetInnerHTML={{
    __html: `
      <script type="application/ld+json">${JSON.stringify(
        jsonLd
      )}</script>
      `
     }}
 />

Visit our new blog home page for more guides and suggestions on building digital products, and keep on reading! 

About the author
Don't miss the latest
Get updates in your inbox
A monthly newsletter to help you build better digital experiences with Contentful.
add-circle remove style-two-pin-marker subtract-circle