presseportale/resources/views/partials/head.blade.php
Kevin Adametz 4edb915a9a web: Doppelveröffentlichung — Prüfsumme, kanonische Zuordnung (aus bis E9), Quellenauskunft, noindex im Portal (Anhang 2)
Über die API kommt praktisch jede Meldung zweimal, je Portal eine Zeile
mit gleichem Text: 9.092 Paare, 53 % des Archivs, bisher jede Fassung
self-canonical und in beiden Sitemaps — Google wählte.

1c.7: press_releases.content_hash (SHA-256 über Titel + Text ohne Markup),
gesetzt beim Speichern, Bestand per press-releases:hash-content
(Query-Builder, Blöcke). Migration in zwei Statements — ADD COLUMN INSTANT,
ADD INDEX INPLACE, kein Rebuild. press-releases:duplicates-report zählt
Paare je Hauptkategorie.

1c.8: canonical_press_release_id + CanonicalAssigner. Erstquelle folgt der
Kategorie (config/canonical.php, Vorschlag zu E9), sonst die zuerst
veröffentlichte Fassung. Zuordnung bei jeder Veröffentlichung und über den
Bestand (press-releases:assign-canonicals). Die Kopie trägt rel=canonical
und mainEntityOfPage auf die Erstquelle; Sitemap und News-Sitemap nennen
nur sie; Leser sehen weiterhin beide. Alles hinter
CANONICAL_ASSIGNMENT_ENABLED (false), bis E9 entschieden ist.

1c.9: user_canonical in den Index-Prüfungen, sourceVerdict() unterscheidet
eigene Adresse / andere eigene Fassung / fremdes Portal; Anzeige im Block
„Google-Index" hinter GSC_CUSTOMER_VISIBLE, ohne Aussage über das Warum.

Dazu: Abschnitt zur einen Quelle auf /gute-pressemitteilung (Verteiler →
viele Kopien, eigene Website zuerst, keine Garantie), noindex in Admin-,
Kunden- und Auth-Layouts, UmamiSnippetTest von der lokalen .env gelöst.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 16:09:16 +00:00

45 lines
2.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{{-- Konto- und Adminbereich gehören nicht in den Index (Anhang 2, Abschnitt 7). --}}
<meta name="robots" content="noindex, nofollow" />
<title>{{ $title ?? config('app.name') }}</title>
{{-- Domain-spezifische Icons (pressekonto/presseecho/businessportal24) --}}
<link rel="icon" href="{{ asset(\App\Helpers\ThemeHelper::getFaviconPath()) }}" type="image/svg+xml">
<link rel="apple-touch-icon" href="{{ asset(\App\Helpers\ThemeHelper::getAppIconPath()) }}">
{{-- Hub × FluxUI Phase 1: Inter Tight + JetBrains Mono + Source Serif 4
(Source Serif 4 nur für brand-mark in Headern, deshalb mitgeladen). --}}
@include('partials.local-fonts')
{{-- Phase 1 Refinement: NUR portal.css einbinden — KEIN resources/js/app.js.
app.js startet Alpine via `Alpine.start()`, aber @fluxScripts (am Ende
des <body>) bringt bereits eine eigene Alpine-Instanz mit. Geladen
wir beides, läuft Alpine doppelt — Browser-Warning
"Detected multiple instances of Alpine running" und kaputte Bindings.
Für x-data im Portal greift Alpine aus @fluxScripts. --}}
@vite(['resources/css/portal.css'], 'build/portal')
@fluxAppearance
{{-- Phase 5 Anti-Flash-Bridge: FluxUI speichert die Erscheinung nur in
LocalStorage. Bei wire:navigate morpht Livewire das DOM und das neue
HTML kommt vom Server OHNE class="dark" → kurzer weißer Flash, bis das
JS die Klasse wieder anhängt. Wir spiegeln den effektiv applizierten
Modus in ein Cookie, das der Server beim nächsten Render liest und
class="dark" direkt im <html>-Tag setzt (siehe Layout-Files). --}}
<script>
(function () {
if (typeof window.Flux === 'undefined') return;
const writeCookie = () => {
const applied = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
document.cookie = 'flux_appearance=' + applied + '; path=/; max-age=31536000; SameSite=Lax';
};
const original = window.Flux.applyAppearance;
window.Flux.applyAppearance = function (appearance) {
original.call(this, appearance);
writeCookie();
};
writeCookie();
})();
</script>