Skip to Main Content

SEO and ExpressionEngine

I've used a number of different methods in the past to get SEO meta tags in ExpressionEngine easily editable for clients. Recently however I feel that I've found what I feel is the best way for me and is also very flexible going forward. This method does require using 4 addons, three of which I use on almost every build and only one of which is commercial.

I've used a number of different methods in the past to get SEO meta tags in ExpressionEngine easily editable for clients. Recently however I feel that I've found what I feel is the best way for me and is also very flexible going forward. This method does require using 4 addons, three of which I use on almost every build and only one of which is commercial.

The key to the magic is SEO Lite and Low Variables. SEO Lite does 90% of the work and Low Variables fills in a couple of holes especially on listing pages or pages that are not comprised of a single entry and may need their own specific keywords or description.

SEO Lite

SEO Lite is a lightweight addon that allows you to implement the basic SEO tags, title, description, and keywords, into your templates easily. The documentation for SEO Lite is very easy to follow and really it's as simple as adding a single tag to your templates and almost everything is finished. Once installed you go to the SEO Lite module page where you can input the default keywords and description as well as edit the template. I usually leave the template alone and fill in the defaults. Defaults will be overwritten on any page with an entry url_title in the last segment.

Adding in the

    
    
      {exp:seo_lite use_last_segment="yes"}
    
  

into your document head will get things working correctly almost strait away. The issue that now crops up is what do you do when you have pages that do not have a url_title in the last segment? You can use embeds to pass through overrides on these specific pages as per the SEO Lite documentation:

    
    
      {exp:seo_lite use_last_segment='yes'
        title_postfix='{embed:title_postfix}'
        default_title='{embed:default_title}'
        default_keywords='{embed:default_keywords}'
        default_description='{embed:default_description}'
}
    
  

This works great. However like many ExpressionEngine developers I now do my best to avoid embeds. The key to avoid using embeds is Low Variables which I already use on 95% of my sites. I am also running my listing pages and single entry pages through the same template. This means I need to have overrides available for the listing pages and ensure that individual entries still get to use the keywords and description entered from within the entries.

Low Variables

Step one replace embeds with low variables. Create a low variables for each page where you need an override. I first create a group called SEO and then call each variable lv-blog-meta-description, lv-blog-meta-keywords where blog will change depending on which page the override is needed on.

Next instead of overriding with embeds in our SEO Lite tag we'll use Low Variables and pass the overrides through via the preparse paramenter since our SEO Lite tag is residing in it's own Low Variable called lv-doctype-header. The key for this to work is that the lv-doctype-header variable needs to be further down the list of variables in the Low Variables CP. I do this by creating a different group called Developer Variables, hiding it from non-managers and placing that group below the SEO group.

Switchee and Ifelse

In order to use a single template for both listing pages and single entry pages, which results in nicer urls, I use the excellent plugin by Mark Croxton - Switchee. So for example on a blog page my url would be domain.com/blog or domain.com/blog/url_title. To allow overrides to work on the listing page, pagination, and categories, but have the individual entries have their own unique meta tags we need switchee. The code below is what I am using:

    
    
      {exp:switchee variable = "{segment_2}" parse="inward"}
  {case value="#^P(\d+)$#|''|category|archives"} 
    {exp:low_variables:single 
        var="lv-doctype-header"
        preparse:pre_url_title="seo-and-expressionengine"
        preparse:pre_entry_id="{entry_id}"
        preparse:pre_default_title=""
        preparse:pre_default_keywords="{lv-blog-meta-keywords}"
        preparse:pre_default_description="{lv-blog-meta-description}"
    }
  {/case}
 
  {case default="yes"}
        {exp:low_variables:single 
            var="lv-doctype-header"
            preparse:pre_url_title="seo-and-expressionengine"
            preparse:pre_entry_id="{entry_id}"
        }
  {/case}
{/exp:switchee}
    
  

Then in the lv-doctype-header variable I have the following which uses IfElse, also by Mark Croxton. If else allows you to parse advanced conditionals without the overhead that comes when using just the baked in conditional EE tags.

    
    
      {exp:ifelse parse="inward"}
 
    {if (segment_2 =="" AND segment_1 !="") OR segment_2 =="map"}
        {exp:seo_lite 
            entry_id="{pre_entry_id}"
            url_title="{pre_url_title}"
            default_title='{pre_default_title}'
            default_keywords='{pre_default_keywords}'
            default_description='{pre_default_description}'
        }
    {/if}
 
    {if segment_2 !="" OR segment_1==""}
 
        {exp:seo_lite 
            entry_id="{pre_entry_id}"
            url_title="{pre_url_title}"
        }
    {/if}
{/exp:ifelse}
    
  

What the above code is doing is in the first conditional checking if the page needs overrides. On my sites generally if segment 2 is empty then that is a listing or unique page. ON this site there is one additional page with segment two filled in that needs unique meta tags and that is the page located at /contact/map hence the advanced conditional there.

The second half checks to see if segment 2 is not empty in which case it looks for a url_title. It also checks if segment_1 is empty (the homepage) and if it is uses that code. Since there is no entry_id or url_title passed on the homepage it loads the default meta keywords and description.

Bonus for Low Variables

If you don't wan't to give your client access to the SEO lite page to adjust the default keywords and description all you need to do is create new variables in Low Variables and then put those into the template code. You now have a site where the meta description and keywords are easily edited on all pages by your client.

Update

Both on twitter and in the comments I have been reminded of NSM Better Meta. NSM Better meta is a more robust option than SEO LIte with many more tags that are easily updatable by the client. The purpose of this article was to outline my approach with the sites that I build where most clients only need to adjust keywords and description. If you need more options than you should definitely check out NSM Better Meta.

Update 2

This post was written for ExpressionEngine 2. EE 3 or 4 have more robust and flexible ways to manage SEO.