feat: enhance medialib image handling and add asset URL resolution

- Implemented `resolveApiAssetUrl` function to normalize asset URLs based on API base.
- Updated `MedialibImage` component to utilize new asset URL resolution and added support for alt text and class properties.
- Enhanced image loading behavior with improved width measurement and focal point handling.
- Added placeholder image handling and improved accessibility with alt text.
- Introduced new test script for auditing broken links in skill documentation.
- Expanded seeded test content to include medialib entries and updated related tests for pagebuilder previews.
- Improved global setup and teardown logging for clarity on seeded content management.
This commit is contained in:
2026-05-17 00:52:41 +00:00
parent 958b45272d
commit 4020ad62c5
44 changed files with 4276 additions and 867 deletions
+64
View File
@@ -226,3 +226,67 @@ curl "http://tibiserver:8080/api/v1/_/<namespace>/ssr?url=/de/ueber-uns"
- **Navigation is part of SSR**: if header/footer are missing, the SSR setup is still incomplete even when the page body renders.
- **SSR cache can go stale**: Always ensure `clear_cache.js` covers every collection that affects rendered output.
- **Do not overfit the skill to demo content**: the skill should explain the architecture and where to inspect project-specific route/content rules, not freeze one content model as universal.
## SSR data loading pattern
In Svelte 5, SSR data loading works via **top-level `loadData()` calls** (NOT inside `$effect`):
```typescript
// ✅ Richtig: Top-Level-Aufruf für SSR + Browser
loadData()
async function loadData() {
const data = await getCachedEntries(...)
state = data
}
// ❌ Falsch: $effect wird für SSR nicht rechtzeitig abgearbeitet
$effect(() => { loadData() })
```
**Warum das funktioniert:**
- `loadData()` läuft während der Component-Initialisierung (vor Template-Auswertung)
- `getCachedEntries``apiRequest` → SSR-Pfad → `context.ssrRequest()` → blockierender HTTP-Fetch in goja
- goja's `await` auf einem bereits aufgelösten Promise läuft synchron weiter (kein Microtask-Hickhack)
- State-Änderungen sind vor der Template-Auswertung sichtbar
**Browser-Reaktivität:** Wenn Props sich ändern (z.B. Navigation zu anderer Kategorie), wird die Component via `{#if}`/`{#key}` neu erstellt → `loadData()` läuft erneut.
## SSR-Cache in der Entwicklung
Der SSR-Cache ist das häufigste Debugging-Hindernis. Der Proxy in `esbuild.config.js` MUSS `&noCache=1` an den SSR-Request anhängen:
```javascript
// esbuild.config.js SSR-Proxy
pathRewrite: function (path, req) {
return "/ssr?url=" + encodeURIComponent(path) + "&noCache=1"
}
```
Ohne `noCache` wird die erste SSR-Antwort gecached und bei Code-Änderungen nicht invalidiert. Der Entwickler sieht immer den alten Stand. **Immer zuerst den Cache-Bypass prüfen, bevor SSR-Fehler gesucht werden.**
**Erkennungsmerkmale für veralteten SSR-Cache:**
- `X-SSR-Cache: true` im Response-Header
- `<!--COMMENT--><!--SSR.ERROR-->` im HTML
- `__SSR_CACHE__` enthält nicht die erwarteten Daten
- Neustart von tibi-server nötig nach `app.server.js`-Änderungen (`docker restart <tibiserver>`)
## Build-Arbeitsschritte bei SSR-Änderungen
Nach jeder Änderung an Svelte-Komponenten oder `api.ts` ist folgendes nötig:
```bash
# 1. Frontend-Bundle bauen
yarn build
# 2. SSR-Bundle bauen (app.server.js)
yarn build:server
# 3. tibi-server neustarten (lädt neues app.server.js)
docker restart <tibiserver>
# 4. Frontend neustarten (für Entwicklungs-Proxy)
make docker-restart-frontend
```
**Wichtig:** `yarn build:server` allein reicht nicht der tibi-server cached das Modul im Speicher und lädt es nur beim Start neu.