1. Go to this page and download the library: Download rasuvaeff/yii3-seo library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
rasuvaeff / yii3-seo example snippets
use Rasuvaeff\Yii3Seo\MetadataDefaults;
use Rasuvaeff\Yii3Seo\OpenGraph;
use Rasuvaeff\Yii3Seo\SelfCanonical;
use Rasuvaeff\Yii3Seo\SelfCanonicalMiddleware;
use Rasuvaeff\Yii3Seo\Title;
use Rasuvaeff\Yii3Seo\TwitterCard;
return [
'rasuvaeff/yii3-seo' => [
'defaults' => new MetadataDefaults(
metadataBase: 'https://example.com',
title: Title::template('%s | My Store', default: 'My Store'),
openGraph: new OpenGraph(siteName: 'My Store', locale: 'en_US'),
twitter: new TwitterCard(card: 'summary_large_image', site: '@mystore'),
selfCanonical: SelfCanonical::enabled(), // optional
),
],
'middlewares' => [
SelfCanonicalMiddleware::class, // only for selfCanonical
// ... router and the rest of the stack
],
];
use Rasuvaeff\Yii3Seo\SeoInjection;
use Yiisoft\Yii\View\Renderer\CsrfViewInjection;
use Yiisoft\Yii\View\Renderer\WebViewRenderer;
return [
WebViewRenderer::class => [
'__construct()' => [
'injections' => [
CsrfViewInjection::class,
SeoInjection::class,
],
],
],
];
use Psr\EventDispatcher\EventDispatcherInterface;
use Rasuvaeff\Yii3Seo\Metadata;
use Rasuvaeff\Yii3Seo\OgImage;
use Rasuvaeff\Yii3Seo\OpenGraph;
use Rasuvaeff\Yii3Seo\SeoMetadataEvent;
final readonly class ProductAction
{
public function __construct(
private EventDispatcherInterface $eventDispatcher,
private ProductResponder $responder,
) {}
public function __invoke(): ResponseInterface
{
$this->eventDispatcher->dispatch(new SeoMetadataEvent(
metadata: new Metadata(
title: 'Awesome Product', // -> "Awesome Product | My Store"
description: 'Buy the awesome product.',
openGraph: new OpenGraph(
type: 'product',
images: [new OgImage(url: '/og/awesome.jpg', width: 1200, height: 630, alt: 'Awesome')],
),
),
));
return $this->responder->render('product/view');
}
}
<!-- layout.php -->
use Yiisoft\Html\Html;
use Rasuvaeff\Yii3Seo\MetadataResolver;
$resolved = (new MetadataResolver())->resolve(
metadata: new Metadata(title: 'Product', description: 'Description'),
defaults: $defaults,
);
$resolved->getTitle(); // "Product | My Store"
$resolved->getOpenGraph(); // merged OpenGraph with title/description fallback
$resolved->getTwitter(); // merged Twitter card with OpenGraph fallback
use Rasuvaeff\Yii3Seo\MetadataValidator;
$result = (new MetadataValidator())->validate($seo->getResolvedMetadata());
$result->isValid(); // true when there are no errors (warnings are advisory)
$result->hasErrors();
$result->getErrors(); // list<MetadataIssue>
$result->getWarnings(); // list<MetadataIssue>
foreach ($result->getIssues() as $issue) {
echo $issue->getSeverity()->value, ' ', $issue->getCode(), ': ', $issue->getMessage(), "\n";
}
// error title.missing: Page title is empty
// warning canonical.missing: Canonical URL is not set
// config/common/params.php
use Rasuvaeff\Yii3Seo\MetadataDefaults;
use Rasuvaeff\Yii3Seo\SelfCanonical;
new MetadataDefaults(
metadataBase: 'https://example.com',
selfCanonical: SelfCanonical::enabled(), // drop every query parameter
// selfCanonical: SelfCanonical::keepingQuery('page'), // keep an explicit allow-list
);
// config/common/params.php — application middleware stack
use Rasuvaeff\Yii3Seo\SelfCanonicalMiddleware;
'middlewares' => [
SelfCanonicalMiddleware::class,
// ... router and the rest of the stack
],
new OpenGraph(
title: null, // falls back to Metadata title
description: null, // falls back to Metadata description
type: null, // inherits defaults; renders og:type "website" if unset everywhere
url: '/page', // resolved against metadataBase
siteName: 'My Site',
locale: 'en_US',
images: [new OgImage(url: '/og.jpg', width: 1200, height: 630, alt: 'Alt', type: 'image/jpeg')],
)
new TwitterCard(
card: null, // summary | summary_large_image | app | player; inherits defaults, renders "summary_large_image" if unset everywhere
site: '@site',
creator: '@creator',
title: null, // falls back to OpenGraph/title
description: null, // falls back to OpenGraph/description
images: [], // falls back to OpenGraph images
)
new Icons(icon: '/favicon.ico', shortcut: '/favicon.ico', apple: '/apple.png', other: [
new Icon(rel: 'mask-icon', url: '/safari.svg'),
]);
new Verification(google: 'g-token', yandex: 'y-token', bing: 'b-token', other: ['me' => 'token']);
new Author(name: 'Alice', url: 'https://example.com/alice');
final class ProductSitemapProvider implements SitemapProviderInterface
{
public function __construct(private ProductRepository $products) {}
public function getUrls(): iterable
{
foreach ($this->products->each() as $product) {
yield new SitemapUrl(
loc: "/products/{$product->id}",
lastModified: $product->updatedAt,
priority: 0.8,
);
}
}
}
$sitemap = new Sitemap($provider->getUrls(), 'https://example.com');
foreach ($sitemap->toChunks() as $chunk) {
echo $chunk;
}
$exporter = new SitemapFileExporter(
metadataBase: 'https://example.com',
limits: new SitemapLimits(), // defaults to the protocol maximums
publicPath: '/', // URL path the files are served under
);
$files = $exporter->export($provider->getUrls(), '/var/www/public');
final class SitemapAction
{
public function __construct(
private SitemapResponseFactory $responses,
private ProductSitemapProvider $provider,
) {}
public function __invoke(): ResponseInterface
{
return $this->responses->create(new Sitemap($this->provider->getUrls(), 'https://example.com'));
}
}