如何让动态元数据更改 Vue 中 SEO 的实际页面源

问题描述 投票:0回答:3

我目前正在通过 Vue 路由器更改页面标题和(在不久的将来)元数据,如下所示:

$route (to, from){
    document.title = to.meta.title
}

当我检查标题时,效果很好:

    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Updated Page Title</title>
        <link href=" /css/app.css?id=b21c63ebd0cb0655a4d8" rel="stylesheet">
    </head>

但是,当我查看页面源代码时,它显示旧信息:

    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        *** <title>Old Page Title</title> ***
        <link href=" /css/app.css?id=b21c63ebd0cb0655a4d8" rel="stylesheet">
    </head>

为了 SEO 目的,我需要标题和元信息都是动态的。我的问题有两个:

  1. 使用vue-meta插件可以解决原始来源的页面标题问题吗?

  2. 我是否必须使用 SSR 或预渲染之类的东西来获取动态元信息,或者他们是否有任何其他路线类似于这种方法来做到这一点?

laravel vue.js seo vue-router
3个回答
2
投票
  • vue-meta
    仅在执行 JavaScript 并渲染页面时应用。所以,不,当您查看页面源代码时,您不会看到这些元标记。

  • 需要SSR或者预渲染吗?或许。这取决于您想要实现的目标。如果在网络爬虫支持 JS 之前拥有出色的 SEO 对您的网站至关重要?那么,是的。

当然,你仍然可以在后端添加一些meta标签。根据您使用的语言/框架,有很多选项可以帮助实现这一目标。例如,对于 Laravel,您可以检查 this 包。

此问题的另一个解决方法是将您的请求分类为来自前端的请求和来自爬虫的请求。例如,您可以通过检查请求中的用户代理来做到这一点,然后您可以相应地调整爬虫的响应(例如,将元标记注入标头)。


这是我建议的解决方法的示例:

IndexController.php

<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use Butschster\Head\Facades\Meta;
use Butschster\Head\Packages\Entities\OpenGraphPackage;

class IndexController extends Controller
{
    const CRAWLERS = [
        'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
        'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)',
        'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Safari/537.36',
        'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
        'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b',
        'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
        'Googlebot-Image/1.0',
        'Mediapartners-Google',
        'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
        'facebookexternalhit/1.1',
        'Twitterbot/1.0',
        'TelegramBot (like TwitterBot)',
    ];

    public function index()
    {
        if ($this->isACrawler()) {
            $this->applyMetaTags();

            return view('layouts.crawler');
        }

        return view('layouts.index');
    }

    public function isACrawler()
    {
        if (in_array(request()->userAgent(), self::CRAWLERS)) {
            return true;
        }

        return false;
    }

    private function applyMetaTags()
    {
        $title = 'Something';
        $description = 'Something else';

        Meta::prependTitle($title)
            ->addMeta('description', ['content' => $description]);

        $og = new OpenGraphPackage('some_name');

        $og->setType('Website')
            ->setSiteName('Your website')
            ->setTitle($title)
            ->setUrl(request()->fullUrl())
            ->setDescription($description);
        
        Meta::registerPackage($og);
    }
}

布局/crawler.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        @meta_tags

        <link rel="shortcut icon" href="{{ asset('favicon.ico') }}">
    </head>
</html>

正如您所见,我正在创建一个爬虫列表,然后检查请求以查看它是否来自爬虫,如果为真,则应用

metatags
并返回我为此目的创建的特定布局。

注意事项:

  • 这不会将元标记应用于您的正常请求。
  • 您需要找到一种方法来过滤请求 URL 并动态应用标签。例如使用正则表达式。

1
投票

我最终使用 hatef 提供的这个包来实现伪解决方法,而没有完整的 SSR 元编辑:https://github.com/butschster/LaravelMetaTags

我实现了一个中间件层来检查正在使用哪个域(多域应用程序),然后根据 vue 路由器的给定端点动态附加元标题:

<?php

namespace App\Http\Middleware;
use Illuminate\Support\Facades\Log;
use Illuminate\Routing\UrlGenerator;
use Butschster\Head\Facades\Meta;
use App\Models\Local\Domains;

use Closure;

class ValidateSEO
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $tempSplit = preg_split('/[\/\/]/', url()->current());
        $domain = Domains::where('domain', $tempSplit[2])->first();

        //length specific check based on site requirements and endpoints
        if($domain && count($tempSplit) <= 4){
            //set meta data based on brand site visited
            $linkedBrands = $domain->brands()->get();
            $selectedBrand = [];
            foreach($linkedBrands as $brand){
                $selectedBrand = $brand;
                break;
            }
            if(isset($selectedBrand['name'])){
                Meta::setTitle($selectedBrand['name'] . ' | Guide')
                ->setDescription($selectedBrand['description'])
                ->setKeywords(['sample' , 'keywords', 'here']);
            } else {
                Meta::setTitle(' Guide')
                ->setKeywords(['sample' , 'keywords', 'here']);
            }
            
        } else {
            //set meta data based on admin endpoint
            Meta::setTitle('Admin | ' . ucfirst($tempSplit[4]));
        }

        return $next($request);
    }
}

0
投票

我已经使用 npm 包 @vueuse/head 在 laravel-vue 项目中实现了。

npm 安装@vueuse/head

Laravel 是一个强大的 PHP 框架,擅长后端开发,而 Vue.js 是一个流行的 JavaScript 框架,擅长创建交互式前端体验。将这些技术与 @vueuse/head 包相结合,使您能够有效地管理动态元标签。

文章中查找代码:

https://www.bitkaleido.com/blog/dynamic-meta-tags-in-laravel-vue-seo-optimized-3

© www.soinside.com 2019 - 2024. All rights reserved.