Khóa học Newnet Framework

Bài 7: Quản lý SEO - Module SEO

Việc website có tiếp cận với người dùng nhiều hay không, nó phụ thuộc vào thứ hạn của website của bạn trên google ngoại trừ việc bạn chạy ads. Cách seo căn bản nhất là url và các thẻ meta data. SEO sẽ giải quyết bài toán này, giúp ta custom dễ dàng url cũng như các tag meta của website.

SEO

Tính năng seo được cấu hình trực tiếp vào từng model hoặc áp dụng cấu hình seo mặc định /admin/seo/setting

Để tính hợp tính năng seo vào model ta khai báo Trait vào model mà sử dụng blade alias @seo trong form tạo model.

Ta tiếp tục ví dụ với module CMS

<?php

namespace Newnet\Cms\Models;
...
use Newnet\Seo\Traits\SeoableTrait;

class Post extends Model
{
    use SeoableTrait;

    protected $table = 'cms__posts';

    protected $fillable = [
        'name',
    ];

    public function getUrl()
    {
        return route('cms.web.post.detail', $this->id);
    }
}

khi khai báo SeoableTrait, nó sẽ báo lỗi ngay vì trong trait này đã khai báo abstract public function getUrl(); nên ta phải khai báo hàm này bên trong model, và nó là đường dẫn chi tiết của model.

Như vậy, ta sẽ có route tương ứng:

Route::get('cms/post/{id}', [PostController::class, 'detail'])
    ->name('cms.web.post.detail');

và controller detail

public function detail($id, Request $request)
{
    $post = $this->postRepository->find($id);
    return view('cms::web.post.detail', compact('post'));
}

Ở phần khởi tạo dữ liệu, ta khai báo @seo là xong, việc còn lại SeoableTrait đã xử lý giúp ta.

<ul class="nav nav-tabs scrollable">
    <li class="nav-item">
        <a class="nav-link active save-tab" data-toggle="pill" href="#cmsPostInfo">
            {{ __('cms::post.tabs.info') }}
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link save-tab" data-toggle="pill" href="#cmsPostSeo">
            {{ __('cms::post.tabs.seo') }}
        </a>
    </li>
</ul>

<div class="tab-content mt-3">
    <div class="tab-pane fade show active" id="cmsPostInfo">
        <div class="row">
            <div class="col-12">
                @input(['name' => 'name', 'label' => __('cms::post.name')])
            </div>
        </div>
    </div>

    <div class="tab-pane fade" id="cmsPostSeo">
        @seo
    </div>
</div>

Khi khởi tạo 1 module mới, mọi thứ đã được tạo sẵn cho chúng ta, chỉ cần chỉnh sửa lại là hoạt động ngay.

REDIRECT

Bài toán: Website của chúng ta có 1 bài viết hay và bài viết đó vô tình bị xóa và không thể khôi phục được. Tuy nhiên vị trí của nó trên google search vẫn on top. Nhưng khi truy cập trực tiếp vào link thì bị lỗi, do không tồn tại bài viết. Điều này không hề tốt và bị mất tương tác. 

Để giải quyết vấn đề trên, chúng ta sẽ chuyển hướng khi trang bị lỗi và được cấu hình trong admin /admin/seo/error-redirect.

Ngoài vấn đề chuyển hướng khi trang bị lỗi, NewNet Framework cũng hỗ trợ việc chuyển hướng trước khi tải trang. Nghĩa là không cần biết link có tồn tại hay link bị hỏng, đều chuyển hướng đi. Nhưng hiện tại chứng năng này đang bị tắt bởi việc detach có cấu hình trong admin hay không gây ảnh hưởng đến hiệu năng website. Chúng ta có thể vào phần config và thay đổi giá trị enable_pre_redirect => true hoặc khai báo trong file môi trường .env SEO_ENABLE_PRE_REDIRECT=true.

Cách này như mình đã nói thì nó bị giảm hiệu năng khi phải kiểm tra trước khi tải trang. Nhưng có cách khác có thể tối ưu việc này bằng cách sử dụng javascript để chuyển hướng trang. Sau khi load trang, ta sẽ dùng js fetch lên server để check url hiện tại có được cấu hình trong phần /admin/seo/pre-redirect hay không. Nếu tồn tại setting thì dùng window.location.href chuyển hướng.

@push('scripts')
    <script>
        fetch('seo/pre-redirect' + window.location.pathname)
            .then((res) => res.json())
            .then((response) => {
                if (response.success) {
                    window.location.href = response.url;
                }
            })
    </script>
@endpush

Dùng JS như này thì không ảnh hưởng tới thời gian load trang, nhưng phải đảm bảo trang phải hoạt động để load được script này. Nếu trang bị lỗi có thể dùng cách trên, chuyển hướng khi trang lỗi.  Thì đâu cũng vào đấy cả thôi.