Einbau in ein CMS oder Framework
Für TYPO3 und Astro gibt es fertige Pakete. Nehmen Sie die — sie nehmen Ihnen genau den Handgriff ab, an dem ein selbstgebauter Einbau erfahrungsgemäß scheitert.
Die Extension pixelpoint/typo3-pixelmap-widget bringt die Karte als
Inhaltselement mit.
composer require pixelpoint/typo3-pixelmap-widget- TYPO3 13.4 LTS und 14.3 LTS, PHP 8.2 bis 8.5
- Kategorien, Orte, Touren und Inhaltssammlungen werden im Backend aus einer Liste gewählt — keine UUIDs abtippen. ⚠ Für Tour-Kategorien aus dieser Auswahl braucht die Karte das Widget ab 0.14.0: davor blieb eine so gewählte Kategorie wirkungslos, und die Karte zeigte keine Touren — ohne Fehlermeldung.
- Fünf Inhaltstypen (Ausflugsziele, Touren, Unterkünfte, Veranstaltungen, Erlebnisse) samt Zeitfenster für Veranstaltungen
- Die Konfiguration kann wahlweise headless als JSON ausgeliefert werden, wenn das Frontend entkoppelt ist
Das Paket liegt in einer GitLab-Composer-Registry, nicht auf Packagist — die Einrichtung steht im README der Extension.
pnpm add @pixelpoint/pixelmap-astro @innoex/pixelmap-widget maplibre-gl---import PixelmapWidget from '@pixelpoint/pixelmap-astro/PixelmapWidget.astro'---
<PixelmapWidget configUrl="https://maps.pixelmap.at/demo/config.json" categories={['uuid1', 'uuid2']} ctaHref="https://maps.pixelmap.at/demo/" height="480px"/>Dazu eine Zeile in der astro.config.mjs, wenn Sie MapLibre 6 fahren:
import pixelmap from '@pixelpoint/pixelmap-astro/integration'
export default defineConfig({ integrations: [pixelmap()] })Die Integration erkennt an Ihrer installierten MapLibre-Fassung, ob ein externer Worker gebraucht wird, und verdrahtet ihn. Unter MapLibre 5 tut sie nichts.
Eigener Bundler
Abschnitt betitelt „Eigener Bundler“Ohne eines der beiden Pakete verdrahten Sie den MapLibre-Worker selbst. Das ist
seit Widget 0.12.0 Pflicht und betrifft nur den Bundler-Weg — der
Einbau per <script type="module"> braucht es nie.
-
Ein Plugin, das den Worker findet. Es prüft, ob Ihre MapLibre-Fassung einen externen Worker mitbringt:
import { createRequire } from 'node:module'const require = createRequire(import.meta.url)export function maplibreWorkerUrlModule() {let workerSpecifier = nulltry {require.resolve('maplibre-gl/dist/maplibre-gl-worker.mjs')workerSpecifier = 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url'} catch {// MapLibre 5 bündelt seinen Worker inline — dann bleibt WORKER_URL leer.}const id = 'virtual:maplibre-worker-url'const aufgelöst = '\0' + idreturn {name: 'maplibre-worker-url',resolveId: (quelle) => (quelle === id ? aufgelöst : null),load: (i) =>i === aufgelöst? workerSpecifier? `export { default } from ${JSON.stringify(workerSpecifier)}`: 'export default null': null,}}Eintragen unter
pluginsIhrervite.config.js. Astro-Projekte haben keinevite.config.js— dort gehört es in dieastro.config.mjsuntervite: { plugins: [ … ] }. -
Die Verdrahtung, im faulen Pfad:
let pendingconst load = () =>(pending ??= (async () => {const [{ config }, { default: workerUrl }] = await Promise.all([import('maplibre-gl'),import('virtual:maplibre-worker-url'),])if (workerUrl) config.WORKER_URL = workerUrlreturn import('@innoex/pixelmap-widget')})())load()rufen Sie, wenn die Karte gebraucht wird. Mehrfach rufen ist unschädlich.
Wenn die Karte über dem Falz steht
Abschnitt betitelt „Wenn die Karte über dem Falz steht“Das Widget baut seine Karte erst auf, wenn es sichtbar wird. Das spart die Karten-Kosten, nicht das Bundle:
Zwei tragfähige Wege, wenn das Gewicht zählt:
- Fassade: ein statisches Vorschaubild mit Knopf; das
<script>-Tag wird erst bei Interaktion eingefügt. - Bundler mit dynamischem
import()(etwa das Astro-Paket): ein verstecktes Element löst dort null Anfragen aus.
Was Sie serverseitig nicht einrichten müssen
Abschnitt betitelt „Was Sie serverseitig nicht einrichten müssen“Das Widget wird auf einer fremden Herkunft eingebunden, jede Anfrage ist
also herkunftsübergreifend und braucht CORS-Kopfzeilen. Die werden auf
maps.pixelmap.at automatisch gesetzt — für jede Karte, ab ihrem ersten
Deploy. Es gibt keinen Handgriff je Kunde und keinen je Karte.
Woran Sie eine fehlende Kopfzeile trotzdem erkennen würden (etwa bei einem eigenen, selbst betriebenen Host):
| Symptom | Ursache |
|---|---|
| „Karte konnte nicht geladen werden.” statt einer Karte | CORS fehlt auf der config.json |
| Karte da, aber Marker sind einfarbige Punkte statt Symbolen | CORS fehlt auf den Symbol-Dateien (/sprites/**) — die Karte funktioniert, sie sieht nur ärmer aus. Ab 0.24.0 fallen dann auch die Symbole in den Sprechblasen auf die mitgelieferte Liste zurück, mit einer Warnung in der Konsole |
Ereignisse
Abschnitt betitelt „Ereignisse“Ab Widget 0.19.0 meldet das Element drei Ereignisse, auf die Ihre Seite hören
kann — etwa um ein Lade-Skelett auszublenden oder eine leere Karte durch einen
eigenen Hinweis zu ersetzen. Es sind CustomEvents am <pixelmap-widget>, mit
bubbles und composed: Ein Zuhörer am umgebenden Container oder am
document hört sie ebenso.
| Ereignis | Wann | event.detail |
|---|---|---|
pixelmap-ready |
Die Karte ist geladen und die Einträge sind eingespielt — bei jedem erfolgreichen Laden, auch mit 0 Einträgen. | { features, tours } (Anzahlen) |
pixelmap-empty |
Direkt nach pixelmap-ready, wenn keine Einträge sichtbar sind. |
{ reason }: collection, no-data oder no-match |
pixelmap-error |
Ein harter Fehler, die Karte ist unbrauchbar — oder die Basiskarte kam gar nicht. | { stage, message }, stage: config, init, layers oder tiles |
reason:collection— die Sammlung war leer oder nicht auflösbar;no-data— es kamen gar keine Einträge an;no-match— Einträge waren da, aber Ihre Auswahl (IDs, Kategorien, Zeitraum) ließ keinen übrig.stage:config—config-urlfehlt oder dieconfig.jsonwar nicht ladbar;init— der Aufbau von Daten oder Karte scheiterte;layers— die Karte lud, ihre Ebenen ließen sich nicht einrichten;tiles— binnen 8 s nach dem Laden kam keine einzige Kachel der Basiskarte an. Beitilesmalt das Widget weiter, Marker und Sprechblasen bleiben nutzbar; Ihre Seite entscheidet, was sie daraus macht. Einzelne fehlende Kacheln sind kein Ausfall.messageist technisch und für die Konsole gedacht, nie für Besucher.- Bei einer leeren Karte zeigt das Widget selbst einen dezenten Hinweis oben in der Mitte, bei einem Fehler seine Fehlermeldung.
- Die Ereignisse feuern erst, wenn das Element in den Sichtbereich kommt — dann beginnt das Widget zu laden. Ein Zuhörer, den Sie vor dem Einfügen anlegen, verpasst also nichts.
document.addEventListener('pixelmap-error', (e) => { console.warn('pixelmap', e.detail.stage, e.detail.message);});Content-Security-Policy
Abschnitt betitelt „Content-Security-Policy“Das Widget rendert in einem eigenen Shadow DOM und bringt seine Stile mit — Sie
importieren kein zusätzliches CSS. An Fremd-Herkünften braucht es den
SPA-Host Ihrer Karte (maps.pixelmap.at oder Ihre Kundendomäne) sowie die
Kachel-Hosts. Die Links in den Sprechblasen (booking-cta) fügen keine
weitere Herkunft hinzu: Sie sind gewöhnliche Links, von dort wird nichts
geladen.