# SEO patterns (`seo-patterns.md`)

This document narrates **`layouts/app.blade.php`**, `config/seo.php`, and `App\Helpers\SeoHelper` interplay.

## Global layout responsibilities

1. `<title>` + meta description sourcing from Blade `@section` fallbacks tied to curated translation/meta helpers.
2. Canonical via explicit `@section('canonical')` or `SeoHelper::getCanonicalUrl()`.
3. hreflang aggregation honoring **indexability heuristics** (`SeoHelper::hasLocaleTranslationsForIndexing`).
4. Robots directives default to `index, follow`; non-indexable locales switch to **`noindex, follow`** to avoid duplicate thin pages appearing in SERPs without blocking equity flow entirely.
5. Open Graph / Twitter mirror canonical URL + OG image dims `1200x630`.
6. Baseline structured data shipped for Organization, WebSite, optional Site Navigation.
7. Microsoft Clarity + GA4 gated to production builds with anonymized IPs.

Refer to snippets in layouts for exact identifiers (GA property `G-TL98YQZC94`, Clarity id `po8nux164q` — update here if infra rotates).

## `config/seo.php` hotspots

| Key | Meaning |
| --- | --- |
| `languages` | hreflang + OG locale interplay |
| `url_translations` | Path segment localization |
| `locale_geo` | Default geo-meta per localized experience |
| `organization` | Feeds structured data constants |
| `hreflang_x_default_locale` | Alternate default pointer |

### Title tagging rules

Prefer `SeoHelper::getPageSeo('{key}')` where defined; fallback to descriptive `@section('title')`.

Avoid redundant brand stuffing if layout already concatenates authoritative suffix patterns.

### Meta descriptions

Maintain **purposeful uniqueness** across programmatic combos; disallow identical strings across large location matrices.

Hard limit around **150–165 visible characters** in SERP preview even though Laravel does not auto-truncate.

### Slugs & redirects

Historical `/industry-services/*` rewriting lives in closure near bottom of `routes/web.php`; never regress those without mapping tables.

Slug changes require:

1. 301 map
2. hreflang regeneration
3. Sitemap regeneration + cache invalidation workflows

### Structured patterns

| Type | Typical generator |
| --- | --- |
| FAQ | `SeoHelper::generateFaqSchema($faqs,$url)` |
| Breadcrumbs | `generateBreadcrumbSchema` |
| Contact | Embedded JSON-LD in page |
| Home local business | Dedicated helper invocation |

RULE: JSON-LD must match textual answers / breadcrumb anchors.

### Sitemaps

Segmented endpoints (`sitemap-general.xml`, `sitemap-services.xml`, etc.). Wrapped in middleware `page.cache`. When adding programmatic clusters, locate appropriate builder method in `SitemapController`.

### Image SEO

Responsive partial `components/seo/image.blade.php` supplies width/height attributes to stabilize CLS—mirror when authoring custom `<img>` tags.

Alt text derives from factual description of depicted deliverable—not generic `'image'`.

---

## Localization nuances

Locales that pass translation quality thresholds receive indexable signals; inferior bundles remain routable for UX yet blocked from SERP indexing.

Consult `messages.php` footprint & `hasLocaleTranslationsForIndexing` guards before launching new locales.

---

## Forbidden actions

| Violation |
| --- |
| Exposing authenticated dashboard docs or previews without auth |
| Hardcoding stale domain strings bypassing `config('seo.site_url')` |
| Injecting contradictory canonical + og:url mismatches |

---

Companion machine-readable excerpt: `resources/design-system/seo-patterns.php`.
