Blogs

Optimizing On-page SEO in dotCMS

Jason Smith

On-page SEO, doesn’t need to be complicated nor does it need to take a lot of effort, but what it does require is some thought and some planning. For those who may be unfamiliar, on-page SEO refers to both the content and the HTML source code of a page on your site, items you can easily control via your CMS. Off-page SEO refers to links and other external signals (items you may not have as much control over).

In my previous post, I talked about how you can use dotCMS to improve your page performance and SEO. In this blog, I will show you how to use your CMS to make your SEO life easier, using our own website and product (dotCMS) for references. We'll take a look at code examples of how to programmatically ensure best practices for some of your SEO tasks.

I will be using SEM Rush to test our site and monitor our progress; however, there are several great SEO testing tools on the market, so look around and see what works best for your needs. For this blog specifically, we need a tool that will crawl our site and check if we have any duplicate title tags, description or broken canonical URLs.

If you’re looking for more information about on-page SEO make sure to check out Alex’s blog: Website Accessibility and SEO: How the Two Overlap.

Now let's make our lives easy peasy by automating some of the basic on-page SEO tasks.

Title and META Description

Let's start with one of the most basic — but also most asked about — best practices for building sites in dotCMS. We look at three key tags: page title, description, and canonical URL. You might be asking yourself, “Shouldn’t that just be part of the page properties?” Technically, you’re right, but what about URL mapped pages like blogs, events, news articles, and so on? When it comes to SEO, I like to give granular control to the content authors and contributors. Then, I write my code to fall back to default content if specific content was not provided.

Setting Up Your Content and Page Types

The first thing I do when building a new site or trying to optimize an older one, is to create these fields on all Page Types and Content Types that use a URL Map: SEO Title, SEO Description, and Canonical URL. Make sure your variable names are the same from one content type to the next. This will make it easier to write one rule for all content types and pages.

Step 1 (Optional)

To keep things organized, I like to create a “Tab” field in dotCMS where I’ll keep all my SEO-specific fields together. For this blog, we’ll be focusing on our three tags, but there are additional SEO fields you might want to add depending on the project, such as social media tags like Open Graph and Twitter cards, or meta robots, geo, and keywords.

Step-1-graphic

Step 2

Add a new text field under the SEO tab. I also try to keep the same naming convention, something like SEO Title, which will generate a variable name seoTitle. Take the time to use the hint field to provide best practice reminders for your content contributors. For example, a reminder that I often use is that page titles should be kept to 55 characters or less.

step-2-title-tag

Below are some additional best practices for title tags you might want to consider.

Title Best Practices:

  • Use a dash in between your keyword phrases and a pipe at the end before your brand name (Example: Primary Keyword – Secondary Keyword | Brand Name )
  • Your title tag should not be the same as your H1 Tag.
  • Keep title tags to 55 characters or less in length, including spaces.

To learn more about the new title tag guidelines, check out this post by Dr. Pete.

Step 3

Next, add a text area field and call it SEO Description — again this will generate a variable name seoDescription. Don’t forget to add recommendations to the hint field to help your contributors write better descriptions.

Best Practices:

  • 150 to 160 characters or less in length, including spaces.
  • Do not use quotes or any non-alpha characters

Step 4 (Optional, but nice to have)

Use a custom field to add a character count to the SEO Title and SEO Description fields. This will help your content contributors know if they have exceeded the recommended character count for the respected SEO fields.

To do this in dotCMS, download the text-count.vtl file and upload it to your site:

Download the text-count.vtl file

In your content type, add a custom field under the SEO Title and call it SEO Title Count. Paste the below code into the Value field and save the field.

#set($maxChar = 50) 
#set($fieldId = "seoTitle")
#dotParse("/application/vtl/custom-fields/text-count.vtl")    

Now repeat this for the SEO Description field, but change the field name to SEO Description Count and the following code in the Value field:

#set($maxChar = 150) 
#set($fieldId = "seoDescription")
#dotParse("/application/vtl/custom-fields/text-count.vtl")

This is what your content editing screen should look like now.

content-edit-screen

Setting the Correct Values on the Page

Now that we have the SEO fields on our pages and content types that use URL maps, let's set the appropriate metadata values for the page. I like to set a Velocity variable for each so I can reuse them anywhere on the page without having to recheck what value should be used.  

To do this, we need to check to see what values are set. Work backward from the content level up to the page level to provide the most appropriate title. As a last resort, I typically use the page’s ‘Friendly SEO’ name, but that's up to you.

Your code would look something like this:

##SET PAGE TITLE
#if($UtilMethods.isSet($URLMapContent.seoTitle))
#set($pTitle = $URLMapContent.seoTitle)
#elseif($UtilMethods.isSet($dotPageContent.seoTitle))
#set($pTitle = $dotPageContent.seoTitle)
#else
#set($pTitle = $dotPageContent.friendlyName)
#end

For the description, we are going to take one additional step to make sure we have a good fall back. If there is no SEO Description, and the page uses a URL Map, we are going to combine the description from the detail page with the title we just set in the previous code snippet.

For example: On our site, we have a section called Known Security Issues and it is composed of two pages, the list page and the detail page.

security-issue

On the detail page, I added the following SEO description.

page-description-example

Then, if a URL Mapped piece of content doesn’t have a description set, I combine the page title and the description from the detail page to generate something like this:

##SET PAGE DESCRIPTION
#if($UtilMethods.isSet($URLMapContent))
#if($UtilMethods.isSet($URLMapContent.seoDescription))
#set($pDescription = $URLMapContent.seoDescription)
#else
#set($pDescription = $!{HTMLPAGE_DESCRIPTION}  + " " + $!{pTitle})
#end
#else
#set($pDescription = $dotPageContent.seoDescription)
#end

Next, we need to set the Canonical URL. Most of the time we can just set the URL from the forward request, but sometimes we may want to point several URLs to the same page. I often do this for campaigns and landing pages where I might want to do tracking or provide unique Vanity URLs. So we’ll simply check to see if the Canonical URL is set on the page and if not just use the URL from the request.

##SET CANONICAL URL
#if($UtilMethods.isSet($dotPageContent.canonicalUrl))
#set($pCanonical = "https://dotcms.com" + $!{dotPageContent.canonicalUrl})
#else
#set($pCanonical = "https://dotcms.com" + $!{request.getAttribute("javax.servlet.forward.request_uri")})
#end

The last thing we simply print out the variables values in the appropriate tags.

<title>$pTitle | dotCMS</title>
<meta name="description" content="$pDescription">
<link rel="canonical" href="$pCanonical">
<meta property="og:title" content=“$pTitle">
<meta property="og:description" content=“$pDescription”>

Notice how we are appending the | dotCMS to the end of the title. If you recall the best practices from earlier your title should follow the following format:

Primary Keyword – Secondary Keyword | Brand Name

This is also why we set the character count to 50 instead of the recommended 55 - 60.

I hope this has helped you learn how to provide simple tools to help content contributors with SEO best practices while ensuring your site doesn’t have duplicate titles or descriptions.

Jason Smith
Chief User Experience Officer
April 09, 2019

Recommended Reading

Headless CMS vs Hybrid CMS: How dotCMS Goes Beyond Headless

What’s the difference between a headless CMS and a hybrid CMS, and which one is best suited for an enterprise?

Why Global Brands Need a Multi-tenant CMS

Maintaining or achieving a global presence requires effective use of resources, time and money. Single-tenant CMS solutions were once the go-to choices for enterprises to reach out to different market...

14 Benefits of Cloud Computing and Terminology Glossary to Get You Started

What is cloud computing, and what benefits does the cloud bring to brands who are entering into the IoT era?