Jeder JTL-Shop hängt an drei serverseitigen Dateien — .htaccess, robots.txt, config.JTL-Shop.ini.php. Updates, Umzüge und vor allem Plugins schreiben dort hinein, meist blind. ShopConfigHub macht daraus eine zentrale, geprüfte, gemeinsam nutzbare Verwaltung — und schlägt sie als Standard fürs JTL-Ökosystem vor.
Schreibt jedes Plugin selbst in die .htaccess, weiß keines, was das andere schon eingetragen hat. Die Folge: kollidierende Rewrites, 404-Ketten, doppelte Regeln — im schlimmsten Fall ein Shop, der nicht mehr startet.
Die eigentliche Grundfunktion: .htaccess, robots.txt und config.JTL-Shop.ini.php nicht mehr als undurchsichtigen Textklumpen behandeln, sondern block-weise — mit sichtbarer Herkunft und einer gemeinsamen Schnittstelle, über die auch fremde Plugins ihre Einträge sicher pflegen.
Automatische Erkennung: JTL-Core, Multidomain, LiteSpeed, LLMS, „App: <Name>“, manuell. Jeder Block einzeln aktivierbar, sortierbar, editierbar — und versioniert mit Grund und Wiederherstellung.
Fremd-Plugins tragen ihre Blöcke nicht mehr selbst in die Datei ein, sondern über eine token-gesicherte API (anlegen, aktualisieren, aktivieren, deaktivieren, löschen). ShopConfigHub schreibt — kontrolliert und konfliktbewusst. Typische Kandidaten sind Plugins, die selbst Rewrites in die .htaccess setzen — etwa das LiteSpeed-Cache-Plugin von ecomData.
In der config werden Defines gezielt je Schlüssel ersetzt statt die Datei neu zu bauen; DB_* und BLOWFISH_KEY sind schreibgeschützt, kritische Defines werden erzwungen.
Ein Betriebsmodus-Schalter (Demo/Scharf) und eine WinMerge-artige Vorschau zeigen den erzeugten Stand neben dem aktuellen — bevor real geschrieben wird.
# >>> ShopConfigHub:BEGIN id=42 source="Multidomain" <<< <IfModule mod_rewrite.c> RewriteEngine On # deinedomain.de -> deinedomain-de/ RewriteCond %{HTTP_HOST} ^(www\.)?deinedomain\.de$ [NC] RewriteRule ^robots\.txt$ deinedomain-de/robots.txt [L] </IfModule> # <<< ShopConfigHub:END id=42 >>>
Marker halten Blöcke identifizierbar — für Menschen, für ShopConfigHub und für andere Plugins.
Jeder SchreibvorgangLaufen über admorris MultiDomain (Partner-Plugin) mehrere Domains auf einer Shop-Instanz, teilen sich alle dieselbe physische robots.txt, sitemap und llms.txt im Root. Für Crawler und KI-Bots ist das schlicht falsch.
Unter jeder Domain würden Bots sonst die URLs, Sprachen und Preise der Hauptdomain sehen — nicht die der aufgerufenen Domain. ShopConfigHub legt je Domain ein eigenes Unterverzeichnis an, erzeugt dort domain-spezifische Dateien und routet jede Domain per .htaccess automatisch auf ihre eigenen — nur, wenn die Zieldatei real existiert (keine 404-Fallen).
Alle MultiDomain-Funktionen gemeinsam an/aus. Ist kein MultiDomain-Plugin installiert, steht er automatisch auf inaktiv.
Ein eigener, sichtbarer .htaccess-Block pro Domain — korrekt vor dem JTL-Rewrite-Block, wahlweise internes Rewrite oder 301, mit Konfliktprüfung gegen bestehende Regeln.
Je Domain im Backend editierbar; Sitemaps (inkl. referenzierter .gz) werden in den Domain-Ordner kopiert und die Pfade umgeschrieben.
Die llms.txt entsteht z. B. mit dem starken llms.txt-Generator von Webstollen. ShopConfigHub verteilt sie je Domain: Reduktion auf die aktiven Sprachen, alle Shop-URLs auf die Domain-URL umgeschrieben (externe Links bleiben) — und Artikelpreise domainspezifisch neu berechnet.
# deinedomain.de (Hauptdomain, Bruttopreis Standard-Lieferland) … ArtNr: ART-100427 | … | Preis: 446,52 EUR | … # deinedomain.ch (Kundengruppe + CHF + Domain-Steuersatz) … ArtNr: ART-100427 | … | Preis: 402,15 CHF | …
Aus cArtNr → tpreisdetail.fVKNetto der Domain-Kundengruppe, optional brutto, umgerechnet über twaehrung.fFaktor. Ergebnis: der Preis, den ein Bot auf der Seite tatsächlich sieht. (Werte illustrativ.)
Aus den je Domain erzeugten Sitemaps liest ShopConfigHub alle URLs (inkl. Sub-Sitemaps, auch .gz) mit lastmod/priority/changefreq aus und schreibt sie domainweise in eine zentrale Tabelle — ressourcenschonend per Cron oder auf Knopfdruck.
kDomain cLoc dLastmod prio 7 https://deinedomain.de/produkt-a 2026-09-28 0.80 7 https://deinedomain.de/produkt-b 2026-09-27 0.64 9 https://deinedomain.ch/produkt-a 2026-09-28 0.80
Domain-genau statt einer einzigen Root-Sitemap, die bei MultiDomain nicht ausreicht.
Eine saubere, domain-zugeordnete URL-Liste — z. B. als Quelle für den Crawler des LiteSpeed-Cache-Plugins von ecomData statt selbstgebautem Sitemap-Parsing.
Monitoring, Index-Checks, Broken-Link-Prüfer, KI-/GEO-Tools greifen auf eine konsolidierte, aktuelle URL-Basis je Domain zu — statt jede Lösung dasselbe mehrfach zu bauen.
Fremd-Plugins tragen ihre Einträge nicht selbst in die Dateien ein, sondern übergeben sie als Blöcke über einen token-gesicherten HTTP-Endpoint. ShopConfigHub schreibt danach die Zieldatei zentral, konfliktbewusst und mit voller Schutzkette. Dieselbe Referenz steht Entwicklern als aufklappbare Backend-Hilfe direkt im Shop bereit.
POST https://<shop>/shopconfighub-endpoint.php — Root-Weiche im Shop-Root, weil PHP unter plugins/ gesperrt ist. Body und Antwort sind JSON (UTF-8).
Header X-SCH-Token: <token> oder Body-Feld token. Je App im Reiter Plugin Anbindung erzeugt, nur einmal im Klartext gezeigt — gespeichert wird nur der SHA-256-Hash.
Jedes Token trägt Scopes (erlaubte Aktionen) und Targets (erlaubte Dateien). Aktionen außerhalb des Scopes oder auf nicht erlaubte Dateien werden mit 403 abgewiesen.
X-Robots-Tag: noindex, nofollow und X-Content-Type-Options: nosniff — der Endpoint ist nicht für Crawler bestimmt.
curl -X POST 'https://<shop>/shopconfighub-endpoint.php' \ -H 'Content-Type: application/json' \ -H 'X-SCH-Token: <IHR_TOKEN>' \ -d '{ "action":"push", "target":"htaccess", "ref":"litespeed-cache", "title":"LiteSpeed Cache Rules", "content":"<IfModule LiteSpeed>…</IfModule>", "active":true }'
Antwort { "ok": true, "id": 123, "ref": "litespeed-cache", "warnings": [] } — bei Fehler { "ok": false, "error": "…", "errors": [ … ] }.
| action | scope | Pflichtfelder | Wirkung |
|---|---|---|---|
push | push | target, ref, content | Block anlegen oder aktualisieren (Upsert je ref). |
update | update | target, ref, content | Wie push, Block muss existieren (sonst 404). |
activate | activate | ref | Block aktivieren — wird in die Datei geschrieben. |
deactivate | deactivate | ref | Block deaktivieren — aus der Datei entfernt, bleibt gespeichert. |
delete | delete | ref | Block endgültig löschen. |
list | — | — | Alle eigenen Blöcke des Tokens auflisten. |
| Feld | Typ | Beschreibung |
|---|---|---|
target | string | Zieldatei: htaccess, robots oder config. Muss in den erlaubten Dateien des Tokens liegen. |
ref | string | Stabiler, App-eigener Schlüssel des Blocks (z. B. litespeed-cache). Eindeutig je Token. |
content | string | Roh-Inhalt. Wird je Ziel syntaktisch geprüft (.htaccess: Container-Balance; robots: Direktiven; config: token_get_all, verbietet u. a. eval/exec). |
title | string, opt. | Anzeigename im Backend (Default „App-Block <ref>“). |
info | string, opt. | Hinweistext (Default „App: <App-Name>“). |
active | bool, opt. | Beim push initial aktiv? Default true. |
Jede mutierende Aktion schreibt die Zieldatei neu — mit Backup, Syntaxprüfung, atomarem Write und Auto-Restore. Schlägt das Schreiben fehl, wird die Block-Änderung zurückgerollt, damit Datei und Datenbank konsistent bleiben. App-Blöcke sind mit Quelle App:<Name> gekennzeichnet und bleiben bei einem erneuten Einlesen (Rescan) der Datei erhalten.
Zwei Update-Fälle, beide abgesichert: eine neue Plugin-Version und ein Versionssprung des JTL-Shops selbst. Eine getroffene Nutzer-Konfiguration wird in keinem Fall überschrieben.
Automatisch beim Update: idempotente Datenbank-Migrationen (per Tracking-Tabelle genau einmal), Sicherstellen des config-Originals, (Neu-)Registrieren des zentralen Crons, (Neu-)Anlegen der Root-Weiche und Setzen des MultiDomain-Master-Defaults (nur falls noch nicht gesetzt). Installiert wird über den JTL-Plugin-Manager.
ShopConfigHub merkt sich, mit welcher Shop-Version das config-Original erfasst wurde. Steigt die Version, wird das Original nur neu erfasst, wenn die Live-config noch keine ShopConfigHub-Region enthält — sonst bleibt das bestehende Original als Restore-Quelle erhalten. Der config-Reiter weist auf den Wechsel hin.
Ändert ein Shop-Update die Kern-Dateien, liest der Admin die betroffene Datei per Rescan neu ein; verwaltete Blöcke werden beim nächsten Schreiben wieder gesetzt, Fremd-/Core-Inhalte bleiben erhalten.
Ausgelegt für JTL-Shop 5.6.1 und die gesamte 5.x-Reihe (MaxShopVersion 5.99), abwärtskompatibel innerhalb 5.x.
Im Demo-Modus bleiben die Shop-Kern-Dateien ohnehin unangetastet — Änderungen nach einem Update lassen sich erst simulieren, dann real schreiben.
In Vorbereitung für eine spätere Version: automatische Konflikt-Erkennung in der .htaccess nach Shop-Updates inkl. optionaler Benachrichtigung per Shop-Mailfunktion — im aktuellen Beta-Stand noch nicht aktiv.
Was sonst noch im Backend steckt — von Betriebsmodus-Details bis zum redigierten Diagnose-Export für die Beta.
In Demo bleiben die Kern-Dateien (root .htaccess/robots.txt, config.JTL-Shop) unberührt — MultiDomain-Unterverzeichnisse und ihre additiven Dateien (Sitemaps, per-Domain robots.txt, llms) werden dagegen real geschrieben, damit sie prüfbar sind.
Schaltet die robots.txt→robots.php-Rewrite-Regel in der .htaccess ab, um die robots.txt als echte Datei auszuliefern.
Das Install-Original wird als config.JTL-Shop.ini.initial.php gesichert; ein Soft-Reset stellt es wieder her — Kern-Defines aktiv, Zusatz-/Versions-Einträge werden deaktiviert statt gelöscht, Fremd-Inhalte bleiben unangetastet.
Ein zentraler Dispatcher-Cron mit per-Job Ein/Aus, Intervall und Batch/Zeitbudget (Sitemap-Kopie, llms-Verteilung, URL-Crawl) — plus manuellem Trigger im Backend.
Sucht über otit.digital nach neuen Versionen: Manifest-GET, SemVer-Vergleich und SHA-256-Prüfung des Downloads. Installiert wird über den JTL-Plugin-Manager.
Ein Log-Reiter mit Audit-Spur und allen Sicherungen — jede Sicherung einzeln wiederherstellbar.
Ein redigiertes Diagnose-ZIP ohne Secrets — für die Beta-Rückmeldung.
Schaltet automatisch mit dem JTL-Backend mit.