Guides

SEO Module

This guide will tell you how to get started with the Contento SEO Module and the different options for your technical SEO setup with code examples for using Next.js.

The SEO module can be switched on by going to the settings tab in your site and then to the SEO tab in the left sidebar. You can then switch it on by clicking the toggle so it goes green.

You will then see the SEO preview and fields appear below.

The SEO module is split into two tabs the Core SEO and the Open Graph settings.


Core SEO

The Core SEO tab has a preview panel at the top that shows you what your SEO will look like on search engines as you complete the fields. This is your general site SEO that will be used if a page does not have it's own SEO. It has the following fields:

Meta Title

The Meta Title field will be mapped to the content attribute of the <meta name="meta title" /> tag.

Prefix

The Prefix field is added to the front of your meta title and will appear across all pages even when they have their own unique meta title and are not using the general site meta title.

Suffix

The Suffix field is added to the end of your meta title and also will appear across all pages. The suffix is typically used for your company name.

Character Limit

If the total character limit of the prefix, meta title and suffix exceeds 60 characters you will be shown a warning message that says "The combined meta title is over 60 characters, this may get truncated in SERPs." this is a warning, but will not stop you from saving the page.

Meta Description

The Meta Description field will be mapped to the content attribute of the <meta name="meta description" /> tag.

Character Limit

If the meta description exceeds 160 characters you will be shown a warning message that says "The meta description is over 160 characters, this may get truncated in SERPs.". Again this is a warning but will not stop you from saving the page.

Robots

The Robots field is a dropdown field with four options that will be mapped to the content attribute in the robots meta tag <meta name="robots" />.

Default

This will output null and will be the default of index <meta name="robots" content="index"/>. Which tells a search engine to index a page.

Index, No Follow

This tells the search engines to index the page, but tells a crawler not to follow any links on the page or pass along any link equity.

No index, No Follow

This tells the search engine not to index the page and for the crawler not to follow any links or pass along any link equity.

No Index, Follow

This tells the search engine not to index the page, but even if it's not indexed the crawler should still follow the links and pass along equity to the linked pages.

Canonical Url

Canonical Urls specify the master version for a url if there are similar or duplicate pages. This field will automatically pull the url from the domain name field in the site general settings for your core SEO. This can be altered on content type and page specific SEO settings.


Open Graph

The Open Graph settings are used to create the og tags used by the Open Graph Protocol originally created by Meta for sharing content to social media. Setting these yourself allows you to control what is used rather than it being decided by the social sharing platforms. The Open Graph settings in the Site SEO settings will be used if you have not set individual Open Graph settings on a specific page. The Open Graph settings include the following fields:

Meta Title

The Meta Title will be mapped to the content attribute of the <meta property="og:title"/> tag, you can either write a unique version in the field or use the toggle to pull the Meta Title from the Core SEO settings.

Meta Description

The Meta Description will be mapped to the content attribute of the <meta property="og:description"/> tag, you can either write a unique version in the field or use the toggle to pull the Meta Description from the Core SEO settings.

Image

The Image url will be mapped to the content attribute of the <meta property="og:image"/> tag. You can select a image from the assets folder or add your own url.

Width & Height

You can manually add the size of your image in pixels by using the width and height fields, which we then use in the code below for the image_height and image_width on the images object. This is available for if you using your own url in the images field, and not pulling an image from the assets folder.

Alt

The Alt tag is used to supply descriptive text for the image to aid with accessibility. It maps to the alt in the code below on the images object.

Url

The Url is pulled from your Domain name in the general site settings and will be mapped to the content attribute of the <meta property="og:url"/> tag. This can be changed on page specific Open Graph settings.


Content Type SEO

Each page content type can be set up with it's own unique settings that will automatically be used for any pages created using that content type.

Meta Title and Meta Description

For the Meta Title and Meta Description there are three options available in their dropdowns for the source of the SEO:

Inherit From Site

This sets any new page you create to automatically use the Meta Title or Meta Description from the Core SEO General Site settings.

From Field

This sets a field on the page as a source for the Meta Title or Meta Description. This could be the title field on the page for example or the excerpt field on a blog post.

Manual

This leaves the source blank and requires your editors to manually enter a Meta Title or Meta Description in the page specific SEO settings.

Robots and Canonical Url

The Robots and Canonical Url fields only have two options in their dropdown, which are Inherit From Site and Manual.


Page Specific SEO

When a page is created by an editor it will automatically use the SEO and Open Graph settings set on the content type. If the editor wants to override these settings they can go into the SEO tab on the page and then change the settings manually for that specific page.


Code

If you're using one of our starter kits we have a helper function available in lib / contento.ts that handles the API call to get your SEO data from the SEO module and maps it into a generateMetadata function from Next.js

If you are using your own code base you can use the functions below or you can use them as an example to build your own.

The type key maps to the og:type attribute and is set as website in the function as this would be the typical type for this usecase. The locale key is mapped to the og:locale is set to en_GB but can be updated to an appropriate locale code for you.

export function generateSeo(
  content: ContentData,
  openGraph?: OpenGraph,
  canonical?: string,
): Metadata {
  const images: Array<{
    url: string | URL
    secureUrl?: string | URL
    alt?: string
    type?: string
    width?: string | number
    height?: string | number
  }> = []

  if (content.seo.open_graph.image_secure_url) {
    images.push({
      url: content.seo.open_graph.image_secure_url,
      secureUrl: content.seo.open_graph.image_secure_url,
      width: content.seo.open_graph.image_width ?? undefined,
      height: content.seo.open_graph.image_height ?? undefined,
      alt: content.seo.open_graph.image_alt ?? undefined,
    })
  }

  let og: OpenGraph = {
    title: content.seo.open_graph.title ?? undefined,
    description: content.seo.open_graph.description ?? undefined,
    url: canonical ? canonical : content.seo.open_graph.url,
    images: images,
    locale: 'en_GB',
    type: 'website',
  }

  if (openGraph) {
    og = { ...og, ...openGraph }
  }

  return {
    title: content.seo.title,
    description: content.seo.description,
    alternates: {
      canonical: canonical ? canonical : content.seo.canonical_url,
    },
    openGraph: og,
  }
}

In the starter kits you will see the generateMetadata function in the page.tsx file for each route, which uses the generateSeo function from lib / contento.ts to map the data from the api to the appropriate keys and is used by Next.js to output the SEO in line with their configuration. Add this function to the page.tsx file for any new routes you create that have a unique page content type if you're using Next.js.

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  return await client
    .getContent({
      params: {
        content_type: ['general_page'],
        slug: params.slug,
        limit: '1',
      },
    })
    .then((response: ContentAPIResponse) => {
      return generateSeo(response.content[0])
    })
    .catch(() => {
      return {}
    })
}

You may wish to add new keys directly into the function for certain routes such as the blog, where additional SEO information is required. This is already present in The Blog starter kit and you will also see additions to the generateSEO function in the author and category routes.


export async function generateMetadata({ params }: Props): Promise<Metadata> {
  return await client
    .getContentBySlug(params.slug, 'blog_post')
    .then((content: ContentData) => {
      return generateSeo(content, {
        type: 'article',
        publishedTime: content.published_at ?? undefined,
        modifiedTime: content.updated_at,
        authors: content.fields.author.content_links[0].content_link.url,
        section: content.fields.category.content_links[0].content_link.name,
      })
    })
    .catch(() => {
      return {}
    })
}

In our examples using Next.js they also use the data from the SEO module to create other types of tags such as the twitter:title and twitter:description for sharing to twitter. You can find out more about this by checking out the Next.js docs.


Examples

The recommended workflow for using the SEO module is that the Core SEO and global Open Graph settings are set and used as a backup. You should then set SEO and Open Graph settings on each page content type you create, and then when a new page is created by the editor if they need to manually override the settings they can do so in the settings of that page instance.

This is an example of the page object when only the Core SEO settings are completed, the global Open Graph settings have not been completed and there is no content type or page specific SEO settings. The Open Graph settings are set by default to automatically pull through the Core Meta Title and Meta Description if not set.


{
  "id": "RaDf2yMpL6",
  "published_at": "2022-09-27T08:54:06+00:00",
  "slug": "contact-us",
  "name": "Contact Us",
  "author": {...},
  "content_type": {...},
  "seo": {
    "title": "Prefix - Core SEO Meta Title - Suffix",
    "description": "Core SEO meta description",
    "robots": null,
    "canonical_url": "http://localhost:3000/contact-us",
    "open_graph": {
      "title": "Core SEO Meta Title",
      "description": "Core SEO meta description",
      "image_secure_url": null,
      "image_width": null,
      "image_height": null,
      "image_alt": null,
      "url": "http://localhost:3000/contact-us"
    }
  },
  "fields": {...}
}

This is an example of a page object when the Core SEO Settings and global Open Graph settings have been completed, but there is no content type or page specific SEO.

{
  "id": "RaDf2yMpL6",
  "published_at": "2022-09-27T08:54:06+00:00",
  "slug": "contact-us",
  "name": "Contact Us",
  "author": {...},
  "content_type": {...},
  "seo": {
      "title": "Prefix - Example Core Meta Title - Suffix",
      "description": "Example Meta Description in the Core SEO settings",
      "robots": null,
      "canonical_url": "http://localhost:3000/contact-us",
      "open_graph": {
          "title": "Example OG Meta Title",
          "description": "Example OG Meta Description",
          "image_secure_url": "https://assets.contento.io/assets/s_01J0jq9q1101eq7zAmV7P1sM78/placeholder-image.webp",
          "image_width": 600,
          "image_height": 400,
          "image_alt": "Example OG Alt",
          "url": "http://localhost:3000/contact-us"
      }
  },
  "fields": {...}
}

In this example the content type SEO settings have been set so that the Meta Title pulls the data through from the internal_name field on the page. The Meta Description field is set to manual and this description would then be the same for each page of this type that was created. The robots field has been set to be "index, nofollow" for this page type. All the other settings are being pulled from the Core SEO settings and global Open Graph settings.

{
  "id": "RaDf2yMpL6",
  "published_at": "2022-09-27T08:54:06+00:00",
  "slug": "contact-us",
  "name": "Contact Us",
  "author": {...},
  "content_type": {...},
  "seo": {
    "title": "Prefix - Contact - Suffix",
    "description": "Example Meta Description set manually in the Content Type",
    "robots": "index, nofollow",
    "canonical_url": "http://localhost:3000/contact-us",
    "open_graph": {
        "title": "Contact",
        "description": "Example Meta Description set manually in the Content Type",
        "image_secure_url": "https://assets.contento.io/assets/s_01J0jq9q1101eq7zAmV7P1sM78/placeholder-image.webp",
        "image_width": "600",
        "image_height": "400",
        "image_alt": "OG Alt",
        "url": "http://localhost:3000/contact-us"
    }
  },
  "fields": {...}
}

This is an example of changing the SEO settings at a page specific level. The Meta Title and Description have been changed to manual and provided by the editor and the robots setting has been set back to default for this page.

{
  "id": "RaDf2yMpL6",
  "published_at": "2022-09-27T08:54:06+00:00",
  "slug": "contact-us",
  "name": "Contact Us",
  "author": {...},
  "content_type": {...},
  "seo": {
    "title": "Prefix - Get in touch - Suffix",
    "description": "Example Meta Description set manually in the page",
    "robots": null,
    "canonical_url": "http://localhost:3000/contact-us",
    "open_graph": {
        "title": "Get in touch",
        "description": "Example Meta Description set manually in the page",
        "image_secure_url": "https://assets.contento.io/assets/s_01J0jq9q1101eq7zAmV7P1sM78/placeholder-image.webp",
        "image_width": "600",
        "image_height": "400",
        "image_alt": "OG Alt",
        "url": "http://localhost:3000/contact-us"
    }
},
  "fields": {...}
}
Hollie Duncan

Written by Hollie Duncan

Updated

Previous
Blocks