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": {...}
}