How to dynamically generate SEO metatags in Laravel

There are many ways you can increase traffic in your website, e.g. social media promotion, ads etc. SEO management is one of the them important tools. There are many techniques in SEO management.

SEO metatags is one of the important part in the website as it helps in search engine crawlers to get details of your website. It will gives user better search results in search engine websites like Google, Bing etc. for your website.

Laravel provides simple and easy ways to add these metatags in your website. There are also many packages available for Laravel to generate SEO metatags. In this article, we will use artesaos/seotools package to generate SEO metatags. It provides helpers for some common SEO techniques in Laravel 5 and Lumen. It also generates SEO metas for Twitter Cards and Open Graph.

In this article we will create simple blogging website. Simply follow these steps and you can generates SEO metatags.

Note: We assume you have installed Composer and configured LAMP setup or you can check this articles to install LAMP and Composer. You should already know about basic commands.

Laravel project setup

First open your Terminal and go through directory where you want to create Laravel project. Then use this command to generate fresh Laravel project.

composer create-project laravel/laravel seotools

Now in the Terminal, go to the project root directory. Also open your Laravel project in text editor. Check if you have .env file in the root directory or copy .env.example file to .env. Set database credentials and also generate APP_KEY with bellow command.

php artisan key:generate

Now you have created fresh Laravel project. Run the bellow command to start the project and run the url localhost:8000 in browser.

php artisan serve

Install package

Now run this command to install SEOTools package.

composer require artesaos/seotools

Then open config/app.php file and add bellow lines in providers array.

'providers' => [
    Artesaos\SEOTools\Providers\SEOToolsServiceProvider::class,
],

And set alias in aliases array

'aliases' => [
    'SEOMeta'   => Artesaos\SEOTools\Facades\SEOMeta::class,
    'OpenGraph' => Artesaos\SEOTools\Facades\OpenGraph::class,
    'Twitter'   => Artesaos\SEOTools\Facades\TwitterCard::class,
    'JsonLd'   => Artesaos\SEOTools\Facades\JsonLd::class,
],

Configure package

Now run bellow command.

php artisan vendor:publish --provider="Artesaos\SEOTools\Providers\SEOToolsServiceProvider"

It will create config/seotools.php config file. In configuration file, you can define default values for SEO metatags. Open config/seotools.php file and edit values to set this value as default.

'meta' => [
    /*
     * The default configurations to be used by the meta generator.
     */
    'defaults'       => [
        'title'        => "Learn SEO management easily", // set false to total remove
        'titleBefore'  => false, // Put defaults.title before page title, like 'It's Over 9000! - Dashboard'
        'description'  => 'Learn SEO management easily for free at here', // set false to total remove
        'separator'    => ' - ',
        'keywords'     => [],
        'canonical'    => false, // Set null for using Url::current(), set false to total remove
        'robots'       => false, // Set to 'all', 'none' or any combination of index/noindex and follow/nofollow
    ],
    /*
     * Webmaster tags are always added.
     */
    'webmaster_tags' => [
        'google'    => null,
        'bing'      => null,
        'alexa'     => null,
        'pinterest' => null,
        'yandex'    => null,
    ],

    'add_notranslate_class' => false,
],
'opengraph' => [
    /*
     * The default configurations to be used by the opengraph generator.
     */
    'defaults' => [
        'title'       => 'Learn SEO management easily', // set false to total remove
        'description' => 'Learn SEO management easily for free at here', // set false to total remove
        'url'         => false, // Set null for using Url::current(), set false to total remove
        'type'        => false,
        'site_name'   => false,
        'images'      => [],
    ],
],
'twitter' => [
    /*
     * The default values to be used by the twitter cards generator.
     */
    'defaults' => [
        //'card'        => 'summary',
        //'site'        => '@HackTheStuff',
    ],
],
'json-ld' => [
    /*
     * The default configurations to be used by the json-ld generator.
     */
    'defaults' => [
        'title'       => 'Learn SEO management easily!', // set false to total remove
        'description' => 'Learn SEO management easily for free at here', // set false to total remove
        'url'         => false, // Set null for using Url::current(), set false to total remove
        'type'        => 'WebPage',
        'images'      => [],
    ],
],

Laravel Setup

Now let's create database table for getting dynamic data.

php artisan make:migration create_articles_table

And in the database/migrations folder, open migration file and add the table fields in the up() method.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title', 255);
            $table->string('slug', 255);
            $table->string('keywords', 255);
            $table->string('description', 255);
            $table->text('content');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

And then create table with bellow migrate command.

php artisan migrate

I have added some dummy data in the articles table for understanding. You may have already data in your table or you can use Faker to create dummy data for testing. You can check this article to create dummy data. Laravel already includes Faker package to generate dummy data.

Now Let's create model class with bellow command. This will create app/Article.php class file.

php artisan make:model Article

Now we will add article route in the routes/web.php file.

<?php

Route::get('/', '[email protected]')->name('homepage');

Route::get('/article/{slug}', '[email protected]')->name('article');

Also create controller class to handle routes.

php artisan make:controller ArticleController

And add two methods. home() method is for homepage and will display list of recent articles while article() method will display single article. Single article is the page where tags will change dynamically according to slug. 

<?php

namespace App\Http\Controllers;

use SEOMeta;
use OpenGraph;
use JsonLd;
use Twitter;
use App\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function home()
    {
        SEOMeta::setTitle('HackTheStuff - Homepage');
        SEOMeta::setDescription('One destination for all stuff');
        SEOMeta::setCanonical('https://hackthestuff.com/');

        OpenGraph::setDescription('One destination for all stuff');
        OpenGraph::setTitle('HackTheStuff - Homepage');
        OpenGraph::setUrl('https://hackthestuff.com/');
        OpenGraph::addProperty('type', 'articles');

        Twitter::setTitle('HackTheStuff - Homepage');
        Twitter::setSite('@HackTheStuff');

        JsonLd::setTitle('HackTheStuff - Homepage');
        JsonLd::setDescription('One destination for all stuff');
        JsonLd::addImage('https://hackthestuff.com/frontTheme/img/logo.png');

        $articles = Article::paginate(5);

        return view('home', compact('articles'));
    }

    public function article($slug)
    {
        $article = Article::where('slug', $slug)->first();

        SEOMeta::setTitle($article->title);
        SEOMeta::setDescription($article->description);
        SEOMeta::addMeta('article:published_time', $article->created_at->toW3CString(), 'property');
        SEOMeta::addKeyword($article->keywords);

        OpenGraph::setDescription($article->description);
        OpenGraph::setTitle($article->title);
        OpenGraph::setUrl('https://hackthestuff.com/article/'.$article->slug);
        OpenGraph::addProperty('type', 'article');
        OpenGraph::addProperty('locale', 'en-US');
        OpenGraph::addImage($article->image);

        Twitter::setTitle($article->title);
        Twitter::setSite('@HackTheStuff');
        
        JsonLd::setTitle($article->title);
        JsonLd::setDescription($article->description);
        JsonLd::setType('Article');
        JsonLd::addImage($article->image);

        return view('article', compact('article'));
    }
}

Now we have two controller method, so we will also need view file. Create bellow two files which will render metatags.

resources/views/home.blade.php

<!DOCTYPE html>
<html>
    <head>
        {!! SEOMeta::generate() !!}
        {!! OpenGraph::generate() !!}
        {!! Twitter::generate() !!}
        {!! JsonLd::generate() !!}
    </head>
    <body>
        <div>
            @foreach($articles as $article)
                <a href="{{ $article->slug }}" title="{{ $article->title }}">
                    <img src="{{ $article->image }}" alt="{{ $article->title }}">
                    <h4>{{ $article->title }}</h4>
                </a>
            @endforeach
        </div>
    </body>
</html>

resources/views/article.blade.php

<!DOCTYPE html>
<html>
    <head>
        {!! SEOMeta::generate() !!}
        {!! OpenGraph::generate() !!}
        {!! Twitter::generate() !!}
        {!! JsonLd::generate() !!}
    </head>
    <body>
        <div>
            <h1>{{ $article->title }}</h1>
            <img src="{{ $article->image }}" alt="{{ $article->title }}">
            <p>{!! $article->content !!}</p>
        </div>
    </body>
</html>

Now restart the server and open in your browser. You can see SEO metatags generated dynamically in every article page.

Conclusion

This way you can add dynamically SEO metatags in your website. Hope you liked this article. If you have any query, feel free to write in the bellow comment section.

Tags: