SEO
The tags
Put @seo in the <head> of every layout, next to @hreflang:
<head>
<meta charset="utf-8">
@seo
@hreflang
</head>@seo prints the <title>, the description, the canonical address, the robots tag when the page is not to be listed, and the Open Graph and Twitter tags used when the address is shared. Do not write these tags by hand.
| Tag | Value: the first one that exists |
|---|---|
| Title | What the editor wrote for search engines, the title of the record, the name of the site. Written in the title format of the Settings page, :title | :site by default. The home page is titled like the site |
| Description | What the editor wrote for search engines, the excerpt of the record, the description of the site |
| Image | The share image of the record, its cover, the share image of the site. The original file is used, not a WebP size, since not every network reads WebP |
noindex | The record asks for it, the record is not published, or the Settings page asks search engines not to list the site |
| Canonical | The current address without its query string |
Pages
For a page of the core there is nothing to do. Each page has a "Search engines" section in its form, and the core fills the tags before showing the view.
Routes of the site
Fill the tags from a record, or value by value:
use Melasistema\MelaCms\Seo;
Route::get('/blog/{slug}', function (string $slug, Seo $seo) {
$post = Post::published()->whereSlug($slug)->firstOrFail();
$seo->for($post)->type('article');
return view('posts.show', ['post' => $post]);
});
Route::get('/blog', function (Seo $seo) {
$seo->title('Blog')->description('Everything we wrote.');
return view('posts.index');
});Seo::for() reads the title, the excerpt and the cover_id of any model, and marks an unpublished record noindex. Other setters: image($media) and noindex().
To let an editor write the title, description and share image of a record, give the model a nullable json column seo and the Melasistema\MelaCms\Concerns\HasSeo trait, and add SeoFields::make() to the form of its resource.
Sitemap
/sitemap.xml lists every published page in every site language, with its last change and the other languages as alternates. A page kept out of search engines is left out.
Add the site's own content under sitemap in the config:
'sitemap' => [
\Melasistema\MelaCms\Models\Page::class,
\App\Models\Post::class, // a model with a url(?string $locale) method
'blog', // a page served by a route of the site
],// On the Post model
public function url(?string $locale = null): string
{
$locale ??= app(Languages::class)->current();
return app(Languages::class)->url($locale, 'blog/'.$this->slugIn($locale));
}An empty array removes the sitemap. It also answers 404 while the Settings page asks search engines not to list the site.
A fresh Laravel app has a static public/robots.txt. Add a Sitemap: https://example.com/sitemap.xml line to it.
Known limits
- No structured data (JSON-LD).
- No sitemap index: one file for everything, up to 50,000 addresses.
- The sitemap is built on every request, without a cache.
- No redirects manager.
- The site-wide
noindexis a meta tag only. A page that does not print@seois not covered.