Granular SEO in ExpressionEngine

Posted

There’s been a lot of talk lately about ExpressionEngine and SEO (search engine optimisation), and I thought I’d share something simple that’s been working quite well for my EE clients for some time now. The objective is to give them more granular control over individual pages; and allow them to experiment and fine-tune over time.

All of this has to be practical. SEO is a time-consuming and complex activity, and clients are busy people right? So it’s important to arm them with enough tools to make a difference, but also be realistic about what they can manage, given limited time and understanding.

Going native

There are a number of good SEO-focussed EE add-ons available, but the minimalist in me likes to avoid add-ons when I can achieve what I need natively in EE. Custom fields are all I need, and I group them under their own “SEO” tab in publish layouts, along with useful instructions for clients.

SEO in the ExpressionEngine Control Panel
Custom SEO tab in ExpressionEngine publish page

I’m not going to explain each of these fields here. There are plenty of SEO resources out there detailing the importance of browser titles, priorities etc… It’s all very dull I’m afraid.

Adding it to the mix

Let’s get these tags into our templates. EE experts can probably skip this, but novices read on. In this example, I’ll use a standard “comments” template displaying a single entry from a news channel. Everything happens in the document <head>.

{preload_replace:my_channel="news"}
{gv_doctype}
{gv_html}

{exp:channel:entries
		channel="{my_channel}" 
		disable="{sn_disable_std}"
		dynamic="yes"
		limit="1"
		require_entry="yes"
	}
{if no_results}{redirect='error'}{/if}
<head>
	<meta charset="{charset}">
	<title>{if cf_browser_title_en}{cf_browser_title_en}{if:else}{title}{/if} | {site_name}</title>
	<meta name="description" content="{cf_meta_description_en}">
{/exp:channel:entries}
	<meta name="author" content="{site_name}">
	<meta name="copyright" content="Copyright {current_time format='%Y'} {gv_site_owner} All rights reserved.">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="/css/styles.css">
	<link rel="stylesheet" media="screen and (max-width: 480px)" href="/css/handheld.css">
</head>

Nothing exceptional here, just a dynamic channel entries tag. The good stuff happens inside the <title> and <meta> description tags where we inject our SEO values. Importantly, since clients sometimes forget to enter a value for Browser Title – tut, tut – we need a fallback. In this case, I’ve got a condition to display the cf_browser_title_en if it has a value, or else just use the entry title.

Note the disable=”{sn_disable_std}” channel parameter, which contains a snippet of the usual disabled channel params – a nice tip I picked up off Carl Crawley at my recent EEUK conference.

BTW – If you’re wondering what the tags are beginning “gv_” they’re global variables I use to store basic reusable stuff like doctype.

Site map template

But wait, what about the other SEO tags? Well they’re used in our XML site map template. Linking an XML site map – or maps – to Google Webmaster Tools for example, helps you control how Google crawls and indexes your pages, and gives you a ton of data on how Google sees your site, so you can fine tune accordingly.

Here’s how our SEO tags would look in an XML site map template. Remember to change your template type to “XML” in EE.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{exp:channel:entries 
		channel="news" 
		disable="{sn_disable_std}" 
		dynamic="no"
	}
	<url>
		<loc>{comment_url_title_auto_path}</loc>
		<lastmod>{edit_date format='{DATE_W3C}'}</lastmod>
		<changefreq>{cf_changefreq}</changefreq>
		<priority>{cf_priority}</priority>
	</url>
	{/exp:channel:entries}
</urlset>

Since we have default values for both Change Frequency (monthly) and Priority (0.5) there’s no need for fallbacks. Now, clients can tell Google how frequently each page needs indexing, and how important/unimportant each page is in the context of the site.

Wrapping up

No question that cooking up a high-ranking website involves a very complicated recipe, but the fields I’ve suggested are pretty key ingredients that will make a difference. They combine to give clients greater control over keywords, crawl rates and search result appearance for individual pages.

You could add more fields for meta keywords, canonical, etc… but again, it’s being realistic about what the client is comfortable with and able to manage. The fields I’ve suggested above are manageable, easy to implement, have had a very positive impact in most cases.

As always, suggestions and comments are very welcome. How do you build granular SEO into EE?

ClientKarma

Thrilled with the outcome of this project. The identity and website have given my new business a real head-start.