Larry Hudson

Writing about making websites


Adding SEO tags to Eleventy

27 March 2021

An important part of setting up a new website is making sure that the content is presented properly to search engines and social networks such as Twitter and Facebook.

I’ve just added SEO tags to this Eleventy site powered by WordPress and WPGraphQL.

Rather than using a WordPress plugin, I followed Dan Fascia’s example and used a block in the Nunjucks template that set some defaults for the homepage, and then overrode those defaults on specific post pages.

I added a new ‘site.js’ file in my _data folder so that data about the site, including my name, Twitter handle and a description, is available globally:

module.exports = {
    'baseURL': 'https://www.larryhudson.io',
    'title': 'Larry Hudson',
    'description': 'Larry Hudson is a web developer based in Melbourne, Australia, focusing on simplicity and accessibility.',
    'twitter': 'larryhudsondev'
}

Then in my layouts/_base.njk, I added the meta tags. I separated the tags that do not change (eg. author, site URL) and the tags that change from template to template (eg. page title, page description).

<!--Twitter Card-->
    <meta name="twitter:card" content="summary">
    <meta name="twitter:site" content="@{{site.twitter}}">
    <meta name="twitter:creator" content="@{{site.twitter}}">
    <meta name="twitter:url" content="{{site.baseURL}}{{page.url}}">

    <!--Schema-->
    <link rel="author" href="{{site.baseURL}}">
    <link rel="publisher" href="{{site.baseURL}}">
        
    <!-- Facebook OpenGraph -->
    <meta property="og:url" content="{{site.baseURL}}{{page.url}}">
    <meta property="og:type" content="website">
    <meta property="og:site_name" content="{{site.title}}">
    <meta property="og:locale" content="en_AU">
    <meta property="article:author" content="{{site.baseURL}}">
    
    {%- block seo -%}
    <!--Twitter Card-->
    <meta name="twitter:title" content="{{title}}">
    <meta name="twitter:description" content="{{ site.description }}">
    
    <!--Schema-->
    <meta itemprop="name" content="{{title}}">
    <meta name="description" content="{{ site.description }}">
    
    <!-- Facebook OpenGraph -->
    <meta property="og:title" content="{{title}}">
    <meta property="og:description" content="{{ site.description }}">
    {%- endblock -%}

Then in specific templates, such as layouts/post.njk, I can override the block to change the title and description tags:

{% block seo %}
    <!--Twitter Card-->
    <meta name="twitter:title" content="{{post.title}}">
    <meta name="twitter:description" content="{{ post.excerpt|striptags|truncate(196) }}">
    
    <!--Schema-->
    <meta itemprop="name" content="{{post.title}}">
    <meta name="description" content="{{ post.excerpt|striptags|truncate(196) }}">
    
    <!-- Facebook OpenGraph -->
    <meta property="og:title" content="{{post.title}}">
    <meta property="og:description" content="{{ post.excerpt|striptags|truncate(196) }}">
{% endblock %}

You can check out the GitHub repository if you want a deeper dive into how I’ve set this up.