# Blog routes, SEO tags and scheduling

> **Diagram:** Each post page sends search engines a canonical URL, a robots tag and BlogPosting JSON-LD; sends social networks og: and twitter: cards with an absolute image URL; and links feed readers to the RSS 2.0 feed.

## Public routes (opt-in)

```php
'routes' => ['enabled' => true, 'prefix' => 'blog', 'layout' => 'layouts.app'],
```

Gives you `/blog`, `/blog/{slug}`, `/blog/category/{slug}`, `/blog/tag/{slug}`, `/blog/feed`, and the
Blade components `<x-ai-blog::meta-tags>`, `<x-ai-blog::structured-data>`, `<x-ai-blog::post-body>`.

Your layout needs `@yield('title')`, `@yield('content')` and `@stack('head')`; the pages put their tags in the stack.

### What the pages send to search engines

- **Post pages:** a canonical URL (the post's own address, or its `canonical_url` when you set one), `og:` and
  `twitter:` cards with an absolute image URL, `article:published_time` and `article:modified_time`, a
  `robots` tag that allows large image previews, an RSS link, and `BlogPosting` JSON-LD with the page address and
  publisher. A `## Question?` heading followed by an answer adds `FAQPage` JSON-LD.
- **Index, category and tag pages:** a description, a canonical URL, `prev`/`next` links, an RSS link and a
  distinct title on every page of results ("Blog — Page 2 — My Site").
- **Feed:** RSS 2.0 with language, last build date and permalink GUIDs.
- Tags with nothing to say are left out rather than sent empty: a post with no description gets no
  `description` tag. Set `ai-blog.seo.description` (or `AI_BLOG_SEO_DESCRIPTION`) for the blog's own description.

## Scheduler

```php
// routes/console.php
Schedule::command('ai-blog:publish-scheduled')->everyMinute();
```
