# Product Updates – SEO Fields and AI Generation

**Last Updated:** 2026-04-08

This document describes the SEO override fields and AI-powered meta generation for Product Updates features.

## Overview

Individual feature posts can override default meta title, description, and featured image alt text. An AI generation endpoint produces SEO-optimized meta from feature content.

## SEO Fields

| Field | Max Length | Purpose | Fallback |
|-------|------------|---------|----------|
| `seo_title` | 41 chars | Page title (user part only) | `title` |
| `meta_description` | 155 chars | Meta description | Truncated `description` |
| `featured_image_alt` | 125 chars | `og:image:alt` and img alt | `title` |

### Suffix Logic

The page title in `post.php` is built as:

- If `seo_title` is set: `seo_title . " - Ordio Produkt-Updates"`
- Else: `title . " - Ordio Produkt-Updates"`

The suffix (`" - Ordio Produkt-Updates"`) is 19 characters. The user-editable part is limited to 41 characters so the full title stays within ~60 characters (Google truncates around 600px).

## Character Limits

| Constant | Value | Purpose |
|---------|-------|---------|
| `SEO_TITLE_USER_MAX` | 41 | User part (suffix adds 19) |
| `META_DESCRIPTION_MAX` | 155 | Meta description |
| `FEATURED_IMAGE_ALT_MAX` | 125 | Alt text |

Sanitization in `v2/helpers/produkt-updates-sanitize.php` truncates values over the limit with an ellipsis.

## AI Generation API

**Endpoint:** `POST /v2/api/produkt-updates-seo-generate.php`

**Authentication:** Requires admin session (`produkt_updates_admin_authenticated`).

**Input (JSON or form-urlencoded):**

- `title` (string)
- `description` (string, plain text or HTML; tags stripped)
- `page_content` (string, plain text or HTML; tags stripped; excerpt ~350 words for context)
- `tag` (optional) – category slug for context
- `read_more_current` (optional) – existing Mehr-Link value

**Output:**

```json
{
  "success": true,
  "seo_title": "...",
  "meta_description": "...",
  "read_more_suggestion": "themen-slug-mit-keywords"
}
```

`read_more_suggestion` is omitted when the model returns `LEER` or the value fails validation.

**Mehr-Link / READ_MORE (AI intent):**

- **Default:** one **internal slug** only (lowercase ASCII, hyphens, digits): relevant **German topic keywords** from title/description/content, aligned with slug/SEO practice (2–5 hyphen segments). Resolved to `/produkt-updates/{slug}` by `processReadMoreLink`.
- **Umlauts:** model is instructed to use `ae` / `oe` / `ue` / `ss`; the API also transliterates before validation so slugs are not stripped empty by `[^a-z0-9\-_]`.
- **Full URL or path** (`https://…` or `/…`): only when an external or absolute target is clearly appropriate; otherwise prefer slug or `LEER`.
- **Rejected:** month-style slugs (e.g. `januar-2025`), invalid formats (see `processReadMoreLink`).

**Logic:**

- Uses Gemini 2.0 Flash as primary provider
- Falls back to OpenAI GPT-4 if Gemini fails
- API keys from `v2/config/ai-faq-config.php` (same as FAQ generation)
- Enforces length limits in prompt and post-processing; slug suggestions soft-capped at 80 characters (non-URL)
- Returns German text, du tone, with call-to-action in description

## Admin UI

- **Tab 2 – Technisch & SEO:** Contains SEO Title, SEO Description, Featured Image Alt, and "SEO generieren" button
- **Char counters:** Show `X/41`, `X/155`, `X/125`; turn orange/red when over limit
- **Generate SEO:** Sends title, description, page content, tag, and current Mehr-Link to the API; fills SEO fields and optional Mehr-Link slug suggestion on success

## Regeneration

When `regenerateMonthsFromContent` runs, `seo_title`, `meta_description`, and `featured_image_alt` are preserved (same pattern as `featured_image`).

## Related Documentation

- [product-updates-content.mdc](../../../.cursor/rules/product-updates-content.mdc) – SEO override logic for post page
- [product-updates-admin.mdc](../../../.cursor/rules/product-updates-admin.mdc) – Tab structure, SEO fields, AI generation
- [product-updates-storage.mdc](../../../.cursor/rules/product-updates-storage.mdc) – Data structure
- [ai-faq-config.php](../../../v2/config/ai-faq-config.php) – API key configuration
