Menu

Cách tạo sitemap đơn giản cho Laravel

Kiến thức lập trình | Aug 26, 2024 1,325
#frontend developer #SEO #Lộ trình FullStack #Lộ trình học #backend develop

Hướng dẫn tạo Sitemap đơn giản trong Laravel

Sitemap là một tệp XML quan trọng trong SEO, giúp các công cụ tìm kiếm như Google, Bing hiểu rõ cấu trúc website, từ đó lập chỉ mục (index) nhanh chóng và chính xác hơn. Đối với các dự án Laravel, chúng ta hoàn toàn có thể tự xây dựng Sitemap Controller để sinh sitemap động từ dữ liệu trong cơ sở dữ liệu.

Trong bài viết này, mình sẽ hướng dẫn bạn cách tạo sitemap trong Laravel cho những website có số lượng trang lớn (hơn 2000 trang). Việc phân trang (paginate) sitemap là rất cần thiết, bởi nó giúp giảm dung lượng mỗi tệp sitemap, đảm bảo Google có thể đọc dễ dàng, đồng thời giúp chúng ta quản lý và mở rộng hệ thống sitemap một cách khoa học hơn.

Một điểm quan trọng khác là việc tối ưu đường dẫn URL cho thân thiện với SEO. Thay vì sử dụng ID khô khan, bạn nên cấu hình slug hoặc key đẹp mắt, ví dụ:
https://example.com/cach-tao-sitemap
Điều này không chỉ giúp cải thiện thứ hạng SEO mà còn nâng cao trải nghiệm người dùng.

Bước 1: Khai báo route


use App\Http\Controllers\SitemapController;

Route::get('sitemap.xml', [SitemapController::class, 'index'])->name('sitemap.index');
Route::get('sitemap/{page}/{slug}', [SitemapController::class, 'central'])->name('sitemap.central');

Ở đây chúng ta có 2 route:

  • sitemap.xml: sitemap index chính, chứa danh sách các sitemap con.
  • sitemap/{page}/{slug}: sitemap chi tiết cho từng loại dữ liệu (blog, page, product, …).

>>> Xem thêm : Cách gửi sitemap lên Google Search Console

Bước 2: Tạo Controller xử lý sitemap

Tạo file app/Http/Controllers/SitemapController.php với nội dung cơ bản như sau:


namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Cache;
use App\Models\Post;
use Carbon\Carbon;

class SitemapController extends Controller
{
    protected $perPage = 100;
    protected $cacheTtl = 3600; // 1 giờ

    public function index()
    {
        $cacheKey = 'sitemap_index';
        $xml = Cache::remember($cacheKey, $this->cacheTtl, function () {
            $sitemaps = [];
            $pageCount = ceil(Post::where('post_type', 'page')->count() / $this->perPage);
            for ($i = 1; $i <= $pageCount; $i++) {
                $sitemaps[] = url("sitemap/{$i}/page.xml");
            }

            $blogCount = ceil(Post::where('post_type', 'post')->count() / $this->perPage);
            for ($i = 1; $i <= $blogCount; $i++) {
                $sitemaps[] = url("sitemap/{$i}/blog.xml");
            }

            return view('sitemap_index', compact('sitemaps'))->render();
        });

        return Response::make($xml, 200, ['Content-Type' => 'application/xml']);
    }

    public function central($page, $slug)
    {
        switch ($slug) {
            case 'page.xml':
                return $this->pages($page);
            case 'blog.xml':
                return $this->blogs($page);
            default:
                return $this->index();
        }
    }

    private function pages($page)
    {
        $xml = Cache::remember("sitemap_pages_{$page}", $this->cacheTtl, function () use ($page) {
            $posts = Post::where('post_type', 'page')->paginate($this->perPage, ['*'], 'page', $page);

            $urls = $posts->map(function ($post) {
                return [
                    'url' => url($post->slug),
                    'lastmod' => $post->updated_at ? Carbon::parse($post->updated_at)->toAtomString() : Carbon::now()->toAtomString(),
                    'priority' => 0.6
                ];
            })->toArray();

            return view('sitemap', compact('urls'))->render();
        });

        return Response::make($xml, 200, ['Content-Type' => 'application/xml']);
    }

    private function blogs($page)
    {
        $xml = Cache::remember("sitemap_blogs_{$page}", $this->cacheTtl, function () use ($page) {
            $posts = Post::where('post_type', 'post')->paginate($this->perPage, ['*'], 'page', $page);

            $urls = $posts->map(function ($post) {
                return [
                    'url' => url('tin-tuc/' . $post->slug),
                    'lastmod' => $post->updated_at ? Carbon::parse($post->updated_at)->toAtomString() : Carbon::now()->toAtomString(),
                    'priority' => 0.68
                ];
            })->toArray();

            return view('sitemap', compact('urls'))->render();
        });

        return Response::make($xml, 200, ['Content-Type' => 'application/xml']);
    }
}

>>> Xem thêm : Các yếu tố giúp tối ưu SEO website đạt điểm cao

Bước 3: Tạo view cho sitemap

File resources/views/sitemap_index.blade.php:


{!! '<?xml version="1.0" encoding="UTF-8"?>' !!}
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    @foreach($sitemaps as $sitemap)
        <sitemap>
            <loc>{{ $sitemap }}</loc>
            <lastmod>{{ \Carbon\Carbon::now()->toAtomString() }}</lastmod>
        </sitemap>
    @endforeach
</sitemapindex>

File resources/views/sitemap.blade.php:


@php echo '<?xml version="1.0" encoding="UTF-8"?>'; @endphp
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
    @foreach ($urls as $sitemap)
        <url>
            <loc>{{ $sitemap['url'] }}</loc>
            <lastmod>{{ $sitemap['lastmod'] ?? \Carbon\Carbon::now()->toAtomString() }}</lastmod>
            <changefreq>{{ $sitemap['update'] ?? 'weekly' }}</changefreq>
            <priority>{{ $sitemap['priority'] ?? '0.5' }}</priority>
        </url>
    @endforeach
</urlset>

Kết luận

Với cách làm trên, bạn có thể dễ dàng tạo sitemap động trong Laravel, phân trang và hỗ trợ nhiều loại nội dung (pages, blogs, products...). Điều này giúp Google index website nhanh chóng và tối ưu SEO.

Bài viết tiếp theo : Lộ trình để trở thành Frontend Developer cho người mới

Chia sẻ bài viết

Tính Thần Số Học Tại Đây

Khám phá bản thân qua các con số từ tên và ngày sinh của bạn

Bình luận

Chia sẻ cảm nghĩ của bạn về bài viết này.

Chưa có bình luận nào. Hãy là người đầu tiên!

Danh sách các bài viết mới nhất 112 bài viết

Danh mục bài viết

Kiến thức lập trình

Khám phá kiến thức lập trình tại Khaizinam Site: hướng dẫn, mẹo, ví dụ thực tế và tài nguyên giúp bạn nâng cao kỹ năng lập trình hiệu quả.

Mã nguồn lập trình

Chia sẻ các mã nguồn hữu ích cho mọi người sử dụng.

Thế giới

Tin tức vòng quanh thế giới

Công nghệ

Enim sit aut facere ipsum dolores corrupti at reprehenderit. Ea illum doloribus et tempore maiores iure. Laboriosam iste enim non expedita minima libero.

Xã hội

Tin tức xã hội, biến động 24h qua trên toàn cầu

Manga Anime

Tin tức về anime, manga được cập nhật mới nhất

Thể thao

Tin tức thể thao toàn cầu được cập nhật hàng ngày

Giải trí

Tin tức giải trí toàn thế giới được cập nhật mới nhất,

Dịch vụ

Khám phá các bài viết trong danh mục này

Làng hải tặc FNS

Game làng hải tặc của Funnysoft, sự kết hợp hoàn hảo giữa HSO, HTTH của teamobi

Pháp luật

Khám phá các bài viết trong danh mục này

Ngoài lề

Khám phá các bài viết trong danh mục này

Thần số học

Khám phá các bài viết trong danh mục này

English flag English

Tính Thần Số Học

Khám phá bản thân qua các con số

Tìm Hiểu