Laravel Ecommerce Tutorial: Part 9, SEO
Tags: laravel, programming, php, webdev
Published: 2023-07-24 00:08:04

In the [last tutorial,](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-8-product-variations) we added the ability to create product variations like color black etc. This is the last post on managing products and in this post we will add the ability to configure Search Engine Optimize for the product by adding things like meta descriptions, keywords, and titles.

This is part 9 of the ongoing tutorial series on [building an ecommerce store in Laravel from start to deployment](<https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-1-introduction >). If you want to jump to a specific section, use the following table of contents:

*   [Laravel Ecommerce Tutorial: Part 1, Introduction](<https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-1-introduction > "Laravel Ecommerce Tutorial: Part 1, Introduction")
*   [Laravel Ecommerce Tutorial: Part 2, Users And Authorization](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-2-users-and-authorization "Laravel Ecommerce Tutorial: Part 2, Users And Authorization")
*   [Laravel Ecommerce Tutorial: Part 3, Managing Roles and Permissions](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-3-managing-roles-and-permissions "Laravel Ecommerce Tutorial: Part 3, Managing Roles and Permissions")
*   [Laravel Ecommerce Tutorial: Part 4, Managing Product Categories](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-4-managing-product-categories "Laravel Ecommerce Tutorial: Part 4, Managing Product Categories")
*   [Laravel Ecommerce Tutorial: Part 5, Managing Brands](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-5-managing-brands "Laravel Ecommerce Tutorial: Part 5, Managing Brands")
*   [Laravel Ecommerce Tutorial: Part 6.1, Creating Products](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-61-creating-products "Laravel Ecommerce Tutorial: Part 6.1, Creating Products")
*   [Laravel Ecommerce Tutorial: Part 6.2, Listing And Deleting Products](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-62-listing-and-deleting-products "Laravel Ecommerce Tutorial: Part 6.2, Listing And Deleting Products")
*   [Laravel Ecommerce Tutorial: Part 6.3, Editing Products](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-63-editing-products "Laravel Ecommerce Tutorial: Part 6.3, Editing Products")
*   [Laravel Ecommerce Tutorial: Part 6.4, Refactoring Products](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-64-refactoring-products "Laravel Ecommerce Tutorial: Part 6.4, Refactoring Products")
*   [Laravel Ecommerce Tutorial: Part 7, Product Options](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-7-product-options "Laravel Ecommerce Tutorial: Part 7, Product Options")
*   [Laravel Ecommerce Tutorial: Part 8, Product Variations](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-8-product-variations "Laravel Ecommerce Tutorial: Part 8, Product Variations")
*   [Laravel Ecommerce Tutorial: Part 9, SEO](https://flixtechs.co.zw/posts/laravel-ecommerce-tutorial-part-9-seo "Laravel Ecommerce Tutorial: Part 9, SEO")

This is going to be very simple. Nothing complicated here, we just add SEO fields to the product model and let the controller update the details when it receives a request from the frontend.

## Models and migrations

Let's start by creating a migration file to add the SEO fields

```sh
php artisan make:migration add_seo_fields_to_products
```

This will create a migration to edit the products table, talk about convention over configuration

Open the newly created migration file and dump the following snippet

```php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('products', function (Blueprint $table) {
            $table->string('canonical_url')->nullable();
            $table->string('seo_title')->nullable();
            $table->string('seo_keywords')->nullable();
            $table->text('seo_description')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('products', function (Blueprint $table) {
            $table->dropColumn(['canonical_url', 'seo_title', 'seo_description', 'seo_keywords']);
        });
    }
};
```

Save the file and run the migration

```bash
php artisan migrate
```

The keywords will be comma separated, if you want to be ambitious, you could cast that to an array in the products model, but I don't think it's necessary. We've finished with models and migrations, let's move on to the next thing.

## Controllers and views

In this section, we start by telling Laravel what kind of request to expect by modifying the product form request to validate our newly created fields

Open the `App\Http\Requests\StoreProductRequest` and add the following snippet at the end of the validation array in the `rules` method

```php
'canonical_url' => 'sometimes|nullable|string|max:255|url|active_url',
'seo_title' => 'sometimes|nullable|string|max:255',
'seo_description' => 'sometimes|nullable|string|max:255',
'seo_keywords' => 'sometimes|nullable|string|max:255'
```

Also add this to `App\Http\Requests\UpdateProductRequest` in the `rules` method

Now we need to add the markup to allow the user to define these fields, open the `admin.products.create` view and find the Search Engine Optimization card.

Replace the SEO card with the following snippet

```html
<div class="card rounded-lg">
    <div class="card-header">
        <h4>Search Engine Optimization</h4>
    </div>
    <div class="card-body">
        <div class='form-group'>
            <label for='canonical_url' class='form-label'>
                Canonical URL
            </label>
            <x-input name="canonical_url" error='canonical_url' form="storeProduct" :value="old('canonical_url')" />
        </div>
        <div class='form-group'>
            <label for='seo_title' class='form-label'>
                SEO Title
            </label>
            <x-input name="seo_title" error='seo_title' form="storeProduct" :value="old('seo_title', '')" />
        </div>

        <div class='form-group'>
            <label for='seo_keywords' class='form-label'>
                SEO Keywords
            </label>
            <x-input name="seo_keywords" error='seo_keywords' form="storeProduct" :value='old("seo_keywords","")' />
        </div>

        <div class='form-group'>
            <label class='form-label' for='seo_description'>
                SEO Description
            </label>
            <textarea name="seo_description" id="seo_description" form="storeProduct" class='form-control'>{{ old('seo_description', '') }}</textarea>
        </div>
    </div>
</div>
```

Open the `admin.products.edit` view and replace the SEO card with

```html
<div class="card rounded-lg">
    <div class="card-header">
        <h4>Search Engine Optimization</h4>
    </div>
    <div class="card-body">
        <div class='form-group'>
            <label for='canonical_url' class='form-label'>
                Canonical URL
            </label>
            <x-input name="canonical_url" error='canonical_url' form="storeProduct" :value="old('canonical_url', $product->canonical_url)" />
        </div>
        <div class='form-group'>
            <label for='seo_title' class='form-label'>
                SEO Title
            </label>
            <x-input name="seo_title" error='seo_title' form="storeProduct" :value="old('seo_title', $product->seo_title)" />
        </div>

        <div class='form-group'>
            <label for='seo_keywords' class='form-label'>
                SEO Keywords
            </label>
            <x-input name="seo_keywords" error='seo_keywords' form="storeProduct" :value='old("seo_keywords", $product->seo_keywords)' />
        </div>

        <div class='form-group'>
            <label class='form-label' for='seo_description'>
                SEO Description
            </label>
            <textarea name="seo_description" id="seo_description" form='storeProduct' class='form-control'>{{ old('seo_description', $product->seo_description) }}</textarea>
        </div>
    </div>
</div>
```

And now navigate to /products/create and create a new product with SEO settings built in place. This marks the end of this post. However, if you wish to be creative you can add open graph tags to the products, for instance you could create an open graph model and then create a polymorphic relationship to the product or something like that.

In the next post, we will create the home page of our ecommerce, the part that customers see in the next one after that, we create a product list with the ability to filter by price category and all those fancy features.

To make sure you don't miss the post when it's out, follow me on DEV, and you will get a notification as soon as it's published.

In the meantime, Happy codding!