SEO Lite – The one calorie SEO addon for ExpressionEngine 2.x

A while back I released DevKit for ExpressionEngine using the module “SEO Lite” as an example. Now this module is ready for download!

Click here to download SEO Lite

Full documentation: SEO Lite documentation

A SEO module for ExpressionEngine – what does it do?

Sure you could add custom fields for this kind of meta data, but SEO Lite makes it cleaner and easier to use for the client.

SEO Lite is a lightweight addon for ExpressionEngine that adds SEO meta data for title, keywords and description for entries on your site, enabling them to rank better in the search engines. It uses a template which you can customize to your needs.

It will add a new tab to the publish entry page called “SEO Lite” where you specify title, keywords, and description for the entry.

If you do not specify anything the original entry title will be used, together with the default values for keywords and description.

Why Lite?

First, it’s very lightweight – you only use one tag to output the template, and this tag uses only one database query to fetch the template, entry title, default entry keywords/description or/and the specific keywords/descriptions for that entry.

So you add the power of SEO optimalization with only one query which should be a good tradeoff and perfect for high-traffic websites.

Second, it’s lite functionality-wise as well. No frills. If you want a more extensive module I recommend NSM Better Meta which is a very good commercial alternative.

The template

The default meta data template looks like this:

<title>{title} - {site_name}</title>
<meta name='keywords' content='{meta_keywords}' />
<meta name='description' content='{meta_description}' />
<!-- generated by seo_lite --!>

This can be edited in the SEO Lite Settings. The only thing that’s replaced by SEO Lite is {title}, {meta_keywords} and {meta_description} and you can use any kind of global variables and EE conditionals in it which should make it pretty powerful.

The Tag

Use this tag in your header template to output the template above:

{exp:seo_lite url_title="{segment_3}"}

The url_title parameter uses {segment_3} to find the entry based on the current url. If you have the entry_id you may also use it like this:

{exp:seo_lite entry_id="{entry_id}"}

Installing the module in a WooTheme

Here’s a video showing how to install the module and use it with any of the WooThemes:

Of course this process will be the almost identical on any site.

ScribeSEO Support In The Works

I’m currently implementing support for ScribeSEO. To get an update when this is ready subscribe to my RSS feed or follow me on Twitter.


Download .zip

Documentation, support, download etc. available over at

Let me know what you think! :-)

  1. I’ve installed this locally and I can see the meta keywords and description fields in the fields sidebar, but there’s no tab from which to access the fields and enter any information.

  2. Hmm, I tested this on 2.1 and after installing I get the SEO Lite tab there automatically .. the module installed fine without any problems? Can you edit the module settings? .. are you logged in as superadmin? Do you have a screenshot?

  3. Same error for me – uploaded, installed, no visible tab on an existing channel… Trying to create my own tabs, and dragging and dropping the fields fails too… I am logged in as superadmin, the module works, and the settings loads – i am able to enter template and default desc/key, no other options are present. Thanks,N

  4. Thanks for the info Neil, and for following up on this one John! Yup, seems like an EE bug:

    I’m not reproducing so can’t confirm it but according to that bug report renaming the tab to a single word should work .. I just did a commit now changing the tab name to “SEO-Lite” instead of “SEO Lite” so you can download over again and see if that helps if you want.

  5. Actually, I’m still having problems. I thought removing the custom layout and redoing it solved the problem, but it only does while you still have that entry’s page open. If you navigate away and come back to it again, the SEO Lite tab is empty again.

  6. hmm, what build are you on John? The latest one released 20th of july (20100720)?

  7. Ok, so I was able to reproduce your problem now by creating a custom layout. As Neil said, when removing my custom layout SEO Lite appeared again .. so it looks like an EE 2.1 bug :-/

  8. Cool add-on. Any chance you could add options to pass through like title_prefix and title_suffix, similar to LG Better Meta?

  9. Ben; don’t know if I understood you right but you can pre/postfix the title with whatever in the template.

    David; just drop the “seo_lite” folder into /system/expressionengine/third_party/ and you’re good to go (read: install it in the backend)

  10. your language file used the language variable TITLE… This overrides the default one provided by EE and so if i change it in your language file to “SEO Title” it also changes the title on the publish tab!! In min i have changed your language variable to “seotitle” and then changed this in you tab file as well allowing me to change it without affecting the publish page! Cheers, N

  11. Sorry to keep sending over bugs. But i am using this on a MSM based site and it fails silently. Stops the template load. So looking at your scripts, i hard coded the site ID into the tag and that causes a: Error Number: 1052 Column ‘entry_id’ in where clause is ambiguous (** Then shows the SQL query – but i didn;t want to cut that over here! **)

    I’ll keep digging and notify you if i find anything to solve it.

  12. Okay… tracked it back to the MSM being the issue. Without learning how MSM work with modules – yours does not create a new row entry for in the config DB for each site. I only have the original site, and no second site. So when it tries to load the default values it fails as the second site ID is missing. Not sure how to solve it – but i guess you need to hook into getting a new DB row in cofig when a new MSM site is created…

  13. Hi Bjorn, Thanks for this plugin, it’s working well for me aside for one issue. It’s similar to Neil’s above, though I’m not running MSM. If any entry id is passed to the plugin I get the same error:

    Error Number: 1052

    Column ‘entry_id’ in where clause is ambiguous.

    Any suggestions on how to fix it/what might be causing it? Thanks, Danielle

  14. Danielle: I just pushed a new version to git which fixes the entry_id bug. Thanks for reporting it!

    Niel: don’t apologise for sending bug reports, I appreciate someone testing it and letting me know when they find something wrong :-) .. I’ll set up some better environment for bug reports etc than this place, but until then comments work. Anyway, my latest commit should fix the entry_id problem. I also updated the use of ‘title’ in the language file. And I’ve implemented an experimental thing for MSN – I haven’t tested it myself but in theory it should work like this: when you create a new site you need to go into the SEO Lite config and hit save once more to save the config for that site. This way you can have different templates etc. per site. Should work, but still untested from my side..

  15. When I uninstall your Module, it removes EE 2.0’s default title fields from all my PUBLISH pages! Do you have a work-around for this?

  16. Hi Steve, that seems very strange .. if you could give me login details for your backend so I can have a look around and see what the problem might be that’d be appreciated (send me an email at “mail @ this domain”) ..

  17. This is a very fine Add-on. Thank you Bjørn!

    A suggestion, I don’t know how hard it is to program, would be to add a conditional check in the parsing of the {exp:seo_lite url_title=”{segment_x}”} so that if no entry can be found with url_title == {segment_x}, the passed value {segment_x} is used as a title anyway. At this moment, if {segment_x} doesn’t relate to any url_title, nothing gets outputted.

  18. Hi, Thank you Bjørn for this fantastic module.

    @Moonbeetle i managed to do what you are trying to achieve with this

    {if segment_2 OR segment_1 != ”} {exp:seo_lite default_title=”{segment_1} | {segment_2}” url_title=”{segment_2}”} {/if}

    Bjørn , your opinion?

  19. Thanks guys,

    Lincolnpixel – yepp that works, if it finds an entry it will use the entry title, if it doesn’t it will use what you specified there. Actually that {if} isn’t necessary (unless you need it to know what to give to default_title of course)

    Moonbeetle – the solution above should have you covered .. I’m not sure what the best solution is here – I can see situations where people would just want the {site_name} to show if no entry was found (which is specified in the template, so SEO Lite should add nothing) .. anyway using default_title is the right approach for now.

  20. hi, just updated to the latest version with the “default_title_prefix” i’m getting this error

    A PHP Error was encountered

    Severity: Warning

    Message: htmlspecialchars() expects parameter 1 to be string, object given

    Filename: helpers/form_helper.php

    Line Number: 639

    any help?

  21. Hmm, I don’t see a reason why that should be the case. SEO Lite will just add a tab like any other third party addon .. is this a Structure issue?

  22. It’s most likely an upgrade problem of either Structure or ExpressionEngine. I noticed that when I add a new channel and set it to be managed by Structure I can get both the Structure and the SEO Lite tab in the publish entry form. While for a channel that already contained data that was entered prior to upgrading Structure to the latest version it seems impossible to have the SEO Lite tab added.

  23. Ok. It would be great if you could update me if you get any more info on this. If it turns out to be a SEO Lite problem I’d like to fix it, but yeah it does sound like a Structure/EE problem just from the info we have so far so I’ll just leave it at that for now.

  24. Found it! Apparantly some publish Toolbar layout was saved for the channel that was managed by Structure prior to having installed SEO Lite. My guess is that if EE finds a saved Toolbar layout for a channel, it will use this saved layout (obviously), but also neglects to list any new tabs for modules that have been installed AFTER the toolbar layout was changed.

  25. I’m running this on an MSM set up, and every time I update the config settings for a site, it overwrites the other site’s settings. I checked SQL manager, and it has a different row for each site created, with the correct site id, but each time I update the settings from any site’s SEO Lite config screen, I overwrite the rest.

  26. In the config: {title} – {site_name}

    In the template: {exp:seo_lite default_title=”Test page”}

    This should output: Test page – [Name of the site]

    For some reason I always get: – [Name of the site]

  27. Hey Bjorn – thanks for this great module! It’s very helpful.

    I’ve got a question on one thing though – In the following URL – the module isn’t picking up on the entry id at the end of the uri. I’ve tried both the {exp:seo_lite use_last_segment=”yes”} as well as the {exp:seo_lite entry_id=”{entry_id}”} and neither one of them pick up the entry.

    Any ideas? Thanks :-)

  28. Hmm, I see why use_last_segment doesn’t work cause it’s expecting the URL title, not the entry_id. Not sure what the best fix is there, maybe another parameter called use_last_segment_id or something. Don’t think I want to do magic there to find out whether or not it’s an url_title or entry_id.

    About using entry_id=”{entry_id}” that should work. I don’t know how your setup is but might it be that {entry_id} gets parsed after the seo_lite module so that what seo_lite gets is {entry_id} instead of 59?

    Anyway, a fix might simply be to use entry_id=”{segment_3}”

  29. 3 custom fields placed under the new tab is the same as this in a client eyes. So I have to ask…why bother?

  30. Nokolew; what if you have several channels? And you’d probably like to use the same header emebed/snippet on all pages, right? It also saves you a channel:entries tag to populate the title tag etc. I think this approach is better / easier than creating custom fields. it might not make much of a difference for the client, but it does make it easier for you.

  31. Hey, great plugin!! Thanks!

    I am trying to get the title bar to display something like this – Products | Introduction – Pulling the TITLE of the post into the titlebar and not the segment like it currently does. Any suggestions?

    I tried this with no luck… {exp:seo_lite url_title=”{segment_1}|{segment_2}|{segment_3}”}

Comments are closed.